@carto/ps-react-ui 4.3.4 → 4.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types/widgets/echart/echart-ui.d.ts +1 -1
- package/dist/types/widgets/echart/types.d.ts +4 -0
- package/dist/widgets/echart.js +96 -85
- package/dist/widgets/echart.js.map +1 -1
- package/package.json +1 -1
- package/src/widgets/echart/echart-ui.test.tsx +18 -0
- package/src/widgets/echart/echart-ui.tsx +25 -13
- package/src/widgets/echart/echart.test.tsx +25 -0
- package/src/widgets/echart/echart.tsx +9 -1
- package/src/widgets/echart/types.ts +4 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { EchartUIProps } from './types';
|
|
2
|
-
export declare function EchartUI(
|
|
2
|
+
export declare function EchartUI(props: EchartUIProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,11 +4,13 @@ import { Ref } from 'react';
|
|
|
4
4
|
import { theme as CartoTheme } from '@carto/meridian-ds/theme';
|
|
5
5
|
import type * as echarts from 'echarts';
|
|
6
6
|
export type EchartOptionsProps = EChartsOption;
|
|
7
|
+
export type EchartReplaceMerge = string[];
|
|
7
8
|
export interface EchartUIProps {
|
|
8
9
|
id: string;
|
|
9
10
|
option: EchartOptionsProps;
|
|
10
11
|
className?: string;
|
|
11
12
|
init?: echarts.EChartsInitOpts;
|
|
13
|
+
replaceMerge?: EchartReplaceMerge;
|
|
12
14
|
style?: React.CSSProperties;
|
|
13
15
|
ref?: Ref<echarts.ECharts>;
|
|
14
16
|
onEvents?: Record<string, Parameters<echarts.ECharts['on']>[2]>;
|
|
@@ -21,6 +23,7 @@ export type EchartWidgetState = BaseWidgetState<{
|
|
|
21
23
|
option: EchartUIProps['option'];
|
|
22
24
|
onEvents?: EchartUIProps['onEvents'];
|
|
23
25
|
init?: EchartUIProps['init'];
|
|
26
|
+
replaceMerge?: EchartReplaceMerge;
|
|
24
27
|
}>;
|
|
25
28
|
export interface EchartWidgetOptionProps<D> {
|
|
26
29
|
data?: D;
|
|
@@ -31,4 +34,5 @@ export interface EchartWidgetProps {
|
|
|
31
34
|
type: string;
|
|
32
35
|
option: EchartUIProps['option'];
|
|
33
36
|
onEvents?: EchartUIProps['onEvents'];
|
|
37
|
+
replaceMerge?: EchartReplaceMerge;
|
|
34
38
|
}
|
package/dist/widgets/echart.js
CHANGED
|
@@ -1,115 +1,126 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { c as
|
|
3
|
-
import { useRef as
|
|
1
|
+
import { jsx as W } from "react/jsx-runtime";
|
|
2
|
+
import { c as j } from "react/compiler-runtime";
|
|
3
|
+
import { useRef as A, useImperativeHandle as U, useEffect as S } from "react";
|
|
4
4
|
import * as k from "echarts";
|
|
5
|
-
import { u as
|
|
6
|
-
import { u as
|
|
7
|
-
import { useShallow as
|
|
8
|
-
import { g as
|
|
9
|
-
import { g as
|
|
5
|
+
import { u as D } from "../use-widget-ref-B0aNCANx.js";
|
|
6
|
+
import { u as L } from "../widget-store-CB6Trp_0.js";
|
|
7
|
+
import { useShallow as Z } from "zustand/shallow";
|
|
8
|
+
import { g as X } from "../options-D9wflre6.js";
|
|
9
|
+
import { g as ee, a as te, b as re, m as ne } from "../utils-D3-eQyDR.js";
|
|
10
|
+
const $ = ["dataset", "series"];
|
|
10
11
|
function B(r) {
|
|
11
|
-
const
|
|
12
|
+
const e = j(23), {
|
|
12
13
|
id: c,
|
|
13
|
-
ref:
|
|
14
|
+
ref: n,
|
|
14
15
|
init: l,
|
|
15
|
-
option:
|
|
16
|
-
className:
|
|
17
|
-
style:
|
|
18
|
-
onEvents:
|
|
19
|
-
} = r,
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
option: a,
|
|
17
|
+
className: s,
|
|
18
|
+
style: u,
|
|
19
|
+
onEvents: f
|
|
20
|
+
} = r, p = r;
|
|
21
|
+
let d;
|
|
22
|
+
e[0] !== p.replaceMerge ? (d = F(p.replaceMerge), e[0] = p.replaceMerge, e[1] = d) : d = e[1];
|
|
23
|
+
const g = d, t = D(c), i = A(null), o = A(null);
|
|
24
|
+
let E, h;
|
|
25
|
+
e[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (E = () => i.current, h = [], e[2] = E, e[3] = h) : (E = e[2], h = e[3]), U(n, E, h);
|
|
26
|
+
let v, C;
|
|
27
|
+
e[4] !== t || e[5] !== l ? (v = () => {
|
|
28
|
+
if (t.current)
|
|
29
|
+
return i.current = k.init(t.current, null, {
|
|
26
30
|
renderer: "svg",
|
|
27
31
|
height: 304,
|
|
28
32
|
...l
|
|
29
33
|
}), () => {
|
|
30
|
-
|
|
34
|
+
i.current?.dispose(), i.current = null;
|
|
31
35
|
};
|
|
32
|
-
},
|
|
33
|
-
let
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
lazyUpdate: !0
|
|
37
|
-
|
|
38
|
-
}, p = [u], t[6] = u, t[7] = E, t[8] = p) : (E = t[7], p = t[8]), S(E, p);
|
|
39
|
-
let C, b;
|
|
40
|
-
t[9] !== e ? (C = () => {
|
|
41
|
-
const g = () => {
|
|
42
|
-
n.current?.resize();
|
|
36
|
+
}, C = [t, l], e[4] = t, e[5] = l, e[6] = v, e[7] = C) : (v = e[6], C = e[7]), S(v, C);
|
|
37
|
+
let M, R;
|
|
38
|
+
e[8] !== a || e[9] !== g ? (M = () => {
|
|
39
|
+
const m = {
|
|
40
|
+
lazyUpdate: !0,
|
|
41
|
+
replaceMerge: g ?? $
|
|
43
42
|
};
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
i.current?.setOption(a, m);
|
|
44
|
+
}, R = [a, g], e[8] = a, e[9] = g, e[10] = M, e[11] = R) : (M = e[10], R = e[11]), S(M, R);
|
|
45
|
+
let b, y;
|
|
46
|
+
e[12] !== t ? (b = () => {
|
|
47
|
+
const m = () => {
|
|
48
|
+
i.current?.resize();
|
|
46
49
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
t[12] !== d ? (R = () => {
|
|
50
|
-
const g = {
|
|
51
|
-
...d ?? {}
|
|
50
|
+
return o.current = new ResizeObserver(m), o.current.observe(t.current), () => {
|
|
51
|
+
o.current?.disconnect(), o.current = null;
|
|
52
52
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
}, y = [t], e[12] = t, e[13] = b, e[14] = y) : (b = e[13], y = e[14]), S(b, y);
|
|
54
|
+
let O, _;
|
|
55
|
+
e[15] !== f ? (O = () => {
|
|
56
|
+
const m = {
|
|
57
|
+
...f ?? {}
|
|
58
|
+
};
|
|
59
|
+
return m.click || (m.mousemove = () => {
|
|
60
|
+
i.current?.getZr().setCursorStyle("default");
|
|
61
|
+
}), Object.entries(m).forEach((w) => {
|
|
62
|
+
const [x, I] = w;
|
|
63
|
+
i.current?.on(x, I);
|
|
58
64
|
}), () => {
|
|
59
|
-
Object.entries(
|
|
60
|
-
const [
|
|
61
|
-
|
|
65
|
+
Object.entries(m).forEach((w) => {
|
|
66
|
+
const [x] = w;
|
|
67
|
+
i.current?.off(x);
|
|
62
68
|
});
|
|
63
69
|
};
|
|
64
|
-
},
|
|
70
|
+
}, _ = [f], e[15] = f, e[16] = O, e[17] = _) : (O = e[16], _ = e[17]), S(O, _);
|
|
65
71
|
let z;
|
|
66
|
-
return
|
|
72
|
+
return e[18] !== t || e[19] !== s || e[20] !== c || e[21] !== u ? (z = /* @__PURE__ */ W("div", { id: c, ref: t, style: u, className: s }), e[18] = t, e[19] = s, e[20] = c, e[21] = u, e[22] = z) : z = e[22], z;
|
|
73
|
+
}
|
|
74
|
+
function F(r) {
|
|
75
|
+
if (Array.isArray(r))
|
|
76
|
+
return r.filter((e) => typeof e == "string");
|
|
67
77
|
}
|
|
68
|
-
function
|
|
69
|
-
const
|
|
78
|
+
function K(r) {
|
|
79
|
+
const e = j(15);
|
|
70
80
|
let c;
|
|
71
|
-
|
|
72
|
-
const
|
|
81
|
+
e[0] !== r.id ? (c = (i) => {
|
|
82
|
+
const o = i.getWidget(r.id);
|
|
73
83
|
return {
|
|
74
|
-
id:
|
|
75
|
-
data:
|
|
76
|
-
option:
|
|
77
|
-
onEvents:
|
|
78
|
-
init:
|
|
84
|
+
id: o?.id,
|
|
85
|
+
data: o?.data,
|
|
86
|
+
option: o?.option,
|
|
87
|
+
onEvents: o?.onEvents,
|
|
88
|
+
init: o?.init,
|
|
89
|
+
replaceMerge: o?.replaceMerge
|
|
79
90
|
};
|
|
80
|
-
},
|
|
81
|
-
const
|
|
91
|
+
}, e[0] = r.id, e[1] = c) : c = e[1];
|
|
92
|
+
const n = L(Z(c));
|
|
82
93
|
let l;
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
if (!
|
|
94
|
+
e[2] !== n.data ? (l = G(n.data), e[2] = n.data, e[3] = l) : l = e[3];
|
|
95
|
+
const a = l;
|
|
96
|
+
if (!n.id)
|
|
86
97
|
return null;
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
dataset:
|
|
90
|
-
},
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
...
|
|
94
|
-
...
|
|
95
|
-
},
|
|
96
|
-
const
|
|
97
|
-
let
|
|
98
|
-
return
|
|
98
|
+
let s;
|
|
99
|
+
e[4] !== a ? (s = a && {
|
|
100
|
+
dataset: a
|
|
101
|
+
}, e[4] = a, e[5] = s) : s = e[5];
|
|
102
|
+
let u;
|
|
103
|
+
e[6] !== s || e[7] !== n.option ? (u = {
|
|
104
|
+
...n.option,
|
|
105
|
+
...s
|
|
106
|
+
}, e[6] = s, e[7] = n.option, e[8] = u) : u = e[8];
|
|
107
|
+
const f = u, p = n.onEvents, d = n.init, g = n.replaceMerge;
|
|
108
|
+
let t;
|
|
109
|
+
return e[9] !== d || e[10] !== p || e[11] !== f || e[12] !== r.id || e[13] !== g ? (t = /* @__PURE__ */ W(B, { id: r.id, option: f, onEvents: p, init: d, replaceMerge: g }), e[9] = d, e[10] = p, e[11] = f, e[12] = r.id, e[13] = g, e[14] = t) : t = e[14], t;
|
|
99
110
|
}
|
|
100
|
-
function
|
|
111
|
+
function G(r) {
|
|
101
112
|
if (!(!r || r.length === 0))
|
|
102
|
-
return r.map((
|
|
103
|
-
source:
|
|
113
|
+
return r.map((e) => ({
|
|
114
|
+
source: e
|
|
104
115
|
}));
|
|
105
116
|
}
|
|
106
117
|
export {
|
|
107
|
-
|
|
118
|
+
K as Echart,
|
|
108
119
|
B as EchartUI,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
X as getCommonOptions,
|
|
121
|
+
ee as getEChartBrushConfig,
|
|
122
|
+
te as getEChartStackConfig,
|
|
123
|
+
re as getEChartZoomConfig,
|
|
124
|
+
ne as mergeEchartWidgetConfig
|
|
114
125
|
};
|
|
115
126
|
//# sourceMappingURL=echart.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"echart.js","sources":["../../src/widgets/echart/echart-ui.tsx","../../src/widgets/echart/echart.tsx"],"sourcesContent":["import { useEffect, useRef, useImperativeHandle } from 'react'\nimport * as echarts from 'echarts'\nimport type { EchartUIProps } from './types'\nimport { useWidgetRef } from '../../hooks'\n\nexport function EchartUI({\n id
|
|
1
|
+
{"version":3,"file":"echart.js","sources":["../../src/widgets/echart/echart-ui.tsx","../../src/widgets/echart/echart.tsx"],"sourcesContent":["import { useEffect, useRef, useImperativeHandle } from 'react'\nimport * as echarts from 'echarts'\nimport type { EchartUIProps } from './types'\nimport { useWidgetRef } from '../../hooks'\n\nconst DEFAULT_REPLACE_MERGE: string[] = ['dataset', 'series']\n\nexport function EchartUI(props: EchartUIProps) {\n const { id, ref, init, option, className, style, onEvents } = props\n const replaceMerge = toReplaceMerge(\n (props as { replaceMerge?: unknown }).replaceMerge,\n )\n\n const chartRef = useWidgetRef<HTMLDivElement>(id)\n const chartInstance = useRef<echarts.ECharts>(null)\n const resizeObserverRef = useRef<ResizeObserver | null>(null)\n\n useImperativeHandle(ref, () => chartInstance.current!, [])\n\n useEffect(() => {\n if (!chartRef.current) return\n\n chartInstance.current = echarts.init(chartRef.current, null, {\n renderer: 'svg',\n height: 304,\n ...init,\n })\n // Cleanup function\n return () => {\n chartInstance.current?.dispose()\n chartInstance.current = null\n }\n }, [chartRef, init])\n\n // Update chart when options change\n useEffect(() => {\n const setOptionConfig = {\n lazyUpdate: true,\n replaceMerge: replaceMerge ?? DEFAULT_REPLACE_MERGE,\n }\n\n chartInstance.current?.setOption(\n option,\n setOptionConfig as Parameters<echarts.ECharts['setOption']>[1],\n )\n }, [option, replaceMerge])\n\n // Handle resize using ResizeObserver\n useEffect(() => {\n const handleResize = () => {\n chartInstance.current?.resize()\n }\n\n resizeObserverRef.current = new ResizeObserver(handleResize)\n resizeObserverRef.current.observe(chartRef.current!)\n\n return () => {\n resizeObserverRef.current?.disconnect()\n resizeObserverRef.current = null\n }\n }, [chartRef])\n\n useEffect(() => {\n const _onEvents = { ...(onEvents ?? {}) }\n if (!_onEvents.click) {\n _onEvents.mousemove = () => {\n chartInstance.current?.getZr().setCursorStyle('default')\n }\n }\n\n // Attach event listeners\n Object.entries(_onEvents).forEach(([event, handler]) => {\n chartInstance.current?.on(event, handler)\n })\n // Cleanup function to remove event listeners\n return () => {\n Object.entries(_onEvents).forEach(([event]) => {\n chartInstance.current?.off(event)\n })\n }\n }, [onEvents])\n\n return <div id={id} ref={chartRef} style={style} className={className} />\n}\n\nfunction toReplaceMerge(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) {\n return undefined\n }\n\n return value.filter((item): item is string => typeof item === 'string')\n}\n","import type {\n EchartProps,\n EchartWidgetState,\n EchartWidgetData,\n EchartOptionsProps,\n} from './types'\nimport { EchartUI } from './echart-ui'\nimport { useWidgetStore } from '../stores/widget-store'\nimport { useShallow } from 'zustand/shallow'\nimport { useMemo } from 'react'\n\nexport function Echart(props: EchartProps) {\n const widget = useWidgetStore(\n useShallow((state) => {\n const widget = state.getWidget<EchartWidgetState>(props.id)\n return {\n id: widget?.id,\n data: widget?.data as EchartWidgetData | undefined,\n option: widget?.option,\n onEvents: widget?.onEvents,\n init: widget?.init,\n replaceMerge: widget?.replaceMerge,\n }\n }),\n )\n\n // Memoize dataset transformation to avoid re-computing on every render\n const dataset = useMemo(() => buildDataset(widget.data), [widget.data])\n\n if (!widget.id) {\n return null\n }\n const option: EchartOptionsProps = {\n ...widget.option,\n ...(dataset && { dataset }),\n }\n\n const onEvents = widget.onEvents\n const init = widget.init\n const replaceMerge = widget.replaceMerge\n\n return (\n <EchartUI\n id={props.id}\n option={option}\n onEvents={onEvents}\n init={init}\n replaceMerge={replaceMerge}\n />\n )\n}\n\n/**\n * Builds the dataset configuration from widget data\n * @param data - The widget data array\n * @returns The dataset configuration for ECharts\n */\nfunction buildDataset(\n data: EchartWidgetData | undefined,\n): EchartOptionsProps['dataset'] {\n if (!data || data.length === 0) {\n return undefined\n }\n\n return data.map((d) => ({\n source: d,\n }))\n}\n"],"names":["DEFAULT_REPLACE_MERGE","EchartUI","props","$","_c","id","ref","init","option","className","style","onEvents","t0","t1","replaceMerge","toReplaceMerge","chartRef","useWidgetRef","chartInstance","useRef","resizeObserverRef","t2","t3","Symbol","for","current","useImperativeHandle","t4","t5","echarts","renderer","height","dispose","useEffect","t6","t7","setOptionConfig","lazyUpdate","setOption","t8","t9","handleResize","resize","ResizeObserver","observe","disconnect","t10","t11","_onEvents","click","mousemove","getZr","setCursorStyle","Object","entries","forEach","t12","event","handler","on","t13","event_0","off","value","Array","isArray","filter","item","Echart","state","widget","getWidget","data","widget_0","useWidgetStore","useShallow","buildDataset","dataset","jsx","length","map","d","source"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -175,6 +175,7 @@ describe('EchartUI', () => {
|
|
|
175
175
|
|
|
176
176
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
177
177
|
lazyUpdate: true,
|
|
178
|
+
replaceMerge: ['dataset', 'series'],
|
|
178
179
|
})
|
|
179
180
|
})
|
|
180
181
|
|
|
@@ -199,6 +200,22 @@ describe('EchartUI', () => {
|
|
|
199
200
|
|
|
200
201
|
expect(mockChart.setOption).toHaveBeenCalledWith(newOption, {
|
|
201
202
|
lazyUpdate: true,
|
|
203
|
+
replaceMerge: ['dataset', 'series'],
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('uses provided replaceMerge values', () => {
|
|
208
|
+
render(
|
|
209
|
+
<EchartUI
|
|
210
|
+
{...defaultProps}
|
|
211
|
+
option={basicOption}
|
|
212
|
+
replaceMerge={['series']}
|
|
213
|
+
/>,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
217
|
+
lazyUpdate: true,
|
|
218
|
+
replaceMerge: ['series'],
|
|
202
219
|
})
|
|
203
220
|
})
|
|
204
221
|
|
|
@@ -479,6 +496,7 @@ describe('EchartUI', () => {
|
|
|
479
496
|
|
|
480
497
|
expect(mockChart.setOption).toHaveBeenCalledWith(complexOption, {
|
|
481
498
|
lazyUpdate: true,
|
|
499
|
+
replaceMerge: ['dataset', 'series'],
|
|
482
500
|
})
|
|
483
501
|
})
|
|
484
502
|
|
|
@@ -3,15 +3,14 @@ import * as echarts from 'echarts'
|
|
|
3
3
|
import type { EchartUIProps } from './types'
|
|
4
4
|
import { useWidgetRef } from '../../hooks'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
init,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}: EchartUIProps) {
|
|
6
|
+
const DEFAULT_REPLACE_MERGE: string[] = ['dataset', 'series']
|
|
7
|
+
|
|
8
|
+
export function EchartUI(props: EchartUIProps) {
|
|
9
|
+
const { id, ref, init, option, className, style, onEvents } = props
|
|
10
|
+
const replaceMerge = toReplaceMerge(
|
|
11
|
+
(props as { replaceMerge?: unknown }).replaceMerge,
|
|
12
|
+
)
|
|
13
|
+
|
|
15
14
|
const chartRef = useWidgetRef<HTMLDivElement>(id)
|
|
16
15
|
const chartInstance = useRef<echarts.ECharts>(null)
|
|
17
16
|
const resizeObserverRef = useRef<ResizeObserver | null>(null)
|
|
@@ -35,11 +34,16 @@ export function EchartUI({
|
|
|
35
34
|
|
|
36
35
|
// Update chart when options change
|
|
37
36
|
useEffect(() => {
|
|
38
|
-
|
|
37
|
+
const setOptionConfig = {
|
|
39
38
|
lazyUpdate: true,
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
39
|
+
replaceMerge: replaceMerge ?? DEFAULT_REPLACE_MERGE,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
chartInstance.current?.setOption(
|
|
43
|
+
option,
|
|
44
|
+
setOptionConfig as Parameters<echarts.ECharts['setOption']>[1],
|
|
45
|
+
)
|
|
46
|
+
}, [option, replaceMerge])
|
|
43
47
|
|
|
44
48
|
// Handle resize using ResizeObserver
|
|
45
49
|
useEffect(() => {
|
|
@@ -78,3 +82,11 @@ export function EchartUI({
|
|
|
78
82
|
|
|
79
83
|
return <div id={id} ref={chartRef} style={style} className={className} />
|
|
80
84
|
}
|
|
85
|
+
|
|
86
|
+
function toReplaceMerge(value: unknown): string[] | undefined {
|
|
87
|
+
if (!Array.isArray(value)) {
|
|
88
|
+
return undefined
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return value.filter((item): item is string => typeof item === 'string')
|
|
92
|
+
}
|
|
@@ -184,6 +184,7 @@ describe('Echart', () => {
|
|
|
184
184
|
}),
|
|
185
185
|
{
|
|
186
186
|
lazyUpdate: true,
|
|
187
|
+
replaceMerge: ['dataset', 'series'],
|
|
187
188
|
},
|
|
188
189
|
)
|
|
189
190
|
})
|
|
@@ -276,6 +277,7 @@ describe('Echart', () => {
|
|
|
276
277
|
|
|
277
278
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
278
279
|
lazyUpdate: true,
|
|
280
|
+
replaceMerge: ['dataset', 'series'],
|
|
279
281
|
})
|
|
280
282
|
|
|
281
283
|
const newOption: EChartsOption = {
|
|
@@ -297,6 +299,7 @@ describe('Echart', () => {
|
|
|
297
299
|
|
|
298
300
|
expect(mockChart.setOption).toHaveBeenCalledWith(newOption, {
|
|
299
301
|
lazyUpdate: true,
|
|
302
|
+
replaceMerge: ['dataset', 'series'],
|
|
300
303
|
})
|
|
301
304
|
})
|
|
302
305
|
|
|
@@ -364,6 +367,7 @@ describe('Echart', () => {
|
|
|
364
367
|
|
|
365
368
|
expect(mockChart.setOption).toHaveBeenCalledWith(complexOption, {
|
|
366
369
|
lazyUpdate: true,
|
|
370
|
+
replaceMerge: ['dataset', 'series'],
|
|
367
371
|
})
|
|
368
372
|
})
|
|
369
373
|
|
|
@@ -400,6 +404,7 @@ describe('Echart', () => {
|
|
|
400
404
|
)
|
|
401
405
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
402
406
|
lazyUpdate: true,
|
|
407
|
+
replaceMerge: ['dataset', 'series'],
|
|
403
408
|
})
|
|
404
409
|
expect(mockChart.on).toHaveBeenCalledWith('click', clickHandler)
|
|
405
410
|
})
|
|
@@ -442,6 +447,7 @@ describe('Echart', () => {
|
|
|
442
447
|
|
|
443
448
|
expect(mockChart.setOption).toHaveBeenCalledWith(emptyOption, {
|
|
444
449
|
lazyUpdate: true,
|
|
450
|
+
replaceMerge: ['dataset', 'series'],
|
|
445
451
|
})
|
|
446
452
|
})
|
|
447
453
|
|
|
@@ -464,6 +470,7 @@ describe('Echart', () => {
|
|
|
464
470
|
}),
|
|
465
471
|
{
|
|
466
472
|
lazyUpdate: true,
|
|
473
|
+
replaceMerge: ['dataset', 'series'],
|
|
467
474
|
},
|
|
468
475
|
)
|
|
469
476
|
})
|
|
@@ -509,6 +516,7 @@ describe('Echart', () => {
|
|
|
509
516
|
|
|
510
517
|
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
511
518
|
lazyUpdate: true,
|
|
519
|
+
replaceMerge: ['dataset', 'series'],
|
|
512
520
|
})
|
|
513
521
|
|
|
514
522
|
rerender(<Echart id='chart-b' />)
|
|
@@ -517,10 +525,27 @@ describe('Echart', () => {
|
|
|
517
525
|
{ series: [{ type: 'line', data: [1, 2, 3] }] },
|
|
518
526
|
{
|
|
519
527
|
lazyUpdate: true,
|
|
528
|
+
replaceMerge: ['dataset', 'series'],
|
|
520
529
|
},
|
|
521
530
|
)
|
|
522
531
|
})
|
|
523
532
|
|
|
533
|
+
test('passes replaceMerge from widget to EchartUI', () => {
|
|
534
|
+
useWidgetStore.getState().setWidget('test-echart', {
|
|
535
|
+
id: 'test-echart',
|
|
536
|
+
type: 'echart',
|
|
537
|
+
option: basicOption,
|
|
538
|
+
replaceMerge: ['series'],
|
|
539
|
+
} as EchartWidgetState)
|
|
540
|
+
|
|
541
|
+
render(<Echart id='test-echart' />)
|
|
542
|
+
|
|
543
|
+
expect(mockChart.setOption).toHaveBeenCalledWith(basicOption, {
|
|
544
|
+
lazyUpdate: true,
|
|
545
|
+
replaceMerge: ['series'],
|
|
546
|
+
})
|
|
547
|
+
})
|
|
548
|
+
|
|
524
549
|
test('disposes chart when component unmounts', () => {
|
|
525
550
|
useWidgetStore.getState().setWidget('test-echart', {
|
|
526
551
|
id: 'test-echart',
|
|
@@ -19,6 +19,7 @@ export function Echart(props: EchartProps) {
|
|
|
19
19
|
option: widget?.option,
|
|
20
20
|
onEvents: widget?.onEvents,
|
|
21
21
|
init: widget?.init,
|
|
22
|
+
replaceMerge: widget?.replaceMerge,
|
|
22
23
|
}
|
|
23
24
|
}),
|
|
24
25
|
)
|
|
@@ -36,9 +37,16 @@ export function Echart(props: EchartProps) {
|
|
|
36
37
|
|
|
37
38
|
const onEvents = widget.onEvents
|
|
38
39
|
const init = widget.init
|
|
40
|
+
const replaceMerge = widget.replaceMerge
|
|
39
41
|
|
|
40
42
|
return (
|
|
41
|
-
<EchartUI
|
|
43
|
+
<EchartUI
|
|
44
|
+
id={props.id}
|
|
45
|
+
option={option}
|
|
46
|
+
onEvents={onEvents}
|
|
47
|
+
init={init}
|
|
48
|
+
replaceMerge={replaceMerge}
|
|
49
|
+
/>
|
|
42
50
|
)
|
|
43
51
|
}
|
|
44
52
|
|
|
@@ -5,12 +5,14 @@ import type { Ref } from 'react'
|
|
|
5
5
|
import { theme as CartoTheme } from '@carto/meridian-ds/theme'
|
|
6
6
|
|
|
7
7
|
export type EchartOptionsProps = EChartsOption
|
|
8
|
+
export type EchartReplaceMerge = string[]
|
|
8
9
|
|
|
9
10
|
export interface EchartUIProps {
|
|
10
11
|
id: string
|
|
11
12
|
option: EchartOptionsProps
|
|
12
13
|
className?: string
|
|
13
14
|
init?: echarts.EChartsInitOpts
|
|
15
|
+
replaceMerge?: EchartReplaceMerge
|
|
14
16
|
style?: React.CSSProperties
|
|
15
17
|
ref?: Ref<echarts.ECharts>
|
|
16
18
|
onEvents?: Record<string, Parameters<echarts.ECharts['on']>[2]>
|
|
@@ -26,6 +28,7 @@ export type EchartWidgetState = BaseWidgetState<{
|
|
|
26
28
|
option: EchartUIProps['option']
|
|
27
29
|
onEvents?: EchartUIProps['onEvents']
|
|
28
30
|
init?: EchartUIProps['init']
|
|
31
|
+
replaceMerge?: EchartReplaceMerge
|
|
29
32
|
}>
|
|
30
33
|
|
|
31
34
|
export interface EchartWidgetOptionProps<D> {
|
|
@@ -38,4 +41,5 @@ export interface EchartWidgetProps {
|
|
|
38
41
|
type: string
|
|
39
42
|
option: EchartUIProps['option']
|
|
40
43
|
onEvents?: EchartUIProps['onEvents']
|
|
44
|
+
replaceMerge?: EchartReplaceMerge
|
|
41
45
|
}
|