Skip to content

Commit 1341d12

Browse files
committed
feat(custom-chart-web): refactor, sizing calculations
1 parent 80b83d4 commit 1341d12

File tree

3 files changed

+78
-117
lines changed

3 files changed

+78
-117
lines changed

packages/pluggableWidgets/custom-chart-web/src/hooks/useCustomChart.ts

+25-38
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
import { debounce } from "@mendix/widget-plugin-platform/utils/debounce";
2-
import { useEffect, useMemo, useRef, useState, type RefObject } from "react";
2+
import { useEffect, useMemo, useRef, useState, type RefObject, CSSProperties } from "react";
33
import { CustomChartContainerProps } from "../../typings/CustomChartProps";
44
import { PlotlyChart, ChartProps } from "../components/PlotlyChart";
5-
import { ChartDataProcessor } from "../utils/ChartDataProcessor";
5+
import { parseData, parseLayout, parseConfig } from "../utils/utils";
66

77
interface UseCustomChartReturn {
88
chartRef: RefObject<HTMLDivElement>;
9-
containerStyle: {
10-
width?: string;
11-
height?: string;
12-
};
9+
containerStyle: CSSProperties;
1310
}
1411

1512
export function useCustomChart(props: CustomChartContainerProps): UseCustomChartReturn {
1613
const chartRef = useRef<HTMLDivElement>(null);
1714
const [chart, setChart] = useState<PlotlyChart | null>(null);
1815
const [containerDimensions, setContainerDimensions] = useState<{ width?: number; height?: number }>({});
19-
const dataProcessor = useRef(new ChartDataProcessor());
2016

2117
const [setContainerDimensionsDebounced, abortDimensionsDebounce] = useMemo(
2218
() =>
@@ -63,74 +59,65 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
6359
return;
6460
}
6561

66-
const data = dataProcessor.current.parseData(props.dataStatic, props.dataAttribute?.value, props.sampleData);
67-
68-
const layout = dataProcessor.current.parseLayout(
69-
props.layoutStatic,
70-
props.layoutAttribute?.value,
71-
props.sampleLayout
72-
);
62+
const data = parseData(props.dataStatic, props.dataAttribute?.value, props.sampleData);
7363

74-
const dimensions = dataProcessor.current.calculateDimensions(
75-
props.widthUnit,
76-
props.width,
77-
props.heightUnit,
78-
props.height,
79-
containerDimensions.width,
80-
containerDimensions.height
81-
);
64+
const layout = parseLayout(props.layoutStatic, props.layoutAttribute?.value, props.sampleLayout);
8265

83-
const { width, height } = dimensions;
66+
const dimensions = {
67+
width: containerDimensions.width ?? 0,
68+
height: containerDimensions.height ?? 0
69+
};
8470

8571
const updateData: ChartProps = {
8672
data,
8773
layout: {
8874
...layout,
89-
width,
90-
height,
75+
width: dimensions.width,
76+
height: dimensions.height,
9177
autosize: true,
9278
font: {
9379
family: "Open Sans, sans-serif",
94-
size: Math.max(12 * (width / 1000), 8)
80+
size: Math.max(12 * (dimensions.width / 1000), 8)
9581
},
9682
legend: {
9783
...layout.legend,
9884
font: {
9985
...layout.legend?.font,
100-
size: Math.max(10 * (width / 1000), 7)
86+
size: Math.max(10 * (dimensions.width / 1000), 7)
10187
},
102-
itemwidth: Math.max(10 * (width / 1000), 3)
88+
itemwidth: Math.max(10 * (dimensions.width / 1000), 3),
89+
itemsizing: "constant"
10390
},
10491
xaxis: {
10592
...layout.xaxis,
10693
tickfont: {
10794
...layout.xaxis?.tickfont,
108-
size: Math.max(10 * (width / 1000), 7)
95+
size: Math.max(10 * (dimensions.width / 1000), 7)
10996
}
11097
},
11198
yaxis: {
11299
...layout.yaxis,
113100
tickfont: {
114101
...layout.yaxis?.tickfont,
115-
size: Math.max(10 * (width / 1000), 7)
102+
size: Math.max(10 * (dimensions.width / 1000), 7)
116103
}
117104
},
118105
margin: {
119106
...layout.margin,
120-
l: Math.max(50 * (width / 1000), 30),
121-
r: Math.max(50 * (width / 1000), 30),
122-
t: Math.max(50 * (width / 1000), 30),
123-
b: Math.max(50 * (width / 1000), 30),
124-
pad: Math.max(4 * (width / 1000), 2)
107+
l: Math.max(50 * (dimensions.width / 1000), 30),
108+
r: Math.max(50 * (dimensions.width / 1000), 30),
109+
t: Math.max(50 * (dimensions.width / 1000), 30),
110+
b: Math.max(50 * (dimensions.width / 1000), 30),
111+
pad: Math.max(4 * (dimensions.width / 1000), 2)
125112
}
126113
},
127114
config: {
128-
...dataProcessor.current.parseConfig(props.configurationOptions),
115+
...parseConfig(props.configurationOptions),
129116
displayModeBar: props.devMode === "developer",
130117
responsive: true
131118
},
132-
width,
133-
height
119+
width: dimensions.width,
120+
height: dimensions.height
134121
};
135122

136123
updateChartDebounced(chart, updateData);

packages/pluggableWidgets/custom-chart-web/src/utils/ChartDataProcessor.ts

-79
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Config, Data, Layout } from "plotly.js-dist-min";
2+
3+
export function parseData(staticData?: string, attributeData?: string, sampleData?: string): Data[] {
4+
let finalData: Data[] = [];
5+
6+
try {
7+
if (staticData) {
8+
finalData = [...finalData, ...JSON.parse(staticData)];
9+
}
10+
if (attributeData) {
11+
finalData = [...finalData, ...JSON.parse(attributeData)];
12+
}
13+
if (!finalData.length && sampleData) {
14+
finalData = [...finalData, ...JSON.parse(sampleData)];
15+
}
16+
} catch (error) {
17+
console.error("Error parsing chart data:", error);
18+
}
19+
20+
return finalData;
21+
}
22+
23+
export function parseLayout(staticLayout?: string, attributeLayout?: string, sampleLayout?: string): Partial<Layout> {
24+
let finalLayout: Partial<Layout> = {};
25+
26+
try {
27+
if (staticLayout) {
28+
finalLayout = { ...finalLayout, ...JSON.parse(staticLayout) };
29+
}
30+
if (attributeLayout) {
31+
finalLayout = { ...finalLayout, ...JSON.parse(attributeLayout) };
32+
}
33+
if (Object.keys(finalLayout).length === 0 && sampleLayout) {
34+
finalLayout = { ...finalLayout, ...JSON.parse(sampleLayout) };
35+
}
36+
} catch (error) {
37+
console.error("Error parsing chart layout:", error);
38+
}
39+
return finalLayout;
40+
}
41+
42+
export function parseConfig(configOptions?: string): Partial<Config> {
43+
if (!configOptions) {
44+
return {};
45+
}
46+
47+
try {
48+
return JSON.parse(configOptions);
49+
} catch (error) {
50+
console.error("Error parsing chart config:", error);
51+
return {};
52+
}
53+
}

0 commit comments

Comments
 (0)