Skip to content

Commit

Permalink
feat(custom-charts-web): add onclick, layout sizing, preview styling
Browse files Browse the repository at this point in the history
  • Loading branch information
rahmanunver committed Jan 20, 2025
1 parent 36c4231 commit 7f10941
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 467 deletions.
2 changes: 1 addition & 1 deletion packages/pluggableWidgets/custom-chart-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"marketplace": {
"minimumMXVersion": "10.16.0",
"appNumber": 1234,
"appName": "CustomChart"
"appName": "Custom chart"
},
"testProject": {
"githubUrl": "https://github.com/mendix/testProjects",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { Properties } from "@mendix/pluggable-widgets-tools";
import {
StructurePreviewProps,
structurePreviewPalette
} from "@mendix/widget-plugin-platform/preview/structure-preview-api";
import { CustomChartPreviewProps } from "../typings/CustomChartProps";

export function getProperties(_values: CustomChartPreviewProps, defaultProperties: Properties): Properties {
return defaultProperties;
}

export function getPreview(_values: CustomChartPreviewProps, isDarkMode: boolean): StructurePreviewProps {
const palette = structurePreviewPalette[isDarkMode ? "dark" : "light"];
const sampleChartSvg = `
Expand Down Expand Up @@ -33,7 +38,7 @@ export function getPreview(_values: CustomChartPreviewProps, isDarkMode: boolean
children: [
{
type: "Text",
content: "Any Chart",
content: "Custom Chart",
fontColor: palette.text.primary,
fontSize: 10,
bold: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const defaultConfig = `{

export function preview(props: CustomChartPreviewProps): ReactElement {
const containerProps = {
name: "preview-chart",
name: "preview-custom-chart",
class: props.class,
style: props.styleObject,
tabIndex: 0,
Expand All @@ -51,10 +51,11 @@ export function preview(props: CustomChartPreviewProps): ReactElement {
sampleLayout: props.sampleLayout,
configurationOptions: props.configurationOptions || defaultConfig,
widthUnit: props.widthUnit,
width: props.width || 100,
width: props.width || 75,
heightUnit: props.heightUnit,
height: props.height || 75
};
console.log(containerProps);

return <CustomChart {...containerProps} />;
}
12 changes: 11 additions & 1 deletion packages/pluggableWidgets/custom-chart-web/src/CustomChart.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { ReactElement, createElement } from "react";
import { CustomChartContainerProps } from "../typings/CustomChartProps";
import { useCustomChart } from "./hooks/useCustomChart";
import { useActionEvents } from "./hooks/useActionEvents";
import "./ui/CustomChart.scss";

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

return <div ref={chartRef} className="widget-custom-chart" style={containerStyle} tabIndex={props.tabIndex} />;
return (
<div
ref={chartRef}
className="widget-custom-chart"
style={containerStyle}
tabIndex={props.tabIndex}
onClick={handleClick}
/>
);
}
14 changes: 9 additions & 5 deletions packages/pluggableWidgets/custom-chart-web/src/CustomChart.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<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">
<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">
<name>Custom chart</name>
<description>Create a custom chart</description>
<studioProCategory>Charts</studioProCategory>
Expand Down Expand Up @@ -80,8 +80,12 @@
<description />
</property>
</propertyGroup>
<!-- <propertyGroup caption="Events">
<property key="eventEntity" type="association" required="false" setLabel="true">
<propertyGroup caption="Events">
<property key="onClick" type="action" required="false">
<caption>On click</caption>
<description />
</property>
<!-- <property key="eventEntity" type="association" required="false" setLabel="true">
<caption>Event entity</caption>
<description>The entity used to pass the event data to the server</description>
<associationTypes>
Expand Down Expand Up @@ -119,8 +123,8 @@
<property key="tooltipForm" type="form" required="false">
<caption>Tooltip form</caption>
<description>The form to show when a user hovers over a chart plot point, context uses 'Tooltip entity'</description>
</property>
</propertyGroup> -->
</property> -->
</propertyGroup>
<propertyGroup caption="Common">
<systemProperty key="Name" />
<systemProperty key="TabIndex" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { executeAction } from "@mendix/widget-plugin-platform/framework/execute-action";
import { useCallback } from "react";
import { CustomChartContainerProps } from "typings/CustomChartProps";

export function useActionEvents(props: CustomChartContainerProps): {
handleClick: () => void;
} {
const handleClick = useCallback((): void => {
if (props.onClick) {
executeAction(props.onClick);
}
}, [props.onClick]);

return { handleClick };
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { debounce } from "@mendix/widget-plugin-platform/utils/debounce";
import { useEffect, useMemo, useRef, useState, type RefObject } from "react";
import { CustomChartContainerProps } from "../../typings/CustomChartProps";
import { PlotlyChart } from "../components/PlotlyChart";
import { PlotlyChart, ChartProps } from "../components/PlotlyChart";
import { ChartDataProcessor } from "../utils/ChartDataProcessor";

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

const [updateChartDebounced, abortChartUpdate] = useMemo(
() =>
debounce(
(
chartInstance: PlotlyChart | null,
updateData: {
data: any;
layout: any;
config: any;
width: number;
height: number;
}
) => {
if (!chartInstance) {
const newChart = new PlotlyChart(chartRef.current!, updateData);
setChart(newChart);
} else {
chartInstance.update(updateData);
}
},
100
),
debounce((chartInstance: PlotlyChart | null, updateData: ChartProps) => {
if (!chartInstance) {
const newChart = new PlotlyChart(chartRef.current!, updateData);
setChart(newChart);
} else {
chartInstance.update(updateData);
}
}, 100),
[]
);

Expand Down Expand Up @@ -83,19 +71,18 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
props.sampleLayout
);

const { width, height } = {
width: containerDimensions.width,
height: dataProcessor.current.calculateDimensions(
props.widthUnit,
props.width,
props.heightUnit,
props.height,
containerDimensions.width,
containerDimensions.height
).height
};
const dimensions = dataProcessor.current.calculateDimensions(
props.widthUnit,
props.width,
props.heightUnit,
props.height,
containerDimensions.width,
containerDimensions.height
);

const updateData = {
const { width, height } = dimensions;

const updateData: ChartProps = {
data,
layout: {
...layout,
Expand All @@ -104,14 +91,43 @@ export function useCustomChart(props: CustomChartContainerProps): UseCustomChart
autosize: true,
font: {
family: "Open Sans, sans-serif",
size: 12
size: Math.max(12 * (width / 1000), 8)
},
legend: {
...layout.legend,
font: {
...layout.legend?.font,
size: Math.max(10 * (width / 1000), 7)
},
itemwidth: Math.max(10 * (width / 1000), 3)
},
xaxis: {
...layout.xaxis,
tickfont: {
...layout.xaxis?.tickfont,
size: Math.max(10 * (width / 1000), 7)
}
},
yaxis: {
...layout.yaxis,
tickfont: {
...layout.yaxis?.tickfont,
size: Math.max(10 * (width / 1000), 7)
}
},
margin: {
...layout.margin,
l: Math.max(50 * (width / 1000), 30),
r: Math.max(50 * (width / 1000), 30),
t: Math.max(50 * (width / 1000), 30),
b: Math.max(50 * (width / 1000), 30),
pad: Math.max(4 * (width / 1000), 2)
}
},
config: {
...dataProcessor.current.parseConfig(props.configurationOptions),
displayModeBar: props.devMode === "developer",
responsive: true,
staticPlot: false
responsive: true
},
width,
height
Expand Down
13 changes: 11 additions & 2 deletions packages/pluggableWidgets/custom-chart-web/src/ui/CustomChart.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
.widget-custom-chart {
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
.svg-container {
.main-svg {
position: absolute;
top: 0;
left: 0;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Config, Data, Layout } from "plotly.js-dist";
import { Config, Data, Layout } from "plotly.js-dist-min";

export class ChartDataProcessor {
parseData(staticData?: string, attributeData?: string, sampleData?: string): Data[] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* @author Mendix Widgets Framework Team
*/
import { CSSProperties } from "react";
import { EditableValue } from "mendix";
import { ActionValue, EditableValue } from "mendix";

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

Expand All @@ -29,6 +29,7 @@ export interface CustomChartContainerProps {
width: number;
heightUnit: HeightUnitEnum;
height: number;
onClick?: ActionValue;
}

export interface CustomChartPreviewProps {
Expand All @@ -53,4 +54,5 @@ export interface CustomChartPreviewProps {
width: number | null;
heightUnit: HeightUnitEnum;
height: number | null;
onClick: {} | null;
}
Loading

0 comments on commit 7f10941

Please sign in to comment.