diff --git a/app/charts/column/columns-state.tsx b/app/charts/column/columns-state.tsx index 382ee5ecc0..60be604a3b 100644 --- a/app/charts/column/columns-state.tsx +++ b/app/charts/column/columns-state.tsx @@ -17,11 +17,12 @@ import { sortBy } from "lodash"; import { ReactNode, useMemo } from "react"; import { ColumnFields, SortingOrder, SortingType } from "../../configurator"; import { - formatError, formatNumberWithUnit, getPalette, mkNumber, - useError, + useErrorMeasure, + useErrorRange, + useErrorVariable, useFormatNumber, useTimeFormatUnit, } from "../../configurator/components/ui-helpers"; @@ -71,20 +72,23 @@ export interface ColumnsState { getAnnotationInfo: (d: Observation) => TooltipInfo; } -const useColumnsState = ({ - data, - fields, - measures, - dimensions, - interactiveFiltersConfig, - aspectRatio, -}: Pick< - ChartProps, - "data" | "measures" | "dimensions" | "interactiveFiltersConfig" -> & { - fields: ColumnFields; - aspectRatio: number; -}): ColumnsState => { +const useColumnsState = ( + chartProps: Pick< + ChartProps, + "data" | "measures" | "dimensions" | "interactiveFiltersConfig" + > & { + fields: ColumnFields; + aspectRatio: number; + } +): ColumnsState => { + const { + data, + fields, + measures, + dimensions, + interactiveFiltersConfig, + aspectRatio, + } = chartProps; const width = useWidth(); const formatNumber = useFormatNumber(); const timeFormatUnit = useTimeFormatUnit(); @@ -106,12 +110,9 @@ const useColumnsState = ({ const getX = useStringVariable(fields.x.componentIri); const getXAsDate = useTemporalVariable(fields.x.componentIri); const getY = useOptionalNumericVariable(fields.y.componentIri); - const getYErrorRange = useError( - measures, - dimensions, - getY, - fields.y.componentIri - ); + const errorMeasure = useErrorMeasure(chartProps, fields.y.componentIri); + const getYErrorRange = useErrorRange(errorMeasure, getY); + const getYError = useErrorVariable(errorMeasure); const getSegment = useSegment(fields.segment?.componentIri); const sortingType = fields.x.sorting?.sortingType; @@ -161,7 +162,6 @@ const useColumnsState = ({ ) ?? 0, 0 ); - const entireMaxValue = max(sortedData, getY) as number; const yScale = scaleLinear() .domain([mkNumber(minValue), mkNumber(maxValue)]) @@ -273,8 +273,8 @@ const useColumnsState = ({ datum: { label: fields.segment?.componentIri && getSegment(datum), value: `${yValueFormatter(getY(datum))}`, - error: getYErrorRange - ? ` ${formatError(getYErrorRange(datum), yValueFormatter)}` + error: getYError + ? `${getYError(datum)}${errorMeasure?.unit ?? ""}` : undefined, color: colors(getSegment(datum)) as string, }, diff --git a/app/charts/shared/interaction/tooltip-content.tsx b/app/charts/shared/interaction/tooltip-content.tsx index 4f0b428749..29424a931a 100644 --- a/app/charts/shared/interaction/tooltip-content.tsx +++ b/app/charts/shared/interaction/tooltip-content.tsx @@ -1,4 +1,3 @@ -import { Trans } from "@lingui/macro"; import { Box, Text } from "theme-ui"; import { LegendItem } from "../legend-color"; import { TooltipValue } from "./tooltip"; @@ -27,43 +26,11 @@ export const TooltipSingle = ({ {segment} )} - {yError && yValue ? ( - <> - - - - - - - - - -
- - Average: - - - - {yValue} - -
- - Error: - - - - {yError} - -
- - ) : ( - <> - {yValue && ( - - {yValue} - - )} - + {yValue && ( + + {yValue} + {yError ? <> ± {yError} : null} + )} ); diff --git a/app/configurator/components/ui-helpers.ts b/app/configurator/components/ui-helpers.ts index ea09c8f096..ce09ef2e28 100644 --- a/app/configurator/components/ui-helpers.ts +++ b/app/configurator/components/ui-helpers.ts @@ -310,18 +310,32 @@ export const formatNumberWithUnit = ( return `${formatter(nb)}${unit ? ` ${unit}` : ""}`; }; -export const useError = ( - measures: ChartProps["measures"], - dimensions: ChartProps["dimensions"], - valueGetter: (d: Observation) => number | null, - valueIri: string -) => { +export const useErrorMeasure = (chartState: ChartProps, valueIri: string) => { + const { measures, dimensions } = chartState; return useMemo(() => { - const errorMeasure = [...measures, ...dimensions].find((m) => { + return [...measures, ...dimensions].find((m) => { return m.related?.some( (r) => r.type === "StandardError" && r.iri === valueIri ); }); + }, [dimensions, measures, valueIri]); +}; + +export const useErrorVariable = (errorMeasure?: DimensionMetaDataFragment) => { + return useMemo(() => { + return errorMeasure + ? (d: Observation) => { + return d[errorMeasure.iri]; + } + : null; + }, [errorMeasure]); +}; + +export const useErrorRange = ( + errorMeasure: DimensionMetaDataFragment | undefined, + valueGetter: (d: Observation) => number | null +) => { + return useMemo(() => { return errorMeasure ? (d: Observation) => { const v = valueGetter(d) as number; @@ -337,7 +351,7 @@ export const useError = ( ]; } : null; - }, [measures, dimensions, valueIri, valueGetter]); + }, [errorMeasure, valueGetter]); }; export const useFormatNumber = () => {