Skip to content

Commit 190c64e

Browse files
committed
fix(charts-web): add aggregate utils for charts
1 parent 51e68bf commit 190c64e

File tree

8 files changed

+181
-95
lines changed

8 files changed

+181
-95
lines changed

packages/pluggableWidgets/area-chart-web/src/AreaChart.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import {
33
ChartWidgetProps,
44
SeriesMapper,
55
containerPropsEqual,
6-
getPlotChartDataTransforms,
76
usePlotChartDataSeries
87
} from "@mendix/shared-charts/main";
8+
import { aggregateDataPoints } from "@mendix/shared-charts/utils/aggregations";
99
import "@mendix/shared-charts/ui/Chart.scss";
1010
import classNames from "classnames";
1111
import { createElement, memo, ReactElement, useCallback } from "react";
@@ -37,25 +37,31 @@ export const AreaChart = memo(function AreaChart(props: AreaChartContainerProps)
3737
const lineColorExpression = line.dataSet === "static" ? line.staticLineColor : line.dynamicLineColor;
3838
const markerColorExpression = line.dataSet === "static" ? line.staticMarkerColor : line.dynamicMarkerColor;
3939
const fillColorExpression = line.dataSet === "static" ? line.staticFillColor : line.dynamicFillColor;
40+
const pts =
41+
line.aggregationType === "none" ? dataPoints : aggregateDataPoints(line.aggregationType, dataPoints);
42+
4043
return {
4144
type: "scatter",
4245
fill: "tonexty",
4346
fillcolor: fillColorExpression
44-
? getExpressionValue<string>(fillColorExpression, dataPoints.dataSourceItems)
47+
? getExpressionValue<string>(fillColorExpression, pts.dataSourceItems)
4548
: undefined,
4649
mode: line.lineStyle === "line" ? "lines" : "lines+markers",
4750
line: {
4851
shape: line.interpolation,
4952
color: lineColorExpression
50-
? getExpressionValue<string>(lineColorExpression, dataPoints.dataSourceItems)
53+
? getExpressionValue<string>(lineColorExpression, pts.dataSourceItems)
5154
: undefined
5255
},
5356
marker: {
5457
color: markerColorExpression
55-
? getExpressionValue<string>(markerColorExpression, dataPoints.dataSourceItems)
58+
? getExpressionValue<string>(markerColorExpression, pts.dataSourceItems)
5659
: undefined
5760
},
58-
transforms: getPlotChartDataTransforms(line.aggregationType, dataPoints)
61+
x: pts.x,
62+
y: pts.y,
63+
hovertext: pts.hovertext,
64+
hoverinfo: pts.hoverinfo
5965
};
6066
}, []);
6167

packages/pluggableWidgets/bar-chart-web/src/BarChart.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import {
2-
ChartWidget,
3-
ChartWidgetProps,
4-
containerPropsEqual,
5-
getPlotChartDataTransforms,
6-
usePlotChartDataSeries
7-
} from "@mendix/shared-charts/main";
1+
import { ChartWidget, ChartWidgetProps, containerPropsEqual, usePlotChartDataSeries } from "@mendix/shared-charts/main";
82
import "@mendix/shared-charts/ui/Chart.scss";
93
import classNames from "classnames";
104
import { ReactElement, createElement, memo, useCallback, useMemo } from "react";
5+
import { aggregateDataPoints } from "@mendix/shared-charts/utils/aggregations";
116

127
import { BarChartContainerProps } from "../typings/BarChartProps";
138

@@ -51,15 +46,22 @@ export const BarChart = memo(function BarChart(props: BarChartContainerProps): R
5146
useCallback((dataSeries, dataPoints, { getExpressionValue }) => {
5247
const barColorExpression =
5348
dataSeries.dataSet === "static" ? dataSeries.staticBarColor : dataSeries.dynamicBarColor;
49+
const pts =
50+
dataSeries.aggregationType === "none"
51+
? dataPoints
52+
: aggregateDataPoints(dataSeries.aggregationType, dataPoints);
5453
return {
5554
type: "bar",
5655
orientation: "h",
5756
marker: {
5857
color: barColorExpression
59-
? getExpressionValue<string>(barColorExpression, dataPoints.dataSourceItems)
58+
? getExpressionValue<string>(barColorExpression, pts.dataSourceItems)
6059
: undefined
6160
},
62-
transforms: getPlotChartDataTransforms(dataSeries.aggregationType, dataPoints)
61+
x: pts.x,
62+
y: pts.y,
63+
hovertext: pts.hovertext,
64+
hoverinfo: pts.hoverinfo
6365
};
6466
}, [])
6567
);

