Skip to content

Commit e804d90

Browse files
authored
Merge pull request #1021 from visualize-admin/feat/improve-sorting
feat: Improve sorting for mix of hierarchical and regular values
2 parents 166c2c1 + 39e8878 commit e804d90

File tree

20 files changed

+509
-266
lines changed

20 files changed

+509
-266
lines changed

app/charts/area/chart-area.tsx

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { memo } from "react";
1+
import { memo } from "react";
22

33
import { Areas } from "@/charts/area/areas";
44
import { AreaChart } from "@/charts/area/areas-state";
@@ -18,6 +18,8 @@ import {
1818
import { Observation } from "@/domain/data";
1919
import {
2020
DimensionMetadataFragment,
21+
useComponentsQuery,
22+
useDataCubeMetadataQuery,
2123
useDataCubeObservationsQuery,
2224
} from "@/graphql/query-hooks";
2325
import { useLocale } from "@/locales/use-locale";
@@ -36,19 +38,38 @@ export const ChartAreasVisualization = ({
3638
queryFilters: QueryFilters;
3739
}) => {
3840
const locale = useLocale();
39-
const [queryResp] = useDataCubeObservationsQuery({
41+
const [metadataQuery] = useDataCubeMetadataQuery({
4042
variables: {
4143
iri: dataSetIri,
4244
sourceType: dataSource.type,
4345
sourceUrl: dataSource.url,
4446
locale,
45-
dimensions: null, // FIXME: Try to load less dimensions
47+
},
48+
});
49+
const [componentsQuery] = useComponentsQuery({
50+
variables: {
51+
iri: dataSetIri,
52+
sourceType: dataSource.type,
53+
sourceUrl: dataSource.url,
54+
locale,
55+
},
56+
});
57+
const [observationsQuery] = useDataCubeObservationsQuery({
58+
variables: {
59+
iri: dataSetIri,
60+
sourceType: dataSource.type,
61+
sourceUrl: dataSource.url,
62+
locale,
63+
dimensions: null,
4664
filters: queryFilters,
4765
},
4866
});
67+
4968
return (
5069
<ChartLoadingWrapper
51-
query={queryResp}
70+
metadataQuery={metadataQuery}
71+
componentsQuery={componentsQuery}
72+
observationsQuery={observationsQuery}
5273
chartConfig={chartConfig}
5374
Component={ChartAreas}
5475
/>

app/charts/chart-loading-wrapper.tsx

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
import { ChartConfig } from "@/configurator";
1414
import { Observation } from "@/domain/data";
1515
import {
16+
ComponentsQuery,
17+
DataCubeMetadataQuery,
1618
DataCubeObservationsQuery,
1719
DimensionMetadataFragment,
1820
} from "@/graphql/query-hooks";
@@ -32,12 +34,22 @@ export const ChartLoadingWrapper = <
3234
TOtherProps,
3335
TChartComponent extends React.ElementType
3436
>({
35-
query,
37+
metadataQuery,
38+
componentsQuery,
39+
observationsQuery,
3640
chartConfig,
3741
Component,
3842
ComponentProps,
3943
}: {
40-
query: Pick<
44+
metadataQuery: Pick<
45+
UseQueryResponse<DataCubeMetadataQuery>[0],
46+
"data" | "fetching" | "error"
47+
>;
48+
componentsQuery: Pick<
49+
UseQueryResponse<ComponentsQuery>[0],
50+
"data" | "fetching" | "error"
51+
>;
52+
observationsQuery: Pick<
4153
UseQueryResponse<DataCubeObservationsQuery>[0],
4254
"data" | "fetching" | "error"
4355
>;
@@ -48,11 +60,38 @@ export const ChartLoadingWrapper = <
4860
keyof ChartCommonProps<TChartConfig>
4961
>;
5062
}) => {
51-
const { data, fetching, error } = query;
52-
if (data?.dataCubeByIri) {
53-
const { title, dimensions, measures, observations } = data?.dataCubeByIri;
63+
const {
64+
data: metadataData,
65+
fetching: fetchingMetadata,
66+
error: metadataError,
67+
} = metadataQuery;
68+
const {
69+
data: componentsData,
70+
fetching: fetchingComponents,
71+
error: componentsError,
72+
} = componentsQuery;
73+
const {
74+
data: observationsData,
75+
fetching: fetchingObservations,
76+
error: observationsError,
77+
} = observationsQuery;
78+
79+
if (
80+
metadataData?.dataCubeByIri &&
81+
componentsData?.dataCubeByIri &&
82+
observationsData?.dataCubeByIri
83+
) {
84+
const { title } = metadataData.dataCubeByIri;
85+
const { dimensions, measures } = componentsData.dataCubeByIri;
86+
const { observations } = observationsData.dataCubeByIri;
87+
5488
return observations.data.length > 0 ? (
55-
<Box data-chart-loaded={!fetching} sx={{ position: "relative" }}>
89+
<Box
90+
data-chart-loaded={
91+
!(fetchingMetadata && fetchingComponents && fetchingObservations)
92+
}
93+
sx={{ position: "relative" }}
94+
>
5695
<A11yTable
5796
title={title}
5897
observations={observations.data}
@@ -61,20 +100,24 @@ export const ChartLoadingWrapper = <
61100
/>
62101
{React.createElement(Component, {
63102
observations: observations.data,
64-
dimensions: dimensions,
65-
measures: measures,
66-
chartConfig: chartConfig,
103+
dimensions,
104+
measures,
105+
chartConfig,
67106
...ComponentProps,
68107
} as ChartCommonProps<TChartConfig> & TOtherProps)}
69-
{fetching && <LoadingOverlay />}
108+
{(fetchingMetadata || fetchingComponents || fetchingObservations) && (
109+
<LoadingOverlay />
110+
)}
70111
</Box>
71112
) : (
72113
<NoDataHint />
73114
);
74-
} else if (error) {
115+
} else if (metadataError || componentsError || observationsError) {
75116
return (
76-
<Flex flexGrow={1} justifyContent="center" minHeight={300}>
77-
<LoadingDataError message={error.message} />
117+
<Flex sx={{ flexDirection: "column", gap: 3 }}>
118+
{metadataError && <Error message={metadataError.message} />}
119+
{componentsError && <Error message={componentsError.message} />}
120+
{observationsError && <Error message={observationsError.message} />}
78121
</Flex>
79122
);
80123
} else {
@@ -85,3 +128,11 @@ export const ChartLoadingWrapper = <
85128
);
86129
}
87130
};
131+
132+
const Error = ({ message }: { message: string }) => {
133+
return (
134+
<Flex flexGrow={1} justifyContent="center" minHeight={300}>
135+
<LoadingDataError message={message} />
136+
</Flex>
137+
);
138+
};

app/charts/column/chart-column.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import { TimeSlider } from "@/configurator/interactive-filters/time-slider";
2828
import { Observation } from "@/domain/data";
2929
import {
3030
DimensionMetadataFragment,
31+
useComponentsWithHierarchiesQuery,
32+
useDataCubeMetadataQuery,
3133
useDataCubeObservationsQuery,
3234
} from "@/graphql/query-hooks";
3335
import { useLocale } from "@/locales/use-locale";
@@ -46,7 +48,23 @@ export const ChartColumnsVisualization = ({
4648
queryFilters: QueryFilters;
4749
}) => {
4850
const locale = useLocale();
49-
const [queryResp] = useDataCubeObservationsQuery({
51+
const [metadataQuery] = useDataCubeMetadataQuery({
52+
variables: {
53+
iri: dataSetIri,
54+
sourceType: dataSource.type,
55+
sourceUrl: dataSource.url,
56+
locale,
57+
},
58+
});
59+
const [componentsWithHierarchiesQuery] = useComponentsWithHierarchiesQuery({
60+
variables: {
61+
iri: dataSetIri,
62+
sourceType: dataSource.type,
63+
sourceUrl: dataSource.url,
64+
locale,
65+
},
66+
});
67+
const [observationsQuery] = useDataCubeObservationsQuery({
5068
variables: {
5169
iri: dataSetIri,
5270
sourceType: dataSource.type,
@@ -59,7 +77,9 @@ export const ChartColumnsVisualization = ({
5977

6078
return (
6179
<ChartLoadingWrapper
62-
query={queryResp}
80+
metadataQuery={metadataQuery}
81+
componentsQuery={componentsWithHierarchiesQuery}
82+
observationsQuery={observationsQuery}
6383
chartConfig={chartConfig}
6484
Component={ChartColumns}
6585
/>

app/charts/column/columns-state.tsx

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
} from "d3";
1616
import get from "lodash/get";
1717
import orderBy from "lodash/orderBy";
18-
import { ReactNode, useCallback, useMemo } from "react";
18+
import { ReactNode, useMemo } from "react";
1919

2020
import {
2121
BOTTOM_MARGIN_OFFSET,
@@ -38,6 +38,7 @@ import { useMaybeAbbreviations } from "@/charts/shared/use-abbreviations";
3838
import useChartFormatters from "@/charts/shared/use-chart-formatters";
3939
import { ChartContext, ChartProps } from "@/charts/shared/use-chart-state";
4040
import { InteractionProvider } from "@/charts/shared/use-interaction";
41+
import { useObservationLabels } from "@/charts/shared/use-observation-labels";
4142
import { Observer, useWidth } from "@/charts/shared/use-width";
4243
import { ColumnConfig, SortingOrder, SortingType } from "@/configurator";
4344
import {
@@ -118,35 +119,10 @@ const useColumnsState = (
118119
dimension: xDimension,
119120
});
120121

121-
const getXIri = useCallback(
122-
(d: Observation) => {
123-
return d[`${fields.x.componentIri}/__iri__`] as string | undefined;
124-
},
125-
[fields.x.componentIri]
126-
);
127-
128-
const observationXLabelsLookup = useMemo(() => {
129-
const lookup = new Map<string, string>();
130-
data.forEach((d) => {
131-
const iri = getXIri(d);
132-
const label = getXAbbreviationOrLabel(d);
133-
lookup.set(iri ?? label, label);
134-
});
135-
136-
return lookup;
137-
}, [data, getXAbbreviationOrLabel, getXIri]);
138-
139-
const getX = useCallback(
140-
(d: Observation) => {
141-
return getXIri(d) ?? getXAbbreviationOrLabel(d);
142-
},
143-
[getXIri, getXAbbreviationOrLabel]
144-
);
145-
const getXLabel = useCallback(
146-
(d: string) => {
147-
return observationXLabelsLookup.get(d) ?? d;
148-
},
149-
[observationXLabelsLookup]
122+
const { getValue: getX, getLabel: getXLabel } = useObservationLabels(
123+
data,
124+
getXAbbreviationOrLabel,
125+
fields.x.componentIri
150126
);
151127

152128
const getXAsDate = useTemporalVariable(fields.x.componentIri);

app/charts/line/chart-lines.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
import { Observation } from "@/domain/data";
2020
import {
2121
DimensionMetadataFragment,
22+
useComponentsQuery,
23+
useDataCubeMetadataQuery,
2224
useDataCubeObservationsQuery,
2325
} from "@/graphql/query-hooks";
2426
import { useLocale } from "@/locales/use-locale";
@@ -37,20 +39,38 @@ export const ChartLinesVisualization = ({
3739
queryFilters: QueryFilters;
3840
}) => {
3941
const locale = useLocale();
40-
const [queryResp] = useDataCubeObservationsQuery({
42+
const [metadataQuery] = useDataCubeMetadataQuery({
4143
variables: {
4244
iri: dataSetIri,
4345
sourceType: dataSource.type,
4446
sourceUrl: dataSource.url,
4547
locale,
46-
dimensions: null, // FIXME: Try to load less dimensions
48+
},
49+
});
50+
const [componentsQuery] = useComponentsQuery({
51+
variables: {
52+
iri: dataSetIri,
53+
sourceType: dataSource.type,
54+
sourceUrl: dataSource.url,
55+
locale,
56+
},
57+
});
58+
const [observationsQuery] = useDataCubeObservationsQuery({
59+
variables: {
60+
iri: dataSetIri,
61+
sourceType: dataSource.type,
62+
sourceUrl: dataSource.url,
63+
locale,
64+
dimensions: null,
4765
filters: queryFilters,
4866
},
4967
});
5068

5169
return (
5270
<ChartLoadingWrapper
53-
query={queryResp}
71+
metadataQuery={metadataQuery}
72+
componentsQuery={componentsQuery}
73+
observationsQuery={observationsQuery}
5474
chartConfig={chartConfig}
5575
Component={ChartLines}
5676
/>

0 commit comments

Comments
 (0)