Skip to content

Commit bb597a9

Browse files
authored
Merge pull request #1565 from visualize-admin/feat/dynamic-y-scale-for-interval-measures
feat: Make the y scale's min value dynamic in some cases
2 parents bf397b7 + cb94af6 commit bb597a9

20 files changed

Lines changed: 147 additions & 57 deletions

app/charts/area/areas-state-props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const useAreasStateVariables = (
3535
const temporalXVariables = useTemporalXVariables(x, {
3636
dimensionsByIri,
3737
});
38-
const numericalYVariables = useNumericalYVariables(y, {
38+
const numericalYVariables = useNumericalYVariables("area", y, {
3939
measuresByIri,
4040
});
4141
const segmentVariables = useSegmentVariables(segment, {

app/charts/column/columns-grouped-state-props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const useColumnsGroupedStateVariables = (
5353
dimensionsByIri,
5454
observations,
5555
});
56-
const numericalYVariables = useNumericalYVariables(y, {
56+
const numericalYVariables = useNumericalYVariables("column", y, {
5757
measuresByIri,
5858
});
5959
const numericalYErrorVariables = useNumericalYErrorVariables(y, {

app/charts/column/columns-grouped-state.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { extent, group, max, min, rollup, sum } from "d3-array";
1+
import { extent, group, max, rollup, sum } from "d3-array";
22
import {
33
ScaleBand,
44
ScaleLinear,
@@ -78,6 +78,7 @@ const useColumnsGroupedState = (
7878
getXLabel,
7979
yMeasure,
8080
getY,
81+
getMinY,
8182
showYStandardError,
8283
yErrorMeasure,
8384
getYError,
@@ -238,11 +239,8 @@ const useColumnsGroupedState = (
238239
const xScaleTimeRange = scaleTime().domain(xScaleTimeRangeDomain);
239240

240241
// y
241-
const minValue = Math.min(
242-
min(scalesData, (d) =>
243-
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
244-
) ?? 0,
245-
0
242+
const minValue = getMinY(scalesData, (d) =>
243+
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
246244
);
247245
const maxValue = Math.max(
248246
max(scalesData, (d) =>
@@ -252,11 +250,8 @@ const useColumnsGroupedState = (
252250
);
253251
const yScale = scaleLinear().domain([minValue, maxValue]).nice();
254252

255-
const minPaddingValue = Math.min(
256-
min(paddingData, (d) =>
257-
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
258-
) ?? 0,
259-
0
253+
const minPaddingValue = getMinY(paddingData, (d) =>
254+
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
260255
);
261256
const maxPaddingValue = Math.max(
262257
max(paddingData, (d) =>
@@ -298,6 +293,7 @@ const useColumnsGroupedState = (
298293
getXAsDate,
299294
getYErrorRange,
300295
getY,
296+
getMinY,
301297
]);
302298

303299
// Group

app/charts/column/columns-stacked-state-props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const useColumnsStackedStateVariables = (
4949
dimensionsByIri,
5050
observations,
5151
});
52-
const numericalYVariables = useNumericalYVariables(y, {
52+
const numericalYVariables = useNumericalYVariables("column", y, {
5353
measuresByIri,
5454
});
5555
const segmentVariables = useSegmentVariables(segment, {

app/charts/column/columns-state-props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const useColumnsStateVariables = (
4848
dimensionsByIri,
4949
observations,
5050
});
51-
const numericalYVariables = useNumericalYVariables(y, {
51+
const numericalYVariables = useNumericalYVariables("column", y, {
5252
measuresByIri,
5353
});
5454
const numericalYErrorVariables = useNumericalYErrorVariables(y, {

app/charts/column/columns-state.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { extent, max, min, rollup, sum } from "d3-array";
1+
import { extent, max, rollup, sum } from "d3-array";
22
import {
33
ScaleBand,
44
ScaleLinear,
@@ -69,6 +69,7 @@ const useColumnsState = (
6969
xTimeUnit,
7070
yMeasure,
7171
getY,
72+
getMinY,
7273
showYStandardError,
7374
yErrorMeasure,
7475
getYError,
@@ -133,11 +134,8 @@ const useColumnsState = (
133134

134135
const xScaleTimeRange = scaleTime().domain(xScaleTimeRangeDomain);
135136

136-
const minValue = Math.min(
137-
min(scalesData, (d) =>
138-
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
139-
) ?? 0,
140-
0
137+
const minValue = getMinY(scalesData, (d) =>
138+
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
141139
);
142140
const maxValue = Math.max(
143141
max(scalesData, (d) =>
@@ -147,11 +145,8 @@ const useColumnsState = (
147145
);
148146
const yScale = scaleLinear().domain([minValue, maxValue]).nice();
149147

150-
const paddingMinValue = Math.min(
151-
min(paddingData, (d) =>
152-
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
153-
) ?? 0,
154-
0
148+
const paddingMinValue = getMinY(paddingData, (d) =>
149+
getYErrorRange ? getYErrorRange(d)[0] : getY(d)
155150
);
156151
const paddingMaxValue = Math.max(
157152
max(paddingData, (d) =>
@@ -185,6 +180,7 @@ const useColumnsState = (
185180
xDimension,
186181
chartConfig.cubes,
187182
sumsByX,
183+
getMinY,
188184
]);
189185

190186
const { left, bottom } = useChartPadding({

app/charts/combo/combo-line-column-state-props.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { min } from "d3-array";
12
import { useCallback, useMemo } from "react";
23

34
import { BaseYGetter, sortComboData } from "@/charts/combo/combo-state-props";
@@ -11,6 +12,7 @@ import {
1112
ChartStateData,
1213
RenderingVariables,
1314
SortingVariables,
15+
shouldUseDynamicMinScaleValue,
1416
useBandXVariables,
1517
useBaseVariables,
1618
useChartData,
@@ -69,8 +71,14 @@ export const useComboLineColumnStateVariables = (
6971
iri: lineIri,
7072
label: getLabelWithUnit(measuresByIri[lineIri]),
7173
color: fields.y.colorMapping[lineIri],
72-
getY: (d) => {
73-
return d[lineIri] !== null ? Number(d[lineIri]) : null;
74+
getY: (d) => (d[lineIri] !== null ? Number(d[lineIri]) : null),
75+
getMinY: (data) => {
76+
const minY =
77+
min(data, (d) => (d[lineIri] !== null ? Number(d[lineIri]) : null)) ??
78+
0;
79+
return shouldUseDynamicMinScaleValue(measuresByIri[lineIri].scaleType)
80+
? minY
81+
: Math.min(0, minY);
7482
},
7583
};
7684
const columnYGetter: YGetter = {
@@ -80,8 +88,13 @@ export const useComboLineColumnStateVariables = (
8088
iri: columnIri,
8189
label: getLabelWithUnit(measuresByIri[columnIri]),
8290
color: fields.y.colorMapping[columnIri],
83-
getY: (d) => {
84-
return d[columnIri] !== null ? Number(d[columnIri]) : null;
91+
getY: (d) => (d[columnIri] !== null ? Number(d[columnIri]) : null),
92+
getMinY: (data) => {
93+
const minY =
94+
min(data, (d) =>
95+
d[columnIri] !== null ? Number(d[columnIri]) : null
96+
) ?? 0;
97+
return Math.min(0, minY);
8598
},
8699
};
87100

app/charts/combo/combo-line-column-state.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ const useComboLineColumnState = (
106106
scalesData,
107107
paddingData,
108108
getY: variables.y.left.getY,
109-
startAtZero: variables.y.left.chartType === "column",
109+
getMinY: variables.y.left.getMinY,
110110
});
111111
const { yScale: yScaleRight, paddingYScale: paddingRightYScale } = useYScales(
112112
{
113113
scalesData,
114114
paddingData,
115115
getY: variables.y.right.getY,
116-
startAtZero: variables.y.right.chartType === "column",
116+
getMinY: variables.y.right.getMinY,
117117
}
118118
);
119119
const [minLeftValue, maxLeftValue] = yScaleLeft.domain();

app/charts/combo/combo-line-dual-state-props.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { min } from "d3-array";
12
import { useCallback, useMemo } from "react";
23

34
import { BaseYGetter, sortComboData } from "@/charts/combo/combo-state-props";
@@ -10,6 +11,7 @@ import {
1011
ChartStateData,
1112
SortingVariables,
1213
TemporalXVariables,
14+
shouldUseDynamicMinScaleValue,
1315
useBaseVariables,
1416
useChartData,
1517
useTemporalXVariables,
@@ -52,8 +54,15 @@ export const useComboLineDualStateVariables = (
5254
iri: leftIri,
5355
label: getLabelWithUnit(measuresByIri[leftIri]),
5456
color: fields.y.colorMapping[leftIri],
55-
getY: (d) => {
56-
return d[leftIri] !== null ? Number(d[leftIri]) : null;
57+
getY: (d) => (d[leftIri] !== null ? Number(d[leftIri]) : null),
58+
getMinY: (data) => {
59+
const minY =
60+
min(data, (d) =>
61+
d[leftIri] !== null ? Number(d[leftIri]) : null
62+
) ?? 0;
63+
return shouldUseDynamicMinScaleValue(measuresByIri[leftIri].scaleType)
64+
? minY
65+
: Math.min(0, minY);
5766
},
5867
},
5968
right: {
@@ -62,8 +71,17 @@ export const useComboLineDualStateVariables = (
6271
iri: rightIri,
6372
label: getLabelWithUnit(measuresByIri[rightIri]),
6473
color: fields.y.colorMapping[rightIri],
65-
getY: (d) => {
66-
return d[rightIri] !== null ? Number(d[rightIri]) : null;
74+
getY: (d) => (d[rightIri] !== null ? Number(d[rightIri]) : null),
75+
getMinY: (data) => {
76+
const minY =
77+
min(data, (d) =>
78+
d[rightIri] !== null ? Number(d[rightIri]) : null
79+
) ?? 0;
80+
return shouldUseDynamicMinScaleValue(
81+
measuresByIri[rightIri].scaleType
82+
)
83+
? minY
84+
: Math.min(0, minY);
6785
},
6886
},
6987
},

app/charts/combo/combo-line-dual-state.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,14 @@ const useComboLineDualState = (
8989
scalesData,
9090
paddingData,
9191
getY: variables.y.left.getY,
92+
getMinY: variables.y.left.getMinY,
9293
});
9394
const { yScale: yScaleRight, paddingYScale: paddingRightYScale } = useYScales(
9495
{
9596
scalesData,
9697
paddingData,
9798
getY: variables.y.right.getY,
99+
getMinY: variables.y.right.getMinY,
98100
}
99101
);
100102

0 commit comments

Comments
 (0)