Skip to content

Commit 881f7ff

Browse files
committed
feat(custom-charts-web): add onclick, layout sizing, preview styling
1 parent 966fb1a commit 881f7ff

11 files changed

+137
-75
lines changed

packages/pluggableWidgets/custom-chart-web/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"marketplace": {
2222
"minimumMXVersion": "10.16.0",
2323
"appNumber": 1234,
24-
"appName": "CustomChart"
24+
"appName": "Custom chart"
2525
},
2626
"testProject": {
2727
"githubUrl": "https://github.com/mendix/testProjects",

packages/pluggableWidgets/custom-chart-web/src/CustomChart.editorConfig.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
import { Properties } from "@mendix/pluggable-widgets-tools";
12
import {
23
StructurePreviewProps,
34
structurePreviewPalette
45
} from "@mendix/widget-plugin-platform/preview/structure-preview-api";
56
import { CustomChartPreviewProps } from "../typings/CustomChartProps";
67

8+
export function getProperties(_values: CustomChartPreviewProps, defaultProperties: Properties): Properties {
9+
return defaultProperties;
10+
}
11+
712
export function getPreview(_values: CustomChartPreviewProps, isDarkMode: boolean): StructurePreviewProps {
813
const palette = structurePreviewPalette[isDarkMode ? "dark" : "light"];
914
const sampleChartSvg = `
@@ -33,7 +38,7 @@ export function getPreview(_values: CustomChartPreviewProps, isDarkMode: boolean
3338
children: [
3439
{
3540
type: "Text",
36-
content: "Any Chart",
41+
content: "Custom Chart",
3742
fontColor: palette.text.primary,
3843
fontSize: 10,
3944
bold: true

packages/pluggableWidgets/custom-chart-web/src/CustomChart.editorPreview.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const defaultConfig = `{
4040

4141
export function preview(props: CustomChartPreviewProps): ReactElement {
4242
const containerProps = {
43-
name: "preview-chart",
43+
name: "preview-custom-chart",
4444
class: props.class,
4545
style: props.styleObject,
4646
tabIndex: 0,
@@ -51,10 +51,11 @@ export function preview(props: CustomChartPreviewProps): ReactElement {
5151
sampleLayout: props.sampleLayout,
5252
configurationOptions: props.configurationOptions || defaultConfig,
5353
widthUnit: props.widthUnit,
54-
width: props.width || 100,
54+
width: props.width || 75,
5555
heightUnit: props.heightUnit,
5656
height: props.height || 75
5757
};
58+
console.log(containerProps);
5859

5960
return <CustomChart {...containerProps} />;
6061
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import { ReactElement, createElement } from "react";
22
import { CustomChartContainerProps } from "../typings/CustomChartProps";
33
import { useCustomChart } from "./hooks/useCustomChart";
4+
import { useActionEvents } from "./hooks/useActionEvents";
45
import "./ui/CustomChart.scss";
56

67
export default function CustomChart(props: CustomChartContainerProps): ReactElement {
78
const { chartRef, containerStyle } = useCustomChart(props);
9+
const { handleClick } = useActionEvents(props);
810

9-
return <div ref={chartRef} className="widget-custom-chart" style={containerStyle} tabIndex={props.tabIndex} />;
11+
return (
12+
<div
13+
ref={chartRef}
14+
className="widget-custom-chart"
15+
style={containerStyle}
16+
tabIndex={props.tabIndex}
17+
onClick={handleClick}
18+
/>
19+
);
1020
}

packages/pluggableWidgets/custom-chart-web/src/CustomChart.xml

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8" ?>
2-
<widget id="com.mendix.widget.web.custom-chart.CustomChart" pluginWidget="true" offlineCapable="true" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
2+
<widget id="com.mendix.widget.web.customchart.CustomChart" pluginWidget="true" offlineCapable="true" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
33
<name>Custom chart</name>
44
<description>Create a custom chart</description>
55
<studioProCategory>Charts</studioProCategory>
@@ -80,8 +80,12 @@
8080
<description />
8181
</property>
8282
</propertyGroup>
83-
<!-- <propertyGroup caption="Events">
84-
<property key="eventEntity" type="association" required="false" setLabel="true">
83+
<propertyGroup caption="Events">
84+
<property key="onClick" type="action" required="false">
85+
<caption>On click</caption>
86+
<description />
87+
</property>
88+
<!-- <property key="eventEntity" type="association" required="false" setLabel="true">
8589
<caption>Event entity</caption>
8690
<description>The entity used to pass the event data to the server</description>
8791
<associationTypes>
@@ -119,8 +123,8 @@
119123
<property key="tooltipForm" type="form" required="false">
120124
<caption>Tooltip form</caption>
121125
<description>The form to show when a user hovers over a chart plot point, context uses 'Tooltip entity'</description>
122-
</property>
123-
</propertyGroup> -->
126+
</property> -->
127+
</propertyGroup>
124128
<propertyGroup caption="Common">
125129
<systemProperty key="Name" />
126130
<systemProperty key="TabIndex" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action";
2+
import { useCallback } from "react";
3+
import { CustomChartContainerProps } from "typings/CustomChartProps";
4+
5+
export function useActionEvents(props: CustomChartContainerProps): {
6+
handleClick: () => void;
7+
} {
8+
const handleClick = useCallback((): void => {
9+
if (props.onClick) {
10+
executeAction(props.onClick);
11+
}
12+
}, [props.onClick]);
13+
14+
return { handleClick };
15+
}

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

+52-36
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { debounce } from "@mendix/widget-plugin-platform/utils/debounce";
22
import { useEffect, useMemo, useRef, useState, type RefObject } from "react";
33
import { CustomChartContainerProps } from "../../typings/CustomChartProps";
4-
import { PlotlyChart } from "../components/PlotlyChart";
4+
import { PlotlyChart, ChartProps } from "../components/PlotlyChart";
55
import { ChartDataProcessor } from "../utils/ChartDataProcessor";
66

77
interface UseCustomChartReturn {
@@ -28,26 +28,14 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
2828

2929
const [updateChartDebounced, abortChartUpdate] = useMemo(
3030
() =>
31-
debounce(
32-
(
33-
chartInstance: PlotlyChart | null,
34-
updateData: {
35-
data: any;
36-
layout: any;
37-
config: any;
38-
width: number;
39-
height: number;
40-
}
41-
) => {
42-
if (!chartInstance) {
43-
const newChart = new PlotlyChart(chartRef.current!, updateData);
44-
setChart(newChart);
45-
} else {
46-
chartInstance.update(updateData);
47-
}
48-
},
49-
100
50-
),
31+
debounce((chartInstance: PlotlyChart | null, updateData: ChartProps) => {
32+
if (!chartInstance) {
33+
const newChart = new PlotlyChart(chartRef.current!, updateData);
34+
setChart(newChart);
35+
} else {
36+
chartInstance.update(updateData);
37+
}
38+
}, 100),
5139
[]
5240
);
5341

@@ -83,19 +71,18 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
8371
props.sampleLayout
8472
);
8573

86-
const { width, height } = {
87-
width: containerDimensions.width,
88-
height: dataProcessor.current.calculateDimensions(
89-
props.widthUnit,
90-
props.width,
91-
props.heightUnit,
92-
props.height,
93-
containerDimensions.width,
94-
containerDimensions.height
95-
).height
96-
};
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+
);
9782

98-
const updateData = {
83+
const { width, height } = dimensions;
84+
85+
const updateData: ChartProps = {
9986
data,
10087
layout: {
10188
...layout,
@@ -104,14 +91,43 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
10491
autosize: true,
10592
font: {
10693
family: "Open Sans, sans-serif",
107-
size: 12
94+
size: Math.max(12 * (width / 1000), 8)
95+
},
96+
legend: {
97+
...layout.legend,
98+
font: {
99+
...layout.legend?.font,
100+
size: Math.max(10 * (width / 1000), 7)
101+
},
102+
itemwidth: Math.max(10 * (width / 1000), 3)
103+
},
104+
xaxis: {
105+
...layout.xaxis,
106+
tickfont: {
107+
...layout.xaxis?.tickfont,
108+
size: Math.max(10 * (width / 1000), 7)
109+
}
110+
},
111+
yaxis: {
112+
...layout.yaxis,
113+
tickfont: {
114+
...layout.yaxis?.tickfont,
115+
size: Math.max(10 * (width / 1000), 7)
116+
}
117+
},
118+
margin: {
119+
...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)
108125
}
109126
},
110127
config: {
111128
...dataProcessor.current.parseConfig(props.configurationOptions),
112129
displayModeBar: props.devMode === "developer",
113-
responsive: true,
114-
staticPlot: false
130+
responsive: true
115131
},
116132
width,
117133
height
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
.widget-custom-chart {
2-
width: 100%;
3-
height: 100%;
2+
position: relative;
3+
display: flex;
4+
flex-direction: column;
5+
align-items: stretch;
6+
.svg-container {
7+
.main-svg {
8+
position: absolute;
9+
top: 0;
10+
left: 0;
11+
}
12+
}
413
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Config, Data, Layout } from "plotly.js-dist";
1+
import { Config, Data, Layout } from "plotly.js-dist-min";
22

33
export class ChartDataProcessor {
44
parseData(staticData?: string, attributeData?: string, sampleData?: string): Data[] {

packages/pluggableWidgets/custom-chart-web/typings/CustomChartProps.d.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @author Mendix Widgets Framework Team
55
*/
66
import { CSSProperties } from "react";
7-
import { EditableValue } from "mendix";
7+
import { ActionValue, EditableValue } from "mendix";
88

99
export type DevModeEnum = "developer" | "advanced";
1010

@@ -29,6 +29,7 @@ export interface CustomChartContainerProps {
2929
width: number;
3030
heightUnit: HeightUnitEnum;
3131
height: number;
32+
onClick?: ActionValue;
3233
}
3334

3435
export interface CustomChartPreviewProps {
@@ -53,4 +54,5 @@ export interface CustomChartPreviewProps {
5354
width: number | null;
5455
heightUnit: HeightUnitEnum;
5556
height: number | null;
57+
onClick: {} | null;
5658
}

pnpm-lock.yaml

+25-25
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)