packages/pluggableWidgets/bubble-chart-web/src/BubbleChart.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
import {
2-
ChartWidget,
3-
ChartWidgetProps,
4-
getPlotChartDataTransforms,
5-
traceEqual,
6-
usePlotChartDataSeries
7-
} from "@mendix/shared-charts/main";
1+
import { ChartWidget, ChartWidgetProps, traceEqual, usePlotChartDataSeries } from "@mendix/shared-charts/main";
82
import "@mendix/shared-charts/ui/Chart.scss";
93
import { defaultEqual, flatEqual } from "@mendix/widget-plugin-platform/utils/flatEqual";
104
import Big from "big.js";
115
import classNames from "classnames";
126
import { ReactElement, createElement, memo, useCallback } from "react";
137
import { BubbleChartContainerProps, LinesType } from "../typings/BubbleChartProps";
148
import { calculateSizeRef } from "./utils";
9+
import { aggregateDataPoints } from "@mendix/shared-charts/utils/aggregations";
1510

1611
const bubbleChartLayoutOptions: ChartWidgetProps["layoutOptions"] = {
1712
xaxis: {
@@ -75,18 +70,25 @@ export const BubbleChart = memo(
7570
);
7671
const markerColorExpression =
7772
line.dataSet === "static" ? line.staticMarkerColor : line.dynamicMarkerColor;
73+
const pts =
74+
line.aggregationType === "none"
75+
? dataPoints
76+
: aggregateDataPoints(line.aggregationType, dataPoints);
7877
return {
7978
type: "scatter",
8079
mode: "markers",
8180
marker: {
8281
color: markerColorExpression
83-
? getExpressionValue<string>(markerColorExpression, dataPoints.dataSourceItems)
82+
? getExpressionValue<string>(markerColorExpression, pts.dataSourceItems)
8483
: undefined,
8584
symbol: ["circle"],
8685
size,
8786
...markerOptions
8887
},
89-
transforms: getPlotChartDataTransforms(line.aggregationType, dataPoints)
88+
x: pts.x,
89+
y: pts.y,
90+
hovertext: pts.hovertext,
91+
hoverinfo: pts.hoverinfo
9092
};
9193
}, [])
9294
);

packages/pluggableWidgets/column-chart-web/src/ColumnChart.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
import {
2-
ChartWidget,
3-
ChartWidgetProps,
4-
containerPropsEqual,
5-
getPlotChartDataTransforms,
6-
usePlotChartDataSeries
7-
} from "@mendix/shared-charts/main";
1+
import { ChartWidget, ChartWidgetProps, containerPropsEqual, usePlotChartDataSeries } from "@mendix/shared-charts/main";
82
import "@mendix/shared-charts/ui/Chart.scss";
93
import classNames from "classnames";
104
import { ReactElement, createElement, memo, useCallback, useMemo } from "react";
115
import { ColumnChartContainerProps } from "../typings/ColumnChartProps";
6+
import { aggregateDataPoints } from "@mendix/shared-charts/utils/aggregations";
127

