Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persisting colors across chart type changes and field changes #2132

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ You can also check the
- Bar charts, dashboard text blocks and Markdown inputs are not hidden behind
flags anymore
- Fixes

- Added button translations for custom color palette update and create button
- Color swatches inside the color picker dynamically adjust to the colors of
the selected palette
Expand All @@ -51,6 +52,8 @@ You can also check the
- Fixed errors regarding switching form existing categorical palette to a
diverging color palette
- Improved filter section styling
- Chart colors stay persistent over chart type changes

- Maintenance
- Added authentication method to e2e tests
- Added authentication to Vercel previews for easier testing
Expand Down
14 changes: 14 additions & 0 deletions app/charts/bar/bars-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
scaleBand,
ScaleLinear,
scaleLinear,
ScaleOrdinal,
scaleOrdinal,
scaleTime,
} from "d3-scale";
import orderBy from "lodash/orderBy";
Expand Down Expand Up @@ -45,6 +47,7 @@ import {
useFormatNumber,
useTimeFormatUnit,
} from "@/formatters";
import { getPalette } from "@/palettes";
import {
getSortingOrders,
makeDimensionValueSorters,
Expand All @@ -62,6 +65,7 @@ export type BarsState = CommonChartState &
yScale: ScaleBand<string>;
minY: string;
getAnnotationInfo: (d: Observation) => TooltipInfo;
colors: ScaleOrdinal<string, string>;
};

const useBarsState = (
Expand Down Expand Up @@ -272,6 +276,15 @@ const useBarsState = (
};
};

const colors = scaleOrdinal<string, string>();

colors.range(
getPalette({
paletteId: fields.color.paletteId,
colorField: fields.color,
})
);

return {
chartType: "bar",
bounds: {
Expand All @@ -286,6 +299,7 @@ const useBarsState = (
yScaleInteraction,
yScale,
getAnnotationInfo,
colors,
...variables,
};
};
Expand Down
19 changes: 11 additions & 8 deletions app/charts/bar/bars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,16 @@ export const ErrorWhiskers = () => {
};

export const Bars = () => {
const { chartData, bounds, getX, xScale, getY, yScale, getRenderingKey } =
useChartState() as BarsState;
const {
chartData,
bounds,
getX,
xScale,
getY,
yScale,
getRenderingKey,
colors,
} = useChartState() as BarsState;
const theme = useTheme();
const { margins } = bounds;
const ref = useRef<SVGGElement>(null);
Expand All @@ -89,10 +97,6 @@ export const Bars = () => {
const bandwidth = yScale.bandwidth();
const x0 = xScale(0);
const renderData: RenderBarDatum[] = useMemo(() => {
const getColor = (d: number) => {
return d <= 0 ? theme.palette.secondary.main : schemeCategory10[0];
};

return chartData.map((d) => {
const key = getRenderingKey(d);
const yScaled = yScale(getY(d)) as number;
Expand All @@ -101,15 +105,14 @@ export const Bars = () => {
const xScaled = xScale(x);
const xRender = xScale(Math.min(x, 0));
const width = Math.max(0, Math.abs(xScaled - x0));
const color = getColor(x);

return {
key,
x: xRender,
y: yScaled,
width,
height: bandwidth,
color,
color: colors(d.key as string) ?? schemeCategory10[0],
};
});
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
5 changes: 5 additions & 0 deletions app/charts/chart-config-ui-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,11 @@ const chartConfigOptionsUISpec: ChartSpecs = {
options: {
showStandardError: {},
showConfidenceInterval: {},
colorPalette: {
type: "single",
paletteId: "dimension",
color: theme.palette.primary.main,
},
},
},
{
Expand Down
5 changes: 5 additions & 0 deletions app/charts/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Dimension, Measure } from "@/domain/data";
import { stringifyComponentId } from "@/graphql/make-component-id";
import { TimeUnit } from "@/graphql/resolver-types";
import { DEFAULT_CATEGORICAL_PALETTE_ID } from "@/palettes";

import bathingWaterData from "../test/__fixtures/data/DataCubeMetadataWithComponentValues-bathingWater.json";
import forestAreaData from "../test/__fixtures/data/forest-area-by-production-region.json";
Expand Down Expand Up @@ -330,6 +331,7 @@ describe("chart type switch", () => {
dimensions: bathingWaterData.data.dataCubeByIri
.dimensions as any as Dimension[],
measures: bathingWaterData.data.dataCubeByIri.measures as Measure[],
palette: DEFAULT_CATEGORICAL_PALETTE_ID,
});

expect(newConfig.interactiveFiltersConfig?.dataFilters.active).toEqual(
Expand Down Expand Up @@ -470,6 +472,7 @@ describe("chart type switch", () => {
id: "https://environment.ld.admin.ch/foen/ubd000502/werteNichtGerundet",
},
] as any as Measure[],
palette: DEFAULT_CATEGORICAL_PALETTE_ID,
}) as ColumnConfig;

expect(newChartConfig.fields.segment).toBeUndefined();
Expand Down Expand Up @@ -512,6 +515,7 @@ describe("chart type switch", () => {
dimensions,
measures,
isAddingNewCube: true,
palette: DEFAULT_CATEGORICAL_PALETTE_ID,
}) as ComboLineDualConfig;

expect(
Expand All @@ -527,6 +531,7 @@ describe("chart type switch", () => {
dimensions,
measures,
isAddingNewCube: false,
palette: DEFAULT_CATEGORICAL_PALETTE_ID,
}) as ComboLineDualConfig;

expect(
Expand Down
Loading