Skip to content

Commit 4363e67

Browse files
authored
Merge pull request #1568 from visualize-admin/fix/temporal-entity-filtering
feat: Add temporal entity dimension filtering to dashboard filters
2 parents bb597a9 + ca65c75 commit 4363e67

16 files changed

Lines changed: 235 additions & 62 deletions

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ You can also check the [release page](https://github.com/visualize-admin/visuali
99

1010
# Unreleased
1111

12+
- Features
13+
- Added TemporalEntityDimension support for global dashboard filters
1214
- Fixes
15+
- Fixed using a time range brush in column charts when X dimension is a TemporalEntityDimension
1316
- Whiskers should now display correctly at the initial render
1417

1518
# [4.6.1] - 2024-06-05

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ import { usePlottableData } from "@/charts/shared/chart-helpers";
66
import {
77
BaseVariables,
88
ChartStateData,
9+
InteractiveFiltersVariables,
910
NumericalYVariables,
1011
SegmentVariables,
1112
SortingVariables,
1213
TemporalXVariables,
1314
useBaseVariables,
1415
useChartData,
16+
useInteractiveFiltersVariables,
1517
useNumericalYVariables,
1618
useSegmentVariables,
1719
useTemporalXVariables,
@@ -22,7 +24,8 @@ export type AreasStateVariables = BaseVariables &
2224
SortingVariables &
2325
TemporalXVariables &
2426
NumericalYVariables &
25-
SegmentVariables;
27+
SegmentVariables &
28+
InteractiveFiltersVariables;
2629

2730
export const useAreasStateVariables = (
2831
props: ChartProps<AreaConfig>
@@ -42,6 +45,10 @@ export const useAreasStateVariables = (
4245
dimensionsByIri,
4346
observations,
4447
});
48+
const interactiveFiltersVariables = useInteractiveFiltersVariables(
49+
chartConfig.interactiveFiltersConfig,
50+
{ dimensionsByIri }
51+
);
4552

4653
const { getX } = temporalXVariables;
4754
const sortData: AreasStateVariables["sortData"] = useCallback(
@@ -59,6 +66,7 @@ export const useAreasStateVariables = (
5966
...temporalXVariables,
6067
...numericalYVariables,
6168
...segmentVariables,
69+
...interactiveFiltersVariables,
6270
};
6371
};
6472

@@ -67,7 +75,13 @@ export const useAreasStateData = (
6775
variables: AreasStateVariables
6876
): ChartStateData => {
6977
const { chartConfig, observations } = chartProps;
70-
const { sortData, getX, getY, getSegmentAbbreviationOrLabel } = variables;
78+
const {
79+
sortData,
80+
getX,
81+
getY,
82+
getSegmentAbbreviationOrLabel,
83+
getTimeRangeDate,
84+
} = variables;
7185
const plottableData = usePlottableData(observations, {
7286
getX,
7387
getY,
@@ -79,6 +93,7 @@ export const useAreasStateData = (
7993
chartConfig,
8094
getXAsDate: getX,
8195
getSegmentAbbreviationOrLabel,
96+
getTimeRangeDate,
8297
});
8398

8499
return {

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

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
BandXVariables,
88
BaseVariables,
99
ChartStateData,
10+
InteractiveFiltersVariables,
1011
NumericalYErrorVariables,
1112
NumericalYVariables,
1213
RenderingVariables,
@@ -15,12 +16,14 @@ import {
1516
useBandXVariables,
1617
useBaseVariables,
1718
useChartData,
19+
useInteractiveFiltersVariables,
1820
useNumericalYErrorVariables,
1921
useNumericalYVariables,
2022
useSegmentVariables,
2123
} from "@/charts/shared/chart-state";
2224
import { useRenderingKeyVariable } from "@/charts/shared/rendering-utils";
2325
import { ColumnConfig, useChartConfigFilters } from "@/configurator";
26+
import { Observation, isTemporalEntityDimension } from "@/domain/data";
2427
import { sortByIndex } from "@/utils/array";
2528

2629
import { ChartProps } from "../shared/ChartProps";
@@ -31,7 +34,8 @@ export type ColumnsGroupedStateVariables = BaseVariables &
3134
NumericalYVariables &
3235
NumericalYErrorVariables &
3336
SegmentVariables &
34-
RenderingVariables;
37+
RenderingVariables &
38+
InteractiveFiltersVariables;
3539

3640
export const useColumnsGroupedStateVariables = (
3741
props: ChartProps<ColumnConfig>
@@ -46,6 +50,7 @@ export const useColumnsGroupedStateVariables = (
4650
} = props;
4751
const { fields, interactiveFiltersConfig } = chartConfig;
4852
const { x, y, segment, animation } = fields;
53+
const xDimension = dimensionsByIri[x.componentIri];
4954
const filters = useChartConfigFilters(chartConfig);
5055

5156
const baseVariables = useBaseVariables(chartConfig);
@@ -65,31 +70,38 @@ export const useColumnsGroupedStateVariables = (
6570
dimensionsByIri,
6671
observations,
6772
});
73+
const interactiveFiltersVariables = useInteractiveFiltersVariables(
74+
interactiveFiltersConfig,
75+
{ dimensionsByIri }
76+
);
6877

69-
const { getX } = bandXVariables;
78+
const { getX, getXAsDate } = bandXVariables;
7079
const { getY } = numericalYVariables;
7180
const sortData: ColumnsGroupedStateVariables["sortData"] = useCallback(
7281
(data) => {
7382
const { sortingOrder, sortingType } = x.sorting ?? {};
83+
const xGetter = isTemporalEntityDimension(xDimension)
84+
? (d: Observation) => getXAsDate(d).getTime().toString()
85+
: getX;
7486
const order = [
7587
...rollup(
7688
data,
7789
(v) => sum(v, (d) => getY(d)),
78-
(d) => getX(d)
90+
(d) => xGetter(d)
7991
),
8092
]
8193
.sort((a, b) => ascending(a[1], b[1]))
8294
.map((d) => d[0]);
8395

8496
if (sortingType === "byDimensionLabel") {
85-
return orderBy(data, getX, sortingOrder);
97+
return orderBy(data, xGetter, sortingOrder);
8698
} else if (sortingType === "byMeasure") {
87-
return sortByIndex({ data, order, getCategory: getX, sortingOrder });
99+
return sortByIndex({ data, order, getCategory: xGetter, sortingOrder });
88100
} else {
89-
return orderBy(data, getX, "asc");
101+
return orderBy(data, xGetter, "asc");
90102
}
91103
},
92-
[getX, getY, x.sorting]
104+
[getX, getXAsDate, getY, x.sorting, xDimension]
93105
);
94106

95107
const getRenderingKey = useRenderingKeyVariable(
@@ -106,6 +118,7 @@ export const useColumnsGroupedStateVariables = (
106118
...numericalYVariables,
107119
...numericalYErrorVariables,
108120
...segmentVariables,
121+
...interactiveFiltersVariables,
109122
getRenderingKey,
110123
};
111124
};
@@ -115,8 +128,13 @@ export const useColumnsGroupedStateData = (
115128
variables: ColumnsGroupedStateVariables
116129
): ChartStateData => {
117130
const { chartConfig, observations } = chartProps;
118-
const { sortData, getXAsDate, getY, getSegmentAbbreviationOrLabel } =
119-
variables;
131+
const {
132+
sortData,
133+
getXAsDate,
134+
getY,
135+
getSegmentAbbreviationOrLabel,
136+
getTimeRangeDate,
137+
} = variables;
120138
const plottableData = usePlottableData(observations, {
121139
getY,
122140
});
@@ -127,6 +145,7 @@ export const useColumnsGroupedStateData = (
127145
chartConfig,
128146
getXAsDate,
129147
getSegmentAbbreviationOrLabel,
148+
getTimeRangeDate,
130149
});
131150

132151
return {

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ import {
66
BandXVariables,
77
BaseVariables,
88
ChartStateData,
9+
InteractiveFiltersVariables,
910
NumericalYVariables,
1011
RenderingVariables,
1112
SegmentVariables,
1213
SortingVariables,
1314
useBandXVariables,
1415
useBaseVariables,
1516
useChartData,
17+
useInteractiveFiltersVariables,
1618
useNumericalYVariables,
1719
useSegmentVariables,
1820
} from "@/charts/shared/chart-state";
1921
import { useRenderingKeyVariable } from "@/charts/shared/rendering-utils";
2022
import { ColumnConfig, useChartConfigFilters } from "@/configurator";
21-
import { Observation } from "@/domain/data";
23+
import { Observation, isTemporalEntityDimension } from "@/domain/data";
2224
import { sortByIndex } from "@/utils/array";
2325

2426
import { ChartProps } from "../shared/ChartProps";
@@ -28,7 +30,8 @@ export type ColumnsStackedStateVariables = BaseVariables &
2830
BandXVariables &
2931
NumericalYVariables &
3032
SegmentVariables &
31-
RenderingVariables;
33+
RenderingVariables &
34+
InteractiveFiltersVariables;
3235

3336
export const useColumnsStackedStateVariables = (
3437
props: ChartProps<ColumnConfig>
@@ -42,6 +45,7 @@ export const useColumnsStackedStateVariables = (
4245
} = props;
4346
const { fields, interactiveFiltersConfig } = chartConfig;
4447
const { x, y, segment, animation } = fields;
48+
const xDimension = dimensionsByIri[x.componentIri];
4549
const filters = useChartConfigFilters(chartConfig);
4650

4751
const baseVariables = useBaseVariables(chartConfig);
@@ -56,31 +60,38 @@ export const useColumnsStackedStateVariables = (
5660
dimensionsByIri,
5761
observations,
5862
});
63+
const interactiveFiltersVariables = useInteractiveFiltersVariables(
64+
interactiveFiltersConfig,
65+
{ dimensionsByIri }
66+
);
5967

60-
const { getX } = bandXVariables;
68+
const { getX, getXAsDate } = bandXVariables;
6169
const sortData: ColumnsStackedStateVariables["sortData"] = useCallback(
6270
(data, { plottableDataWide }) => {
6371
const { sortingOrder, sortingType } = x.sorting ?? {};
72+
const xGetter = isTemporalEntityDimension(xDimension)
73+
? (d: Observation) => getXAsDate(d).getTime().toString()
74+
: getX;
6475
const xOrder = plottableDataWide
6576
.sort((a, b) => ascending(a.total ?? undefined, b.total ?? undefined))
66-
.map(getX);
77+
.map(xGetter);
6778

6879
if (sortingOrder === "desc" && sortingType === "byDimensionLabel") {
69-
return [...data].sort((a, b) => descending(getX(a), getX(b)));
80+
return [...data].sort((a, b) => descending(xGetter(a), xGetter(b)));
7081
} else if (sortingOrder === "asc" && sortingType === "byDimensionLabel") {
71-
return [...data].sort((a, b) => ascending(getX(a), getX(b)));
82+
return [...data].sort((a, b) => ascending(xGetter(a), xGetter(b)));
7283
} else if (sortingType === "byMeasure") {
7384
return sortByIndex({
7485
data,
7586
order: xOrder,
76-
getCategory: getX,
87+
getCategory: xGetter,
7788
sortingOrder,
7889
});
7990
} else {
80-
return [...data].sort((a, b) => ascending(getX(a), getX(b)));
91+
return [...data].sort((a, b) => ascending(xGetter(a), xGetter(b)));
8192
}
8293
},
83-
[getX, x.sorting]
94+
[getX, getXAsDate, x.sorting, xDimension]
8495
);
8596

8697
const getRenderingKey = useRenderingKeyVariable(
@@ -96,6 +107,7 @@ export const useColumnsStackedStateVariables = (
96107
...bandXVariables,
97108
...numericalYVariables,
98109
...segmentVariables,
110+
...interactiveFiltersVariables,
99111
getRenderingKey,
100112
};
101113
};
@@ -118,6 +130,7 @@ export const useColumnsStackedStateData = (
118130
getY,
119131
getSegment,
120132
getSegmentAbbreviationOrLabel,
133+
getTimeRangeDate,
121134
} = variables;
122135
const plottableData = usePlottableData(observations, {
123136
getY,
@@ -142,6 +155,7 @@ export const useColumnsStackedStateData = (
142155
chartConfig,
143156
getXAsDate,
144157
getSegmentAbbreviationOrLabel,
158+
getTimeRangeDate,
145159
});
146160

147161
return {

0 commit comments

Comments
 (0)