From a8439641ce63439e2c1c5f3bb6818e5fd9a6e1b9 Mon Sep 17 00:00:00 2001 From: Bartosz Prusinowski Date: Tue, 3 Oct 2023 13:58:45 +0200 Subject: [PATCH] feat: Add initial ComboLineDual Y field UI options --- app/charts/chart-config-ui-options.ts | 1 + .../components/chart-options-selector.tsx | 123 +++++++++++++++++- 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/app/charts/chart-config-ui-options.ts b/app/charts/chart-config-ui-options.ts index bb90b5c97..88d813b61 100644 --- a/app/charts/chart-config-ui-options.ts +++ b/app/charts/chart-config-ui-options.ts @@ -886,6 +886,7 @@ const chartConfigOptionsUISpec: ChartSpecs = { { field: "y", optional: false, + // TODO: maybe we should even create the components here? customComponent: true, componentTypes: ["NumericalMeasure"], filters: false, diff --git a/app/configurator/components/chart-options-selector.tsx b/app/configurator/components/chart-options-selector.tsx index 60cd68225..6a4811b7b 100644 --- a/app/configurator/components/chart-options-selector.tsx +++ b/app/configurator/components/chart-options-selector.tsx @@ -1,5 +1,6 @@ import { t, Trans } from "@lingui/macro"; import { Box, Stack, Tooltip, Typography } from "@mui/material"; +import { groups } from "d3"; import get from "lodash/get"; import React, { useCallback, useEffect, useMemo } from "react"; @@ -22,6 +23,7 @@ import { ColorFieldType, ColorScaleType, ComboChartConfig, + ComboLineDualConfig, ComboLineSingleConfig, ComponentType, ConfiguratorStateConfiguringChart, @@ -537,7 +539,10 @@ const ChartComboYField = (props: ChartComboYFieldProps) => { const { chartConfig, ...rest } = props; return ; } - case "comboLineDual": + case "comboLineDual": { + const { chartConfig, ...rest } = props; + return ; + } case "comboLineColumn": throw new Error("Not implemented!"); default: @@ -721,6 +726,122 @@ const ChartComboLineSingleYField = ( ); }; +const ChartComboLineDualYField = ( + props: ChartComboYFieldProps +) => { + const locale = useLocale(); + const [, dispatch] = useConfiguratorState(isConfiguring); + const { chartConfig, measures } = props; + const { fields } = chartConfig; + const { y } = fields; + + const numericalMeasures = React.useMemo(() => { + return measures.filter(isNumericalMeasure); + }, [measures]); + + const { leftAxisMeasure, rightAxisMeasure } = React.useMemo(() => { + const leftAxisMeasure = numericalMeasures.find( + (m) => m.iri === y.leftAxisComponentIri + ) as DimensionMetadataFragment; + const rightAxisMeasure = numericalMeasures.find( + (m) => m.iri === y.rightAxisComponentIri + ) as DimensionMetadataFragment; + + return { + leftAxisMeasure, + rightAxisMeasure, + }; + }, [numericalMeasures, y.leftAxisComponentIri, y.rightAxisComponentIri]); + + // FIXME: handle properly in getPossibleChartTypes, then uncomment + // if (leftAxisMeasure.unit !== rightAxisMeasure.unit) { + // throw new Error( + // "ChartComboYField can only be used with dual-unit charts!" + // ); + // } + + const getOptions = React.useCallback( + (orientation: "left" | "right") => { + return groups(numericalMeasures, (d) => d.unit ?? "None").map( + ([k, v]) => { + return [ + { label: k, value: k }, + v.map((m) => { + return { + value: m.iri, + label: m.label, + disabled: + orientation === "left" + ? m.unit === rightAxisMeasure.unit + : m.unit === leftAxisMeasure.unit, + }; + }), + ]; + } + ) as [Option, Option[]][]; + }, + [leftAxisMeasure.unit, numericalMeasures, rightAxisMeasure.unit] + ); + + return ( + + Measures + + + {/* FIXME: translate */} + Note that you can only combine measures of different units. + + + { + const newIri = e.target.value as string; + dispatch({ + type: "CHART_OPTION_CHANGED", + value: { + locale, + field: "y", + path: "rightAxisComponentIri", + value: newIri, + }, + }); + }} + sx={{ mb: 2 }} + /> + + + ); +}; + const ChartFieldAnimation = ({ field }: { field: AnimationField }) => { return (