feat: add wbs tree

This commit is contained in:
2025-09-01 16:55:20 +03:30
parent 7325e18cec
commit 6255b20476
6 changed files with 196 additions and 35 deletions

View File

@@ -3,20 +3,25 @@ import App from "@/App.vue";
import { registerPlugins } from "@core/utils/plugins";
import "gridstack/dist/gridstack.min.css";
// AG Grid styles
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-alpine.css";
import '@styles/ag-grid-overrides.scss'
import "@styles/ag-grid-overrides.scss";
// Styles
import "@core-scss/template/index.scss";
import "@styles/styles.scss";
// Create vue app
import Highcharts from "highcharts";
import HighchartsVue from "highcharts-vue";
import * as Sankey from "highcharts/modules/sankey";
import * as Organization from "highcharts/modules/organization";
import * as Accessibility from "highcharts/modules/accessibility";
const plug = m => (typeof m === "function" ? m : m && typeof m.default === "function" ? m.default : null);
plug(Sankey)?.(Highcharts);
plug(Organization)?.(Highcharts);
plug(Accessibility)?.(Highcharts);
const app = createApp(App);
// Register plugins
registerPlugins(app);
// Mount vue app
app.use(HighchartsVue);
app.mount("#app");

View File

@@ -1,43 +1,48 @@
export default [
{
title: 'Dashboards',
icon: { icon: 'tabler-smart-home' },
title: "Dashboards",
icon: { icon: "tabler-smart-home" },
children: [
{
title: 'Analytics',
to: 'dashboards-analytics',
icon: { icon: 'tabler-chart-pie-2' },
title: "Analytics",
to: "dashboards-analytics",
icon: { icon: "tabler-chart-pie-2" },
},
{
title: 'CRM',
to: 'dashboards-crm',
icon: { icon: 'tabler-cube' },
title: "CRM",
to: "dashboards-crm",
icon: { icon: "tabler-cube" },
},
{
title: 'Ecommerce',
to: 'dashboards-ecommerce',
icon: { icon: 'tabler-shopping-cart' },
title: "Ecommerce",
to: "dashboards-ecommerce",
icon: { icon: "tabler-shopping-cart" },
},
{
title: 'Academy',
to: 'dashboards-academy',
icon: { icon: 'tabler-book' },
title: "Academy",
to: "dashboards-academy",
icon: { icon: "tabler-book" },
},
{
title: 'Logistics',
to: 'dashboards-logistics',
icon: { icon: 'tabler-truck' },
title: "Logistics",
to: "dashboards-logistics",
icon: { icon: "tabler-truck" },
},
{
title: "Demo",
to: "dashboards-demo",
icon: { icon: "tabler-truck" },
},
{
title: "Gantt",
to: "dashboards-gantt",
icon: { icon: "tabler-truck" },
},
{
title: 'Demo',
to: 'dashboards-demo',
icon: { icon: 'tabler-truck' },
},
{
title: 'Gantt',
to: 'dashboards-gantt',
icon: { icon: 'tabler-truck' },
title: "WBS",
to: "dashboards-wbs",
icon: { icon: "tabler-truck" },
},
],
},
]
];

View File

