From f35b111e87c353c85abf935452cd6d14efa4cb03 Mon Sep 17 00:00:00 2001 From: Pierre Romera Date: Tue, 16 Jun 2026 15:58:50 +0000 Subject: [PATCH 1/5] fix(charts): correct sortBy, scale guards, and loaded payload - BarChart/ColumnChart: sortedData sorted itself instead of loadedData, so enabling sortBy rendered an empty chart; sort loadedData instead - ColumnChart: fall back to 0 when d3.max is undefined so a missing/ non-numeric value field no longer yields a NaN y-scale (vanished bars) - StackedColumnChart: use ?? so an explicit maxValue of 0 is honoured - StackedBarChart: stop throwing in barStyle on a zero total; log and fall back to 100 like StackedColumnChart - Bar/Column/LineChart: clamp padded width/height (and Bar range, StackedColumn tickSize) to >= 0 to avoid negative SVG dimensions - BarChart: remove dead initialize() axis builder and its watcher - useChart: emit('loaded', loadedData) and detect highlights on loadedData so URL-fetched data works - add sortBy regression tests for BarChart and ColumnChart --- lib/composables/useChart.ts | 4 +-- lib/datavisualisations/BarChart/BarChart.vue | 20 ++++-------- .../ColumnChart/ColumnChart.vue | 8 ++--- .../LineChart/LineChart.vue | 4 +-- .../StackedBarChart/StackedBarChart.vue | 5 +-- .../StackedColumnChart/StackedColumnChart.vue | 4 +-- .../BarChart/BarChart.spec.js | 31 +++++++++++++++++++ .../ColumnChart/ColumnChart.spec.js | 31 +++++++++++++++++++ 8 files changed, 81 insertions(+), 26 deletions(-) diff --git a/lib/composables/useChart.ts b/lib/composables/useChart.ts index 5b7af3a..8f67bf3 100644 --- a/lib/composables/useChart.ts +++ b/lib/composables/useChart.ts @@ -155,7 +155,7 @@ export function useChart( await afterLoaded?.() isLoaded.value = true - emit('loaded') + emit('loaded', loadedData.value) if (onResized) { onResized() @@ -217,7 +217,7 @@ export function useChart( }) const dataHasHighlights = computed(() => { - const data = toValue(dataRef) + const data = loadedData.value if (Array.isArray(data)) { return some(data, highlighted) } diff --git a/lib/datavisualisations/BarChart/BarChart.vue b/lib/datavisualisations/BarChart/BarChart.vue index d4dd04a..d978312 100644 --- a/lib/datavisualisations/BarChart/BarChart.vue +++ b/lib/datavisualisations/BarChart/BarChart.vue @@ -2,7 +2,7 @@ import * as d3 from 'd3' import identity from 'lodash/identity' import sortByFn from 'lodash/sortBy' -import { computed, ref, watch, ComponentPublicInstance } from 'vue' +import { computed, ref, ComponentPublicInstance } from 'vue' import { getChartProps, useChart } from '@/composables/useChart' defineOptions({ @@ -104,13 +104,13 @@ const isLoaded = ref(false) const { loadedData, elementsMaxBBox, dataHasHighlights, d3Formatter } = useChart(el, getChartProps(props), { emit }, isLoaded, onResize) -const sortedData = computed((): [] => { +const sortedData = computed((): object[] => { if (!loadedData.value) { return [] } return !props.sortBy ? loadedData.value - : sortByFn(sortedData.value, props.sortBy) + : sortByFn(loadedData.value, props.sortBy) }) const labelWidth = computed(() => { @@ -140,8 +140,8 @@ const margin = computed(() => { }) const padded = computed(() => { - const widthP = width.value - margin.value.left - margin.value.right - const heightP = height.value - margin.value.top - margin.value.bottom + const widthP = Math.max(0, width.value - margin.value.left - margin.value.right) + const heightP = Math.max(0, height.value - margin.value.top - margin.value.bottom) return { width: widthP, height: heightP } }) @@ -150,7 +150,7 @@ const scale = computed(() => { .scaleLinear() // @ts-expect-error D3 api .domain([0, d3.max(sortedData.value, (d: Datum) => d.value)]) - .range([0, padded.value.width - valueWidth.value]) + .range([0, Math.max(0, padded.value.width - valueWidth.value)]) return { x } }) @@ -191,14 +191,6 @@ function onResize() { } } -function initialize() { - // @ts-expect-error D3 api - d3.axisBottom().scale(scale.value.x) -} - -watch(width, () => { - initialize() -})