diff --git a/app/components/form.tsx b/app/components/form.tsx
index e5174e4f7d..bdb15097e2 100644
--- a/app/components/form.tsx
+++ b/app/components/form.tsx
@@ -157,12 +157,14 @@ export const Select = ({
options,
onChange,
sortOptions = true,
+ controls,
}: {
id: string;
options: Option[];
label?: ReactNode;
disabled?: boolean;
sortOptions?: boolean;
+ controls?: React.ReactNode;
} & SelectProps) => {
const locale = useLocale();
const sortedOptions = useMemo(() => {
@@ -181,6 +183,7 @@ export const Select = ({
{label && (
)}
void;
}) => {
+ const controls = (
+ <>
+
+
+ >
+ );
return (
{dimension.__typename === "TemporalDimension" ? (
{
+ const keys = Object.keys(chartConfig.filters);
+ const fieldIndex = Object.keys(chartConfig.filters).indexOf(dimensionIri);
+ if (fieldIndex == 0 && delta === -1) {
+ return;
+ }
+ if (fieldIndex === keys.length - 1 && delta === 1) {
+ return;
+ }
+ const replaced = keys[fieldIndex + delta];
+ keys[fieldIndex + delta] = dimensionIri;
+ keys[fieldIndex] = replaced;
+ chartConfig.filters = Object.fromEntries(
+ keys.map((k) => [k, chartConfig.filters[k]])
+ );
+ }
+);
+
+const ensureFilterValuesCorrect = produce(
+ (
+ chartConfig: ChartConfig,
+ { dimensions }: { dimensions: DataCubeMetadata["dimensions"] }
+ ) => {
+ let dirty = false;
+ const newFilters = mapValues(chartConfig.filters, (f, dimensionIri) => {
+ if (f.type !== "single") {
+ return f;
+ }
+ const values = dimensions.find((dim) => dim.iri === dimensionIri)?.values;
+ if (!values || values.length === 0) {
+ return f;
+ }
+ if (values.find((v) => v.value === f.value)) {
+ return f;
+ }
+ dirty = true;
+ f.value = values[0].value;
+ return f;
+ });
+ if (dirty) {
+ chartConfig.filters = newFilters;
+ }
+ }
+);
+
export const ChartConfigurator = ({
state,
}: {
state: ConfiguratorStateConfiguringChart;
}) => {
const locale = useLocale();
- const [{ data }] = useDataCubeMetadataWithComponentValuesQuery({
- variables: {
+ const [, dispatch] = useConfiguratorState();
+ const variables = React.useMemo(
+ () => ({
+ date: new Date(),
iri: state.dataSet,
locale,
filters: state.chartConfig.filters,
+ }),
+ [state, locale]
+ );
+ const [{ data, fetching }, executeQuery] =
+ useDataCubeMetadataWithComponentValuesQuery({
+ variables: variables,
+ });
+ const metaData = data?.dataCubeByIri;
+
+ const handleMove = useCallback(
+ (dimensionIri: string, delta: number) => {
+ if (!metaData) {
+ return;
+ }
+
+ const chartConfig = moveFilterField(state.chartConfig, {
+ dimensionIri,
+ delta,
+ });
+
+ dispatch({
+ type: "CHART_CONFIG_REPLACED",
+ value: {
+ chartConfig,
+ dataSetMetadata: metaData,
+ },
+ });
},
- });
+ [dispatch, metaData, state.chartConfig]
+ );
+
+ React.useEffect(() => {
+ executeQuery({
+ requestPolicy: "network-only",
+ variables,
+ });
+ }, [variables, executeQuery]);
+
+ React.useEffect(() => {
+ if (!metaData || !data || !data.dataCubeByIri) {
+ return;
+ }
+ // Make sure that the filters are in line with the values
+ const chartConfig = ensureFilterValuesCorrect(state.chartConfig, {
+ dimensions: data.dataCubeByIri.dimensions,
+ });
+
+ dispatch({
+ type: "CHART_CONFIG_REPLACED",
+ value: {
+ chartConfig,
+ dataSetMetadata: metaData,
+ },
+ });
+ }, [data, dispatch, metaData, state.chartConfig]);
if (data?.dataCubeByIri) {
const mappedIris = getFieldComponentIris(state.chartConfig.fields);
- const filterDimensions = data?.dataCubeByIri.dimensions
- .filter((dim) => !mappedIris.has(dim.iri))
- .sort((a, b) => (a.isKeyDimension ? 0 : 1));
-
+ const keysOrder = Object.fromEntries(
+ Object.keys(state.chartConfig.filters).map((k, i) => [k, i])
+ );
+ const filterDimensions = sortBy(
+ data?.dataCubeByIri.dimensions.filter((dim) => !mappedIris.has(dim.iri)),
+ [(x) => keysOrder[x.iri] ?? Infinity]
+ );
return (
<>
@@ -96,6 +237,7 @@ export const ChartConfigurator = ({
Filters
+ {fetching ? "..." : ""}
{filterDimensions.map((dimension, i) => (
@@ -103,6 +245,7 @@ export const ChartConfigurator = ({
key={dimension.iri}
dimension={dimension}
index={i}
+ onMove={(n) => handleMove(dimension.iri, n)}
/>
))}
diff --git a/app/configurator/components/field.tsx b/app/configurator/components/field.tsx
index 0bba025b7c..e7d7b2d335 100644
--- a/app/configurator/components/field.tsx
+++ b/app/configurator/components/field.tsx
@@ -67,6 +67,7 @@ export const DataFilterSelect = ({
id,
disabled,
isOptional,
+ controls,
}: {
dimensionIri: string;
label: string;
@@ -74,6 +75,7 @@ export const DataFilterSelect = ({
id: string;
disabled?: boolean;
isOptional?: boolean;
+ controls: React.ReactNode;
}) => {
const fieldProps = useSingleFilterSelect({ dimensionIri });
@@ -106,6 +108,7 @@ export const DataFilterSelect = ({
label={isOptional ? `${label} (${optionalLabel})` : label}
disabled={disabled}
options={allOptions}
+ controls={controls}
{...fieldProps}
>
);
@@ -121,6 +124,7 @@ export const DataFilterSelectTime = ({
id,
disabled,
isOptional,
+ controls,
}: {
dimensionIri: string;
label: string;
@@ -131,6 +135,7 @@ export const DataFilterSelectTime = ({
id: string;
disabled?: boolean;
isOptional?: boolean;
+ controls?: React.ReactNode;
}) => {
const fieldProps = useSingleFilterSelect({ dimensionIri });
const formatLocale = useTimeFormatLocale();
@@ -184,6 +189,7 @@ export const DataFilterSelectTime = ({
disabled={disabled}
options={allOptions}
sortOptions={false}
+ controls={controls}
{...fieldProps}
>
);
diff --git a/app/pages/api/graphql.ts b/app/pages/api/graphql.ts
index d08630b9e0..9b7b1f1fae 100644
--- a/app/pages/api/graphql.ts
+++ b/app/pages/api/graphql.ts
@@ -3,7 +3,6 @@ import configureCors from "cors";
import DataLoader from "dataloader";
import "global-agent/bootstrap";
import { NextApiRequest, NextApiResponse } from "next";
-import { Filters } from "../../configurator";
import { resolvers } from "../../graphql/resolvers";
import typeDefs from "../../graphql/schema.graphql";
import { runMiddleware } from "../../lib/run-middleware";
diff --git a/app/rdf/query-dimension-values.ts b/app/rdf/query-dimension-values.ts
index aa0a80fbe9..ef53dffcb1 100644
--- a/app/rdf/query-dimension-values.ts
+++ b/app/rdf/query-dimension-values.ts
@@ -81,12 +81,14 @@ export async function loadDimensionValues(
): Promise> {
const dimensionIri = dimension.path;
- let filterList = filters ? Object.entries(filters) : [];
- filterList = filterList.slice(
+ let allFiltersList = filters ? Object.entries(filters) : [];
+ const filterList = allFiltersList.slice(
0,
- filterList.findIndex(([iri]) => iri == dimensionIri?.value) + 1
+ allFiltersList.findIndex(([iri]) => iri == dimensionIri?.value)
);
+ console.log("filters for ", dimensionIri?.value, allFiltersList, filterList);
+
let query = SELECT.DISTINCT`?value`.WHERE`
${datasetIri} ${cubeNs.observationSet} ?observationSet .
?observationSet ${cubeNs.observation} ?observation .