@@ -19,6 +19,10 @@ export default [
title: "Gantt",
to: "dashboards-gantt",
},
{
title: "WBS",
to: "dashboards-wbs",
},
{
title: "Academy",
to: "dashboards-academy",

View File

@@ -13,7 +13,6 @@ import ProjectActivityBarChart from "@/components/ProjectActivityBarChart.vue";
import AnalysisCard from "@/components/AnalysisCard.vue";
import CostOverview from "@/components/CostOverview.vue";
import GeneratedLeadsCard from "@/views/dashboards/ecommerce/EcommerceGeneratedLeads.vue";
import GanttChart from "./gantt.vue";
import EcommerceCongratulationsJohn from '@/views/dashboards/ecommerce/EcommerceCongratulationsJohn.vue'
import EcommerceEarningReports from '@/views/dashboards/ecommerce/EcommerceEarningReports.vue'

View File

@@ -0,0 +1,147 @@
<script setup>
import HC from "highcharts"
import { ref, onMounted } from "vue"
const cssRGB = name => getComputedStyle(document.documentElement).getPropertyValue(name).trim()
const toHex = rgb => {
const [r,g,b] = rgb.split(",").map(v => parseInt(v,10))
const h = n => n.toString(16).padStart(2,"0")
return `#${h(r)}${h(g)}${h(b)}`
}
const toRGBA = (rgb,a=1)=>`rgba(${rgb.split(",").map(v=>parseInt(v,10)).join(",")},${a})`
const leafs = [
"Bastarnisch","Brabantian","Burgundian","Crimean Gothic","Danish",
"Dutch","English","Faroese","Flemish","Frisian","Gepidisch","Gothic",
"Herulisch","(High) German","Hollandic","Icelandic","Limburgish",
"Low German","Norwegian","Rhinelandic","Rugisch","Skirisch","Swedish",
"Vandalic","Yiddish"
].map(leaf => ({ id: leaf, color: toHex(cssRGB("--v-theme-primary")) }))
const hangingNodes = [
{ id: "North Germanic", layout: "hanging", offsetHorizontal: -15 },
{ id: "West Germanic", layout: "hanging" },
{ id: "East Germanic", layout: "hanging" }
]
const nodes = hangingNodes.concat(leafs)
onMounted(() => {
HC.setOptions({
chart: {
backgroundColor: 'transparent',
style: { fontFamily: "Inter, Segoe UI, Roboto, sans-serif" }
},
title: { style: { color: toHex(cssRGB("--v-theme-on-surface")) } },
subtitle: { style: { color: toHex(cssRGB("--v-theme-on-surface")) } },
xAxis: {
lineColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25),
tickColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25),
labels: { style: { color: toHex(cssRGB("--v-theme-on-surface")) } },
gridLineColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25)
},
yAxis: {
lineColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25),
tickColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25),
labels: { style: { color: toHex(cssRGB("--v-theme-on-surface")) } },
gridLineColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25),
title: { style: { color: toHex(cssRGB("--v-theme-on-surface")) } }
},
legend: {
itemStyle: { color: toHex(cssRGB("--v-theme-on-surface")) },
itemHoverStyle: { color: toHex(cssRGB("--v-theme-on-surface")) }
},
tooltip: {
backgroundColor: toRGBA(cssRGB("--v-theme-surface"), 0.95),
borderColor: toRGBA(cssRGB("--v-theme-grey-300"), 0.25),
style: { color: toHex(cssRGB("--v-theme-on-surface")) }
},
credits: { enabled: false }
})
})
const chartOptions = ref({
chart: { inverted: true, height: 1200, backgroundColor: 'transparent' },
title: { text: "The Germanic Language Tree" },
accessibility: { point: { descriptionFormat: "{add index 1}. {toNode.id} comes from {fromNode.id}" } },
tooltip: { outside: true },
series: [{
name: "Germanic language tree",
type: "organization",
keys: ["from", "to"],
nodeWidth: 40,
nodePadding: 20,
colorByPoint: false,
hangingIndentTranslation: "cumulative",
hangingIndent: 10,
levels: [
{ level: 0, color: toHex(cssRGB("--v-theme-background")) },
{ level: 1, color: toHex(cssRGB("--v-theme-background")) },
{ level: 2, color: toHex(cssRGB("--v-theme-success")) },
{ level: 3, color: toHex(cssRGB("--v-theme-warning")) },
{ level: 4, color: toHex(cssRGB("--v-theme-primary")) }
],
nodes,
data: [
["Germanic","West Germanic"],
["West Germanic","Old English"],
["Old English","Middle English"],
["Middle English","English"],
["West Germanic","Old Frisian"],
["Old Frisian","Frisian"],
["West Germanic","Old Dutch"],
["Old Dutch","Middle Dutch"],
["Middle Dutch","Hollandic"],
["Middle Dutch","Flemish"],
["Middle Dutch","Dutch"],
["Middle Dutch","Limburgish"],
["Middle Dutch","Brabantian"],
["Middle Dutch","Rhinelandic"],
["West Germanic","Old Low German"],
["Old Low German","Middle Low German"],
["Middle Low German","Low German"],
["West Germanic","Old High German"],
["Old High German","Middle High German"],
["Middle High German","(High) German"],
["Middle High German","Yiddish"],
["Germanic","East Germanic"],
["East Germanic","Gothic"],
["East Germanic","Vandalic"],
["East Germanic","Burgundian"],
["East Germanic","Bastarnisch"],
["East Germanic","Gepidisch"],
["East Germanic","Herulisch"],
["East Germanic","Rugisch"],
["East Germanic","Skirisch"],
["East Germanic","Crimean Gothic"],
["Germanic","North Germanic"],
["North Germanic","Old Norse"],
["Old Norse","Old Icelandic"],
["Old Icelandic","Icelandic"],
["Old Norse","Old Norwegian"],
["Old Norwegian","Norwegian"],
["Old Norse","Faroese"],
["North Germanic","Old Swedish"],
["Old Swedish","Middle Swedish"],
["Middle Swedish","Swedish"],
["North Germanic","Old Danish"],
["Old Danish","Middle Danish"],
["Middle Danish","Danish"]
]
}]
})
</script>
<template>
<div class="chart-container">
<highcharts :options="chartOptions" />
</div>
</template>
<style scoped>
.chart-container {
padding: 16px;
background-color: transparent;
min-height: 100vh;
}
</style>

1
typed-router.d.ts vendored
View File

@@ -81,6 +81,7 @@ declare module 'vue-router/auto-routes' {
'dashboards-demo': RouteRecordInfo<'dashboards-demo', '/dashboards/demo', Record<never, never>, Record<never, never>>,
'dashboards-ecommerce': RouteRecordInfo<'dashboards-ecommerce', '/dashboards/ecommerce', Record<never, never>, Record<never, never>>,
'dashboards-gantt': RouteRecordInfo<'dashboards-gantt', '/dashboards/gantt', Record<never, never>, Record<never, never>>,
'dashboards-wbs': RouteRecordInfo<'dashboards-wbs', '/dashboards/wbs', Record<never, never>, Record<never, never>>,
'extensions-swiper': RouteRecordInfo<'extensions-swiper', '/extensions/swiper', Record<never, never>, Record<never, never>>,
'extensions-tour': RouteRecordInfo<'extensions-tour', '/extensions/tour', Record<never, never>, Record<never, never>>,
'forgot-password': RouteRecordInfo<'forgot-password', '/forgot-password', Record<never, never>, Record<never, never>>,