From c05872fe0f5f4ece973173245a30bbfb946bec92 Mon Sep 17 00:00:00 2001 From: antoine Date: Fri, 24 Apr 2026 16:18:16 +0200 Subject: [PATCH 1/3] Format date labels for XY charts --- demo/app/Sharp/Dashboard/PostDashboard.php | 2 +- package-lock.json | 141 +++++++++++++++--- package.json | 6 +- .../components/widgets/graph/Area.vue | 16 +- .../components/widgets/graph/Bar.vue | 16 +- .../components/widgets/graph/Line.vue | 12 +- src/Dashboard/SharpDashboard.php | 5 +- src/Dashboard/Widgets/IsXYChart.php | 5 + .../Widgets/SharpAreaGraphWidget.php | 2 +- src/Dashboard/Widgets/SharpBarGraphWidget.php | 2 +- .../Widgets/SharpGraphWidgetDataSet.php | 25 +++- .../Widgets/SharpLineGraphWidget.php | 2 +- src/Dashboard/Widgets/XYChartInterface.php | 5 + tests/Unit/Dashboard/SharpDashboardTest.php | 40 +++++ tsconfig.json | 1 + 15 files changed, 240 insertions(+), 40 deletions(-) create mode 100644 src/Dashboard/Widgets/XYChartInterface.php diff --git a/demo/app/Sharp/Dashboard/PostDashboard.php b/demo/app/Sharp/Dashboard/PostDashboard.php index 4852162df..af88af502 100644 --- a/demo/app/Sharp/Dashboard/PostDashboard.php +++ b/demo/app/Sharp/Dashboard/PostDashboard.php @@ -65,7 +65,7 @@ protected function buildWidgetsData(): void 'visits_line', SharpGraphWidgetDataSet::make(collect(CarbonPeriod::create($this->getStartDate(), $this->getEndDate())) ->mapWithKeys(fn (Carbon $day, $k) => [ - $day->isoFormat('L') => rand(10, 100), + $day->format('Y-m-d') => rand(10, 100), ])) ->setLabel('Visits') ->setColor('#274754'), diff --git a/package-lock.json b/package-lock.json index 3199f7b4d..644ccb494 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,8 +29,8 @@ "@tiptap/pm": "^3.3.0", "@tiptap/starter-kit": "^3.3.0", "@tiptap/vue-3": "^3.3.0", - "@unovis/ts": "^1.7.0-pre.1", - "@unovis/vue": "^1.7.0-pre.1", + "@unovis/ts": "^1.6.5", + "@unovis/vue": "^1.6.5", "@uppy/core": "^4.4.1", "@uppy/drop-target": "^3.1.1", "@uppy/thumbnail-generator": "^4.1.1", @@ -77,7 +77,7 @@ "laravel-vite-plugin": "^3.0.1", "tailwindcss": "^4.2.4", "tw-animate-css": "^1.3.0", - "typescript": "^5.6.3", + "typescript": "^6.0.3", "vite": "^8.0.10", "vite-bundle-visualizer": "^0.8.1", "vite-plugin-circular-dependency": "^0.4.1", @@ -4245,16 +4245,34 @@ } }, "node_modules/@unovis/ts": { - "version": "1.7.0-pre.1", - "resolved": "https://registry.npmjs.org/@unovis/ts/-/ts-1.7.0-pre.1.tgz", - "integrity": "sha512-7iXo6MKtH4lkKFT0bD+n6B0+Z168IofiD6qE0932+MeONizVG35W7QCKCwLY2YgPdKRrSF38VLMnJVYlDSBLdw==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@unovis/ts/-/ts-1.6.5.tgz", + "integrity": "sha512-4qeo0nKESrCX7vZr+zEGFjg2QbyjgxXN8//mPnvZi0e2mf+ZrjIRmHReHwO3u7fqMD7kgMMMD1ABJJFBcOempA==", "license": "Apache-2.0", "dependencies": { "@emotion/css": "^11.7.1", "@juggle/resize-observer": "^3.3.1", "@types/d3": "^7.4.0", + "@types/d3-array": "~3.2.2", + "@types/d3-axis": "~3.0.6", + "@types/d3-brush": "~3.0.6", + "@types/d3-chord": "~3.0.6", "@types/d3-collection": "^1.0.10", + "@types/d3-color": "~3.1.3", + "@types/d3-drag": "~3.0.7", + "@types/d3-ease": "~3.0.2", + "@types/d3-force": "~3.0.10", + "@types/d3-geo": "~3.1.0", + "@types/d3-hierarchy": "~3.1.7", + "@types/d3-interpolate": "~3.0.4", + "@types/d3-path": "~3.1.1", "@types/d3-sankey": "^0.12.4", + "@types/d3-scale": "~4.0.9", + "@types/d3-selection": "~3.0.0", + "@types/d3-shape": "~3.1.7", + "@types/d3-timer": "~3.0.2", + "@types/d3-transition": "~3.0.9", + "@types/d3-zoom": "~3.0.8", "@types/dagre": "^0.7.50", "@types/geojson": "^7946.0.8", "@types/leaflet": "1.7.6", @@ -4267,10 +4285,28 @@ "@unovis/dagre-layout": "0.8.8-2", "@unovis/graphlibrary": "2.2.0-2", "d3": "^7.2.1", + "d3-array": "~3", + "d3-axis": "~3", + "d3-brush": "~3", + "d3-chord": "~3", "d3-collection": "^1.0.7", + "d3-color": "~3", + "d3-drag": "~3", + "d3-ease": "~3", + "d3-force": "~3", + "d3-geo": "~3", "d3-geo-projection": "^4.0.0", + "d3-hierarchy": "~3", + "d3-interpolate": "~3", "d3-interpolate-path": "^2.2.3", + "d3-path": "~3", "d3-sankey": "^0.12.3", + "d3-scale": "~4", + "d3-selection": "~3", + "d3-shape": "~3", + "d3-timer": "~3", + "d3-transition": "~3", + "d3-zoom": "~3", "elkjs": "^0.10.0", "geojson": "^0.5.0", "leaflet": "1.7.1", @@ -4280,7 +4316,8 @@ "three": "^0.135.0", "throttle-debounce": "^5.0.0", "topojson-client": "^3.1.0", - "tslib": "^2.3.1" + "tslib": "^2.3.1", + "typescript": "~4.2.4" } }, "node_modules/@unovis/ts/node_modules/@types/leaflet": { @@ -4304,13 +4341,26 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/@unovis/ts/node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/@unovis/vue": { - "version": "1.7.0-pre.1", - "resolved": "https://registry.npmjs.org/@unovis/vue/-/vue-1.7.0-pre.1.tgz", - "integrity": "sha512-m4LLLm4L6kWMq1Nh068IORSQX4dQb+4qUZBlUnSXlBCj4bBdqjoHmnsUcYQKhYhP96eULA5M8Jm5KbKsVjvdNA==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@unovis/vue/-/vue-1.6.5.tgz", + "integrity": "sha512-BSyEeuenhSCqo0kox4xe3bWMDUn0gfF4haggrVhhNWcp6pDmctniDebOP/8AFKlhPhfGJ6b39MdvoQNhXwc46A==", "license": "Apache-2.0", "peerDependencies": { - "@unovis/ts": "1.7.0-pre.1", + "@unovis/ts": "1.6.5", "vue": "^3" } }, @@ -15462,10 +15512,11 @@ "dev": true }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "devOptional": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -23467,15 +23518,33 @@ } }, "@unovis/ts": { - "version": "1.7.0-pre.1", - "resolved": "https://registry.npmjs.org/@unovis/ts/-/ts-1.7.0-pre.1.tgz", - "integrity": "sha512-7iXo6MKtH4lkKFT0bD+n6B0+Z168IofiD6qE0932+MeONizVG35W7QCKCwLY2YgPdKRrSF38VLMnJVYlDSBLdw==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@unovis/ts/-/ts-1.6.5.tgz", + "integrity": "sha512-4qeo0nKESrCX7vZr+zEGFjg2QbyjgxXN8//mPnvZi0e2mf+ZrjIRmHReHwO3u7fqMD7kgMMMD1ABJJFBcOempA==", "requires": { "@emotion/css": "^11.7.1", "@juggle/resize-observer": "^3.3.1", "@types/d3": "^7.4.0", + "@types/d3-array": "~3.2.2", + "@types/d3-axis": "~3.0.6", + "@types/d3-brush": "~3.0.6", + "@types/d3-chord": "~3.0.6", "@types/d3-collection": "^1.0.10", + "@types/d3-color": "~3.1.3", + "@types/d3-drag": "~3.0.7", + "@types/d3-ease": "~3.0.2", + "@types/d3-force": "~3.0.10", + "@types/d3-geo": "~3.1.0", + "@types/d3-hierarchy": "~3.1.7", + "@types/d3-interpolate": "~3.0.4", + "@types/d3-path": "~3.1.1", "@types/d3-sankey": "^0.12.4", + "@types/d3-scale": "~4.0.9", + "@types/d3-selection": "~3.0.0", + "@types/d3-shape": "~3.1.7", + "@types/d3-timer": "~3.0.2", + "@types/d3-transition": "~3.0.9", + "@types/d3-zoom": "~3.0.8", "@types/dagre": "^0.7.50", "@types/geojson": "^7946.0.8", "@types/leaflet": "1.7.6", @@ -23488,10 +23557,28 @@ "@unovis/dagre-layout": "0.8.8-2", "@unovis/graphlibrary": "2.2.0-2", "d3": "^7.2.1", + "d3-array": "~3", + "d3-axis": "~3", + "d3-brush": "~3", + "d3-chord": "~3", "d3-collection": "^1.0.7", + "d3-color": "~3", + "d3-drag": "~3", + "d3-ease": "~3", + "d3-force": "~3", + "d3-geo": "~3", "d3-geo-projection": "^4.0.0", + "d3-hierarchy": "~3", + "d3-interpolate": "~3", "d3-interpolate-path": "^2.2.3", + "d3-path": "~3", "d3-sankey": "^0.12.3", + "d3-scale": "~4", + "d3-selection": "~3", + "d3-shape": "~3", + "d3-timer": "~3", + "d3-transition": "~3", + "d3-zoom": "~3", "elkjs": "^0.10.0", "geojson": "^0.5.0", "leaflet": "1.7.1", @@ -23501,7 +23588,8 @@ "three": "^0.135.0", "throttle-debounce": "^5.0.0", "topojson-client": "^3.1.0", - "tslib": "^2.3.1" + "tslib": "^2.3.1", + "typescript": "~4.2.4" }, "dependencies": { "@types/leaflet": { @@ -23521,13 +23609,18 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" } } }, "@unovis/vue": { - "version": "1.7.0-pre.1", - "resolved": "https://registry.npmjs.org/@unovis/vue/-/vue-1.7.0-pre.1.tgz", - "integrity": "sha512-m4LLLm4L6kWMq1Nh068IORSQX4dQb+4qUZBlUnSXlBCj4bBdqjoHmnsUcYQKhYhP96eULA5M8Jm5KbKsVjvdNA==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@unovis/vue/-/vue-1.6.5.tgz", + "integrity": "sha512-BSyEeuenhSCqo0kox4xe3bWMDUn0gfF4haggrVhhNWcp6pDmctniDebOP/8AFKlhPhfGJ6b39MdvoQNhXwc46A==", "requires": {} }, "@uppy/companion-client": { @@ -34946,9 +35039,9 @@ "dev": true }, "typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "devOptional": true }, "typescript-auto-import-cache": { diff --git a/package.json b/package.json index 670eec477..0a267e331 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "laravel-vite-plugin": "^3.0.1", "tailwindcss": "^4.2.4", "tw-animate-css": "^1.3.0", - "typescript": "^5.6.3", + "typescript": "^6.0.3", "vite": "^8.0.10", "vite-bundle-visualizer": "^0.8.1", "vite-plugin-circular-dependency": "^0.4.1", @@ -57,8 +57,8 @@ "@tiptap/pm": "^3.3.0", "@tiptap/starter-kit": "^3.3.0", "@tiptap/vue-3": "^3.3.0", - "@unovis/ts": "^1.7.0-pre.1", - "@unovis/vue": "^1.7.0-pre.1", + "@unovis/ts": "^1.6.5", + "@unovis/vue": "^1.6.5", "@uppy/core": "^4.4.1", "@uppy/drop-target": "^3.1.1", "@uppy/thumbnail-generator": "^4.1.1", diff --git a/resources/js/dashboard/components/widgets/graph/Area.vue b/resources/js/dashboard/components/widgets/graph/Area.vue index 5de32129a..b70ef3ccf 100644 --- a/resources/js/dashboard/components/widgets/graph/Area.vue +++ b/resources/js/dashboard/components/widgets/graph/Area.vue @@ -15,7 +15,17 @@ const props = defineProps>(); - const { data, x, y, color, tooltipTemplate, containerConfig, chartConfig, xAxisConfig, yAxisConfig } = useXYChart(props); + const { + data, + x, + y, + color, + tooltipTemplate, + containerConfig, + chartConfig, + xAxisConfig, + yAxisConfig + } = useXYChart(props); const svgDefs = computed(() => props.value?.datasets.map((dataset, i) => ` @@ -101,11 +111,11 @@ } satisfies CrosshairConfigInterface" /> - + diff --git a/resources/js/dashboard/components/widgets/graph/Bar.vue b/resources/js/dashboard/components/widgets/graph/Bar.vue index 698e56bfa..7a69fd8bf 100644 --- a/resources/js/dashboard/components/widgets/graph/Bar.vue +++ b/resources/js/dashboard/components/widgets/graph/Bar.vue @@ -19,7 +19,17 @@ const props = defineProps>(); - const { data, x, y, color, tooltipTemplate, chartConfig, xAxisConfig, containerConfig, yAxisConfig } = useXYChart(props); + const { + data, + x, + y, + color, + tooltipTemplate, + chartConfig, + xAxisConfig, + containerConfig, + yAxisConfig + } = useXYChart(props); - + - + diff --git a/resources/js/dashboard/components/widgets/graph/Line.vue b/resources/js/dashboard/components/widgets/graph/Line.vue index e2fa8ab96..2b5f6b5db 100644 --- a/resources/js/dashboard/components/widgets/graph/Line.vue +++ b/resources/js/dashboard/components/widgets/graph/Line.vue @@ -13,7 +13,17 @@ const props = defineProps>(); - const { data, x, y, color, tooltipTemplate, containerConfig, chartConfig, xAxisConfig, yAxisConfig } = useXYChart(props); + const { + data, + x, + y, + color, + tooltipTemplate, + containerConfig, + chartConfig, + xAxisConfig, + yAxisConfig + } = useXYChart(props);