Skip to content

Commit

Permalink
refactor: Adapt test to use interactive filters dashboard context
Browse files Browse the repository at this point in the history
  • Loading branch information
ptbrowne committed May 16, 2024
1 parent 41697f0 commit 56b54cd
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 119 deletions.
2 changes: 1 addition & 1 deletion app/charts/shared/chart-helpers.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jest.mock("../../rdf/extended-cube", () => ({
}));

jest.mock("@/stores/interactive-filters", () => ({
useInteractiveFilters: jest.fn(() => ({
useChartInteractiveFilters: jest.fn(() => ({
A_1: { type: "single", value: "A_1_1" },
A_2: { type: "single", value: "A_2_1" },
B_1: { type: "single", value: "B_1_1" },
Expand Down
7 changes: 5 additions & 2 deletions app/charts/shared/use-sync-interactive-filters.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useState } from "react";
import useSyncInteractiveFilters from "@/charts/shared/use-sync-interactive-filters";
import { ChartConfig, InteractiveFiltersConfig } from "@/config-types";
import {
InteractiveFiltersChartProvider,
InteractiveFiltersProvider,
useChartInteractiveFilters,
} from "@/stores/interactive-filters";
Expand Down Expand Up @@ -78,8 +79,10 @@ const setup = ({
);
};
const root = render(
<InteractiveFiltersProvider>
<Component />
<InteractiveFiltersProvider chartConfigs={[chartConfig]}>
<InteractiveFiltersChartProvider chartConfigKey={chartConfig.key}>
<Component />
</InteractiveFiltersChartProvider>
</InteractiveFiltersProvider>
);
const getIFState = () =>
Expand Down
109 changes: 58 additions & 51 deletions app/docs/charts.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import { LegendColor } from "@/charts/shared/legend-color";
import { InteractionVoronoi } from "@/charts/shared/overlay-voronoi";
import { ConfiguratorStateProvider } from "@/configurator/configurator-state";
import { Dimension, Measure } from "@/domain/data";
import { InteractiveFiltersProvider } from "@/stores/interactive-filters";
import {
InteractiveFiltersChartProvider,
InteractiveFiltersProvider,
} from "@/stores/interactive-filters";
import { CONFIGURATOR_STATE_VERSION } from "@/utils/chart-config/versioning";

import {
Expand Down Expand Up @@ -67,27 +70,29 @@ const ColumnsStory = {
activeChartKey: "scatterplot",
}}
>
<InteractiveFiltersProvider>
<ColumnChart
observations={columnObservations}
measures={columnMeasures}
measuresByIri={keyBy(columnMeasures, (d: Measure) => d.iri)}
dimensions={columnDimensions}
dimensionsByIri={keyBy(columnDimensions, (d: Dimension) => d.iri)}
chartConfig={chartConfig}
aspectRatio={0.4}
>
<ChartContainer>
<ChartSvg>
<AxisHeightLinear />
<AxisWidthBand />
<AxisWidthBandDomain />
<Columns />
<ErrorWhiskers />
</ChartSvg>
<Tooltip type="single" />
</ChartContainer>
</ColumnChart>
<InteractiveFiltersProvider chartConfigs={[chartConfig]}>
<InteractiveFiltersChartProvider chartConfigKey={chartConfig.key}>
<ColumnChart
observations={columnObservations}
measures={columnMeasures}
measuresByIri={keyBy(columnMeasures, (d: Measure) => d.iri)}
dimensions={columnDimensions}
dimensionsByIri={keyBy(columnDimensions, (d: Dimension) => d.iri)}
chartConfig={chartConfig}
aspectRatio={0.4}
>
<ChartContainer>
<ChartSvg>
<AxisHeightLinear />
<AxisWidthBand />
<AxisWidthBandDomain />
<Columns />
<ErrorWhiskers />
</ChartSvg>
<Tooltip type="single" />
</ChartContainer>
</ColumnChart>
</InteractiveFiltersChartProvider>
</InteractiveFiltersProvider>
</ConfiguratorStateProvider>
),
Expand Down Expand Up @@ -115,35 +120,37 @@ const ScatterplotStory = {
activeChartKey: "scatterplot",
}}
>
<InteractiveFiltersProvider>
<ScatterplotChart
observations={scatterplotObservations}
dimensions={scatterplotDimensions}
dimensionsByIri={keyBy(scatterplotDimensions, (d) => d.iri)}
measures={scatterplotMeasures}
measuresByIri={keyBy(scatterplotMeasures, (d) => d.iri)}
chartConfig={scatterplotChartConfig}
aspectRatio={1}
>
<ChartContainer>
<ChartSvg>
<AxisWidthLinear />
<AxisHeightLinear />
<AxisWidthLinearDomain />
<AxisHeightLinearDomain />
<Scatterplot />
<InteractionVoronoi />
</ChartSvg>
<Tooltip type="single" />
</ChartContainer>
{scatterplotFields.segment && (
<LegendColor
chartConfig={chartConfig}
symbol="square"
interactive
/>
)}
</ScatterplotChart>
<InteractiveFiltersProvider chartConfigs={[chartConfig]}>
<InteractiveFiltersChartProvider chartConfigKey={chartConfig.key}>
<ScatterplotChart
observations={scatterplotObservations}
dimensions={scatterplotDimensions}
dimensionsByIri={keyBy(scatterplotDimensions, (d) => d.iri)}
measures={scatterplotMeasures}
measuresByIri={keyBy(scatterplotMeasures, (d) => d.iri)}
chartConfig={scatterplotChartConfig}
aspectRatio={1}
>
<ChartContainer>
<ChartSvg>
<AxisWidthLinear />
<AxisHeightLinear />
<AxisWidthLinearDomain />
<AxisHeightLinearDomain />
<Scatterplot />
<InteractionVoronoi />
</ChartSvg>
<Tooltip type="single" />
</ChartContainer>
{scatterplotFields.segment && (
<LegendColor
chartConfig={chartConfig}
symbol="square"
interactive
/>
)}
</ScatterplotChart>
</InteractiveFiltersChartProvider>
</InteractiveFiltersProvider>
</ConfiguratorStateProvider>
),
Expand Down
33 changes: 19 additions & 14 deletions app/docs/datatable.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import {
tableMeasures,
tableObservations,
} from "@/docs/fixtures";
import { InteractiveFiltersProvider } from "@/stores/interactive-filters";
import {
InteractiveFiltersChartProvider,
InteractiveFiltersProvider,
} from "@/stores/interactive-filters";

const meta: Meta = {
title: "Charts / Charts / Data Table",
Expand All @@ -20,19 +23,21 @@ export default meta;
const DataTableStory: StoryObj = {
render: () => {
return (
<InteractiveFiltersProvider>
<TableChart
observations={tableObservations}
dimensions={tableDimensions}
dimensionsByIri={keyBy(tableDimensions, (d) => d.iri)}
measures={tableMeasures}
measuresByIri={keyBy(tableMeasures, (d) => d.iri)}
chartConfig={tableConfig}
>
<ChartContainer>
<Table />
</ChartContainer>
</TableChart>
<InteractiveFiltersProvider chartConfigs={[tableConfig]}>
<InteractiveFiltersChartProvider chartConfigKey={tableConfig.key}>
<TableChart
observations={tableObservations}
dimensions={tableDimensions}
dimensionsByIri={keyBy(tableDimensions, (d) => d.iri)}
measures={tableMeasures}
measuresByIri={keyBy(tableMeasures, (d) => d.iri)}
chartConfig={tableConfig}
>
<ChartContainer>
<Table />
</ChartContainer>
</TableChart>
</InteractiveFiltersChartProvider>
</InteractiveFiltersProvider>
);
},
Expand Down
49 changes: 27 additions & 22 deletions app/docs/lines.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { BrushTime } from "@/charts/shared/brush";
import { ChartContainer, ChartSvg } from "@/charts/shared/containers";
import { LegendColor } from "@/charts/shared/legend-color";
import { ConfiguratorStateProvider } from "@/configurator/configurator-state";
import { InteractiveFiltersProvider } from "@/stores/interactive-filters";
import {
InteractiveFiltersChartProvider,
InteractiveFiltersProvider,
} from "@/stores/interactive-filters";
import { CONFIGURATOR_STATE_VERSION } from "@/utils/chart-config/versioning";

import {
Expand Down Expand Up @@ -45,28 +48,30 @@ const LineChartStory = () => (
activeChartKey: "line",
}}
>
<InteractiveFiltersProvider>
<LineChart
observations={observations}
dimensions={dimensions}
dimensionsByIri={keyBy(dimensions, (d) => d.iri)}
measures={measures}
measuresByIri={keyBy(measures, (d) => d.iri)}
chartConfig={chartConfig}
aspectRatio={0.4}
>
<ChartContainer>
<ChartSvg>
<BrushTime />
<AxisHeightLinear /> <AxisTime /> <AxisTimeDomain />
<Lines />
</ChartSvg>
</ChartContainer>
<InteractiveFiltersProvider chartConfigs={[chartConfig]}>
<InteractiveFiltersChartProvider chartConfigKey={chartConfig.key}>
<LineChart
observations={observations}
dimensions={dimensions}
dimensionsByIri={keyBy(dimensions, (d) => d.iri)}
measures={measures}
measuresByIri={keyBy(measures, (d) => d.iri)}
chartConfig={chartConfig}
aspectRatio={0.4}
>
<ChartContainer>
<ChartSvg>
<BrushTime />
<AxisHeightLinear /> <AxisTime /> <AxisTimeDomain />
<Lines />
</ChartSvg>
</ChartContainer>

{fields.segment && (
<LegendColor chartConfig={chartConfig} symbol="line" interactive />
)}
</LineChart>
{fields.segment && (
<LegendColor chartConfig={chartConfig} symbol="line" interactive />
)}
</LineChart>
</InteractiveFiltersChartProvider>
</InteractiveFiltersProvider>
</ConfiguratorStateProvider>
);
Expand Down
24 changes: 13 additions & 11 deletions app/docs/tooltip.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
measures,
observations,
} from "@/docs/fixtures";
import { InteractiveFiltersProvider } from "@/stores/interactive-filters";
import { InteractiveFiltersChartProvider } from "@/stores/interactive-filters";
import { CHART_CONFIG_VERSION } from "@/utils/chart-config/versioning";

import { ReactSpecimen } from "./catalog";
Expand Down Expand Up @@ -60,7 +60,7 @@ const TooltipContent = ({ children }: { children: ReactNode }) => (

const TooltipBoxStory = () => (
<ReactSpecimen>
<InteractiveFiltersProvider>
<InteractiveFiltersChartProvider chartConfigKey="column-chart">
<ColumnChart
observations={observations}
measures={measures}
Expand Down Expand Up @@ -213,18 +213,20 @@ const TooltipBoxStory = () => (
</div>
</Flex>
</ColumnChart>
</InteractiveFiltersProvider>
</InteractiveFiltersChartProvider>
</ReactSpecimen>
);

export { TooltipBoxStory as TooltipBox };
export { TooltipContentStory as TooltipContent };
export { TooltipContentStory2 as TooltipContent2 };
export { RulerStory as Ruler };
export {
RulerStory as Ruler,
TooltipBoxStory as TooltipBox,
TooltipContentStory as TooltipContent,
TooltipContentStory2 as TooltipContent2,
};

const TooltipContentStory = {
render: () => (
<InteractiveFiltersProvider>
<InteractiveFiltersChartProvider chartConfigKey="column-chart">
<ColumnChart
observations={observations}
measures={measures}
Expand Down Expand Up @@ -287,13 +289,13 @@ const TooltipContentStory = {
</TooltipBox>
</div>
</ColumnChart>
</InteractiveFiltersProvider>
</InteractiveFiltersChartProvider>
),
};

export const TooltipContentStory2 = {
render: () => (
<InteractiveFiltersProvider>
<InteractiveFiltersChartProvider chartConfigKey="column-chart">
<ColumnChart
observations={observations}
measures={measures}
Expand Down Expand Up @@ -359,7 +361,7 @@ export const TooltipContentStory2 = {
</TooltipBox>
</div>
</ColumnChart>
</InteractiveFiltersProvider>
</InteractiveFiltersChartProvider>
),
};

Expand Down
28 changes: 10 additions & 18 deletions app/stores/interactive-filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ const InteractiveFiltersContext = createContext<
| undefined
>(undefined);

/**
* Returns filters that are shared across multiple charts.
*/
export const getSharedFilters = (
chartConfigs: ChartConfig[]
): SharedFilters => {
Expand All @@ -159,37 +162,26 @@ export const getSharedFilters = (
if (!interactiveFiltersConfig) {
return [];
}
const { timeRange, dataFilters, legend } = interactiveFiltersConfig;
return [
{ type: "timeRange" as const, value: timeRange },
// ...dataFilters.componentIris.map((ci) => ({
// type: "dataFilters" as const,
// value: {
// ...dataFilters,
// componentIri: ci,
// },
// })),
// { type: "legend" as const, value: legend },
].filter((x) => x.value.active);

const { timeRange } = interactiveFiltersConfig;
return [{ type: "timeRange" as const, value: timeRange }].filter(
(x) => x.value.active
);
});

const sharedFilters = Object.entries(
// TODO implement recognizing shared filters across joined by dimensions
groupBy(allActiveFilters, (x) => `${x.type} - ${x.value.componentIri}`)
).filter(([iri, filters]) => filters.length > 1);
).filter(([_iri, filters]) => filters.length > 1);

return sharedFilters.map(([iri, filters]) => ({
return sharedFilters.map(([_iri, filters]) => ({
iri: filters[0].value.componentIri,
type: filters[0].type,
value: (() => {
const type = filters[0].type;
switch (type) {
case "timeRange":
return filters[0].value;
// case "legend":
// return filters[0].value;
// case "dataFilters":
// return filters[0].value;
default:
const _exhaustiveCheck: never = type;
throw new Error(`Unhandled type: ${_exhaustiveCheck}`);
Expand Down

0 comments on commit 56b54cd

Please sign in to comment.