138
const columnChartLayoutOptions: ChartWidgetProps["layoutOptions"] = {
149
xaxis: {
@@ -51,13 +46,20 @@ export const ColumnChart = memo(function ColumnChart(props: ColumnChartContainer
5146
useCallback((dataSeries, dataPoints, { getExpressionValue }) => {
5247
const columnColorExpression =
5348
dataSeries.dataSet === "static" ? dataSeries.staticBarColor : dataSeries.dynamicBarColor;
49+
const pts =
50+
dataSeries.aggregationType === "none"
51+
? dataPoints
52+
: aggregateDataPoints(dataSeries.aggregationType, dataPoints);
5453
return {
5554
marker: {
5655
color: columnColorExpression
57-
? getExpressionValue<string>(columnColorExpression, dataPoints.dataSourceItems)
56+
? getExpressionValue<string>(columnColorExpression, pts.dataSourceItems)
5857
: undefined
5958
},
60-
transforms: getPlotChartDataTransforms(dataSeries.aggregationType, dataPoints)
59+
x: pts.x,
60+
y: pts.y,
61+
hovertext: pts.hovertext,
62+
hoverinfo: pts.hoverinfo
6163
};
6264
}, [])
6365
);

packages/pluggableWidgets/line-chart-web/src/LineChart.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
import {
2-
ChartWidget,
3-
ChartWidgetProps,
4-
getPlotChartDataTransforms,
5-
traceEqual,
6-
usePlotChartDataSeries
7-
} from "@mendix/shared-charts/main";
1+
import { ChartWidget, ChartWidgetProps, traceEqual, usePlotChartDataSeries } from "@mendix/shared-charts/main";
2+
import { aggregateDataPoints } from "@mendix/shared-charts/utils/aggregations";
83
import "@mendix/shared-charts/ui/Chart.scss";
94
import { defaultEqual, flatEqual } from "@mendix/widget-plugin-platform/utils/flatEqual";
105
import classNames from "classnames";
@@ -40,22 +35,28 @@ export const LineChart = memo(
4035
const lineColorExpression = line.dataSet === "static" ? line.staticLineColor : line.dynamicLineColor;
4136
const markerColorExpression =
4237
line.dataSet === "static" ? line.staticMarkerColor : line.dynamicMarkerColor;
43-
38+
const pts =
39+
line.aggregationType === "none"
40+
? dataPoints
41+
: aggregateDataPoints(line.aggregationType, dataPoints);
4442
return {
4543
type: "scatter",
4644
mode: line.lineStyle === "line" ? "lines" : "lines+markers",
4745
line: {
4846
shape: line.interpolation,
4947
color: lineColorExpression
50-
? getExpressionValue<string>(lineColorExpression, dataPoints.dataSourceItems)
48+
? getExpressionValue<string>(lineColorExpression, pts.dataSourceItems)
5149
: undefined
5250
},
5351
marker: {
5452
color: markerColorExpression
55-
? getExpressionValue<string>(markerColorExpression, dataPoints.dataSourceItems)
53+
? getExpressionValue<string>(markerColorExpression, pts.dataSourceItems)
5654
: undefined
5755
},
58-
transforms: getPlotChartDataTransforms(line.aggregationType, dataPoints)
56+
x: pts.x,
57+
y: pts.y,
58+
hovertext: pts.hovertext,
59+
hoverinfo: pts.hoverinfo
5960
};
6061
}, [])
6162
);

packages/pluggableWidgets/time-series-chart-web/src/TimeSeries.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
import {
2-
ChartWidget,
3-
ChartWidgetProps,
4-
getPlotChartDataTransforms,
5-
usePlotChartDataSeries,
6-
traceEqual
7-
} from "@mendix/shared-charts/main";
1+
import { ChartWidget, ChartWidgetProps, usePlotChartDataSeries, traceEqual } from "@mendix/shared-charts/main";
2+
import { aggregateDataPoints } from "@mendix/shared-charts/utils/aggregations";
83
import "@mendix/shared-charts/ui/Chart.scss";
94
import { defaultEqual, flatEqual } from "@mendix/widget-plugin-platform/utils/flatEqual";
105
import classNames from "classnames";
@@ -62,8 +57,12 @@ export const TimeSeries = memo(
6257
function TimeSeries(props: TimeSeriesContainerProps): ReactElement | null {
6358
const chartLines = usePlotChartDataSeries(
6459
props.lines,
65-
useCallback(
66-
(line, dataPoints) => ({
60+
useCallback((line, dataPoints) => {
61+
const pts =
62+
line.aggregationType === "none"
63+
? dataPoints
64+
: aggregateDataPoints(line.aggregationType, dataPoints);
65+
return {
6766
mode: line.lineStyle === "line" ? "lines" : "lines+markers",
6867
fill: line.enableFillArea ? "tonexty" : "none",
6968
fillcolor: line.fillColor?.value,
@@ -74,10 +73,12 @@ export const TimeSeries = memo(
7473
marker: {
7574
color: line.markerColor?.value
7675
},
77-
transforms: getPlotChartDataTransforms(line.aggregationType, dataPoints)
78-
}),
79-
[]
80-
)
76+
x: pts.x,
77+
y: pts.y,
78+
hovertext: pts.hovertext,
79+
hoverinfo: pts.hoverinfo
80+
};
81+
}, [])
8182
);
8283

8384
const timeSeriesLayout = useMemo<ChartWidgetProps["layoutOptions"]>(

packages/shared/charts/src/hooks/usePlotChartDataSeries.ts

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ExtraTraceProps } from "../components/types";
1717
// Use "value" prop on EditableValue to extract AttributeValue, as AttributeValue not exported.
1818
type AttributeValue = EditableValue["value"];
1919

20-
type PlotChartDataPoints = {
20+
export type PlotChartDataPoints = {
2121
x: Datum[];
2222
y: Datum[];
2323
hovertext: string[] | undefined;
@@ -102,10 +102,10 @@ function loadStaticSeries(series: PlotDataSeries, mapSerie: SeriesMapper<PlotDat
102102

103103
return {
104104
...(onClickAction ? { onClick: bindListAction(onClickAction) } : undefined),
105-
...mapSerie(series, dataPoints, mapperHelpers),
106105
...dataPoints,
106+
...mapSerie(series, dataPoints, mapperHelpers),
107107
customSeriesOptions
108-
};
108+
} as PlotChartSeries;
109109
}
110110

111111
function loadDynamicSeries(series: PlotDataSeries, mapSerie: SeriesMapper<PlotDataSeries>): PlotChartSeries[] | null {
@@ -116,27 +116,25 @@ function loadDynamicSeries(series: PlotDataSeries, mapSerie: SeriesMapper<PlotDa
116116
}
117117

118118
const dataSourceItemGroups = groupDataSourceItems(series);
119-
120119
if (!dataSourceItemGroups) {
121120
return null;
122121
}
123122

124123
const loadedSeries = dataSourceItemGroups
125124
.map(itemGroup => {
126125
const dataPoints = extractDataPoints(series, itemGroup.dynamicNameValue, itemGroup.items);
127-
128126
if (!dataPoints) {
129127
return null;
130128
}
131129

132130
return {
133131
...(onClickAction ? { onClick: bindListAction(onClickAction) } : undefined),
134-
...mapSerie(series, dataPoints, mapperHelpers),
135132
...dataPoints,
133+
...mapSerie(series, dataPoints, mapperHelpers),
136134
customSeriesOptions
137-
};
135+
} as PlotChartSeries;
138136
})
139-
.filter((element): element is PlotChartSeries => Boolean(element));
137+
.filter((e): e is PlotChartSeries => Boolean(e));
140138

141139
return loadedSeries;
142140
}
@@ -249,37 +247,6 @@ function extractDataPoints(
249247
};
250248
}
251249

252-
type AggregationTypeEnum = "none" | "count" | "sum" | "avg" | "min" | "max" | "median" | "mode" | "first" | "last";
253-
254-
export function getPlotChartDataTransforms(
255-
aggregationType: AggregationTypeEnum,
256-
dataPoints: PlotChartDataPoints
257-
): PlotData["transforms"] {
258-
if (aggregationType === "none") {
259-
return [];
260-
}
261-
return [
262-
{
263-
type: "aggregate",
264-
groups: dataPoints.x.map(dataPoint => {
265-
if (dataPoint == null) {
266-
return "";
267-
}
268-
return typeof dataPoint === "string" || typeof dataPoint === "number"
269-
? dataPoint.toLocaleString()
270-
: dataPoint.toLocaleDateString();
271-
}),
272-
aggregations: [
273-
{
274-
target: "y",
275-
func: aggregationType,
276-
enabled: true
277-
}
278-
]
279-
}
280-
];
281-
}
282-
283250
export const mapperHelpers: MapperHelpers = {
284251
// NOTE: For now ignore explicit "return undefined" statements. They exist just to make TS happy.
285252
getExpressionValue(attr, items) {

0 commit comments

Comments
 (0)