From b78eb5abb999bbdab30e883325ee8ce52494aa4c Mon Sep 17 00:00:00 2001 From: Tero Tikkanen Date: Fri, 22 Nov 2024 17:04:07 +0200 Subject: [PATCH] Handle colors better (polished -> chroma) --- .../paths/graphs/DimensionalNodePlot.tsx | 17 ++++++++++++----- .../paths/graphs/DimensionalPieGraph.tsx | 19 +++++++++++++++---- .../paths/outcome/OutcomeNodeContent.tsx | 1 + utils/paths/metric.ts | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/components/paths/graphs/DimensionalNodePlot.tsx b/components/paths/graphs/DimensionalNodePlot.tsx index 542bae65..739db37a 100644 --- a/components/paths/graphs/DimensionalNodePlot.tsx +++ b/components/paths/graphs/DimensionalNodePlot.tsx @@ -1,5 +1,6 @@ import { useEffect, useMemo, useState } from 'react'; +import chroma from 'chroma-js'; import type { DimensionalNodeMetricFragment, InstanceGoalEntry, @@ -9,7 +10,6 @@ import { isEqual } from 'lodash'; import { useTranslations } from 'next-intl'; import dynamic from 'next/dynamic'; import type { LayoutAxis } from 'plotly.js'; -import { tint } from 'polished'; import { Col, DropdownItem, @@ -225,7 +225,7 @@ export default function DimensionalNodePlot({ const defaultColor = color || theme.graphColors.blue070; const shapes: Plotly.Layout['shapes'] = []; const plotData: Plotly.Data[] = []; - const rangeMode = metric.stackable ? 'tozero' : 'normal'; + //const rangeMode = metric.stackable ? 'tozero' : 'normal'; TODO: Do we need this? const filled = metric.stackable; const filledStyles = (stackGroup: string) => { @@ -293,7 +293,14 @@ export default function DimensionalNodePlot({ const genTraces = (cv: MetricCategoryValues, idx: number) => { const stackGroup = cv.isNegative ? 'neg' : 'pos'; - const color = cv.color || colors[idx]; + const forecastColorChange = 1; + const separateYearsColorChange = separateYears ? 1.75 : 0; + //const color = lighten(colorTint, cv.color || colors[idx]); + const color = chroma(cv.color || colors[idx]) + .brighten(separateYearsColorChange) + .hex(); + //const color = chroma(baseColor).brighten(0.5).hex(); + const separateYearsTrace = separateYears ? { marker: { color }, @@ -351,7 +358,7 @@ export default function DimensionalNodePlot({ y: [cv.historicalValues[lastHist], cv.forecastValues[0]], hoverinfo: 'skip', showlegend: false, - fillcolor: tint(0.3, color), + fillcolor: chroma(color).brighten(forecastColorChange).hex(), }); } if (hasForecast) { @@ -360,7 +367,7 @@ export default function DimensionalNodePlot({ const separateYearsConfig = separateYears ? {} : { - fillcolor: tint(0.3, color), + fillcolor: chroma(color).brighten(forecastColorChange).hex(), }; if (separateYears) { separateYearsIndices.push( diff --git a/components/paths/graphs/DimensionalPieGraph.tsx b/components/paths/graphs/DimensionalPieGraph.tsx index 9609c9be..cc1da90b 100644 --- a/components/paths/graphs/DimensionalPieGraph.tsx +++ b/components/paths/graphs/DimensionalPieGraph.tsx @@ -1,5 +1,6 @@ import { useEffect, useMemo, useState } from 'react'; +import chroma from 'chroma-js'; import type { DimensionalNodeMetricFragment } from 'common/__generated__/paths/graphql'; import { isEqual } from 'lodash'; import { useTranslations } from 'next-intl'; @@ -26,16 +27,26 @@ type DimensionalPieGraphProps = { metric: NonNullable; endYear: number; color?: string | null; + colorChange?: number; }; -const DimensionalPieGraph = ({ metric, endYear }: DimensionalPieGraphProps) => { +const DimensionalPieGraph = ({ + metric, + endYear, + colorChange: colorChangeProp = 0, +}: DimensionalPieGraphProps) => { const t = useTranslations(); const theme = useTheme(); const activeGoal = useReactiveVar(activeGoalVar); const cube = useMemo(() => new DimensionalMetric(metric), [metric]); + const isForecast = cube.isForecastYear(endYear); const defaultConfig = cube.getDefaultSliceConfig(activeGoal); const [sliceConfig, setSliceConfig] = useState(defaultConfig); + // TODO: Handle this color change more elegantly. + // Currently isForecast and set colorChange will not be true at the same time + const colorChange = isForecast ? 1 : colorChangeProp; + useEffect(() => { /** * If the active goal changes, we will reset the grouping + filtering @@ -137,9 +148,9 @@ const DimensionalPieGraph = ({ metric, endYear }: DimensionalPieGraphProps) => { `${yearData.allLabels.find((l) => l.id === rowId)?.label}` || '' ); pieSegmentValues.push(datum ? Math.abs(datum) : null); - pieSegmentColors.push( - yearData.allLabels.find((l) => l.id === rowId)?.color || '#333' - ); + const segmentColor = + yearData.allLabels.find((l) => l.id === rowId)?.color || '#333'; + pieSegmentColors.push(chroma(segmentColor).brighten(colorChange).hex()); pieSegmentHovers.push( `${yearData.allLabels.find((l) => l.id === rowId)?.label}, ${ datum && Math.abs(datum).toFixed(1) diff --git a/components/paths/outcome/OutcomeNodeContent.tsx b/components/paths/outcome/OutcomeNodeContent.tsx index 26b9a3f8..4c9fbd41 100644 --- a/components/paths/outcome/OutcomeNodeContent.tsx +++ b/components/paths/outcome/OutcomeNodeContent.tsx @@ -189,6 +189,7 @@ const OutcomeNodeContent = ({ endYear={ separateYears ? separateYears[separateYears.length - 1] : endYear } + colorChange={separateYears ? 1.75 : 0} /> ), diff --git a/utils/paths/metric.ts b/utils/paths/metric.ts index 15a218b4..0c1d597a 100644 --- a/utils/paths/metric.ts +++ b/utils/paths/metric.ts @@ -541,7 +541,7 @@ export class DimensionalMetric { return out; } - private isForecastYear(year: number) { + isForecastYear(year: number) { return this.data.forecastFrom && year >= this.data.forecastFrom; }