@czi-sds/data-viz 0.4.2 → 0.6.0

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.
@@ -1,7 +1,12 @@
1
1
  /// <reference types="react" />
2
- import { ECharts, ElementEvent, DatasetComponentOption, EChartsOption, ScatterSeriesOption } from "echarts";
3
2
  import { HTMLAttributes } from "react";
3
+ import { DatasetComponentOption, ECharts, EChartsOption, ScatterSeriesOption } from "echarts";
4
4
  interface CreateChartOptionsProps {
5
+ /**
6
+ * Display reference line and axis value under mouse pointer
7
+ * https://echarts.apache.org/en/option.html#axisPointer
8
+ */
9
+ axisPointer?: EChartsOption["axisPointer"];
5
10
  /**
6
11
  * The data array to be visualized
7
12
  * The data point object shape can be whatever you like, but it must be consistent with the `encode` option
@@ -18,6 +23,44 @@ interface CreateChartOptionsProps {
18
23
  * }
19
24
  */
20
25
  data: DatasetComponentOption["source"];
26
+ /**
27
+ * The `dataZoom` prop is utilized for implementing zoom functionality within a
28
+ * specific area of the chart. This feature empowers users to inspect data in
29
+ * granular detail, obtain an overview of the entire dataset, or eliminate
30
+ * outlier points.
31
+ * By applying the `dataZoom` prop while locking the zoom level, the chart
32
+ * efficiently renders a confined portion of the heatmap. This selective
33
+ * rendering strategy becomes especially advantageous when dealing with
34
+ * extensive datasets. Instead of rendering the entire heatmap at once,
35
+ * the chart dynamically loads and renders specific segments as the user
36
+ * scrolls through the data. This approach optimizes performance and enables
37
+ * the creation of heatmaps with large amounts of data.
38
+ * https://echarts.apache.org/en/option.html#dataZoom
39
+ */
40
+ dataZoom?: EChartsOption["dataZoom"];
41
+ /**
42
+ * The `camera` prop is utilized for implementing camera view port functionality
43
+ * within a specific area of the chart. This feature empowers users to render
44
+ * a confined portion of the heatmap. This selective rendering strategy becomes
45
+ * especially advantageous when dealing with extensive datasets. Instead of
46
+ * rendering the entire heatmap at once, the chart dynamically loads and renders
47
+ * specific segments as the user scrolls through the data. This approach optimizes
48
+ * performance and enables the creation of heatmaps with large amounts of data.
49
+ *
50
+ * The `height` and `width` properties are used to specify the dimensions of the
51
+ * camera view port. The `active` property is used to enable or disable the camera
52
+ * view port functionality.
53
+ */
54
+ camera?: {
55
+ active: boolean;
56
+ height: number;
57
+ width: number;
58
+ };
59
+ /**
60
+ * Customize the style of each cell item when mouse hovers on it, such as color, border, opacity, etc.
61
+ * https://echarts.apache.org/en/option.html#series-scatter.emphasis
62
+ */
63
+ emphasis?: ScatterSeriesOption["emphasis"];
21
64
  /**
22
65
  * The data for the x axis
23
66
  * For example:
@@ -30,7 +73,13 @@ interface CreateChartOptionsProps {
30
73
  * [{ value: "cellType1", textStyle: { color: "red" } }, "cellType2", "cellType3"]
31
74
  */
32
75
  yAxisData: CategoryAxisData;
76
+ /**
77
+ * The width of the chart in pixels
78
+ */
33
79
  width: number;
80
+ /**
81
+ * The height of the chart in pixels
82
+ */
34
83
  height: number;
35
84
  /**
36
85
  * Provide a mapping of data key to x/y axis encoding
@@ -56,6 +105,10 @@ interface CreateChartOptionsProps {
56
105
  * https://echarts.apache.org/en/option.html#series-scatter.itemStyle
57
106
  */
58
107
  itemStyle?: ScatterSeriesOption["itemStyle"];
108
+ /**
109
+ * The shape of the symbol.
110
+ */
111
+ symbol?: "circle" | "rect" | "roundRect";
59
112
  /**
60
113
  * `symbolSize` can be set to single numbers like 10, or use an array to represent width and height. For example, [20, 10] means symbol width is 20, and height is 10.
61
114
  *
@@ -71,6 +124,16 @@ interface CreateChartOptionsProps {
71
124
  * https://echarts.apache.org/en/option.html#grid
72
125
  */
73
126
  grid?: EChartsOption["grid"] | ((defaultOption: EChartsOption["grid"]) => EChartsOption["grid"]);
127
+ /**
128
+ * The options object to be passed to echarts.setOption()
129
+ * https://echarts.apache.org/en/option.html
130
+ */
131
+ options?: EChartsOption;
132
+ /**
133
+ * Event listeners for the chart
134
+ * https://echarts.apache.org/en/api.html#events
135
+ */
136
+ onEvents?: Record<string, (event: unknown, chart: ECharts) => void>;
74
137
  }
75
138
  type OrdinalRawValue = string | number;
76
139
  /**
@@ -85,7 +148,6 @@ type CategoryAxisData = (OrdinalRawValue | {
85
148
  })[];
86
149
  interface HeatmapChartProps extends HTMLAttributes<HTMLDivElement>, CreateChartOptionsProps {
87
150
  echartsRendererMode?: "svg" | "canvas";
88
- onChartMouseMove?: (event: ElementEvent, chart: ECharts) => void;
89
151
  }
90
152
  declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<HeatmapChartProps & import("react").RefAttributes<HTMLDivElement>>>;
91
153
  export { HeatmapChartProps, _default, _default as HeatmapChart };
package/dist/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { init } from 'echarts';
3
- import { useMemo, useEffect, memo, forwardRef, useState, useRef } from 'react';
3
+ import { useMemo, useEffect, forwardRef, useRef, useState, useCallback, memo } from 'react';
4
4
  import { throttle } from 'lodash';
5
5
  import { styled } from '@mui/material/styles';
6
6
 
@@ -60,8 +60,70 @@ var DEFAULT_ITEM_STYLE = {
60
60
  return "rgb(0, 0, 0)";
61
61
  },
62
62
  };
63
- function createChartOptions(_a) {
64
- var data = _a.data, xAxisData = _a.xAxisData, yAxisData = _a.yAxisData, width = _a.width, height = _a.height, encode = _a.encode, _b = _a.itemStyle, itemStyle = _b === void 0 ? DEFAULT_ITEM_STYLE : _b, symbolSize = _a.symbolSize, gridProp = _a.grid;
63
+ function createChartOptions(props) {
64
+ var axisPointer = props.axisPointer, camera = props.camera, data = props.data, dataZoom = props.dataZoom, emphasis = props.emphasis, encode = props.encode, gridProp = props.grid, _a = props.itemStyle, itemStyle = _a === void 0 ? DEFAULT_ITEM_STYLE : _a, options = props.options, symbolSize = props.symbolSize, _b = props.symbol, symbol = _b === void 0 ? "rect" : _b;
65
+ var _c = generateDefaultValues(props), defaultAxisPointer = _c.defaultAxisPointer, defaultDataZoom = _c.defaultDataZoom, defaultEmphasis = _c.defaultEmphasis, defaultGrid = _c.defaultGrid, defaultXAxis = _c.defaultXAxis, defaultYAxis = _c.defaultYAxis;
66
+ var customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp;
67
+ var _d = options || {}, optionsAxisPointer = _d.axisPointer, optionsDataZoom = _d.dataZoom, optionsSeries = _d.series, optionsXAxis = _d.xAxis, optionsYAxis = _d.yAxis, optionsRest = __rest(_d, ["axisPointer", "dataZoom", "series", "xAxis", "yAxis"]);
68
+ return __assign({ animation: false, axisPointer: mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer), dataZoom: (camera === null || camera === void 0 ? void 0 : camera.active)
69
+ ? mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom)
70
+ : [], dataset: {
71
+ source: data,
72
+ }, grid: customGrid || defaultGrid, series: [
73
+ Object.assign({
74
+ emphasis: Object.assign(defaultEmphasis, emphasis),
75
+ encode: encode,
76
+ itemStyle: itemStyle,
77
+ legendHoverLink: false,
78
+ symbol: symbol,
79
+ symbolSize: symbolSize,
80
+ }, optionsSeries
81
+ ? Array.isArray(optionsSeries)
82
+ ? optionsSeries[0]
83
+ : optionsSeries
84
+ : [], { symbol: symbol, type: "scatter" }),
85
+ ], xAxis: [
86
+ Object.assign(defaultXAxis, optionsXAxis
87
+ ? Array.isArray(optionsXAxis)
88
+ ? optionsXAxis[0]
89
+ : optionsXAxis
90
+ : {}),
91
+ ], yAxis: [
92
+ Object.assign(defaultYAxis, optionsYAxis
93
+ ? Array.isArray(optionsYAxis)
94
+ ? optionsYAxis[0]
95
+ : optionsYAxis
96
+ : {}),
97
+ ] }, optionsRest);
98
+ }
99
+ function mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer) {
100
+ var finalAxisPointer = Array.isArray(axisPointer)
101
+ ? axisPointer // if it's an array, assume that the user has [{...propsToChangeOnX}] OR [ , {...propsToChangeOnY}] OR [{...propsToChangeOnX}, {...propsToChangeOnY}]
102
+ : [axisPointer, axisPointer]; // else if the user only supplies one AxisPointer object, we assume they want the props to apply to both x and y axisPointer objects
103
+ var finalOptionsAxisPointer = Array.isArray(optionsAxisPointer)
104
+ ? optionsAxisPointer
105
+ : [optionsAxisPointer, optionsAxisPointer];
106
+ // merge x axisPointer options
107
+ var x = __assign(__assign(__assign({}, defaultAxisPointer), finalAxisPointer[0]), finalOptionsAxisPointer === null || finalOptionsAxisPointer === void 0 ? void 0 : finalOptionsAxisPointer[0]);
108
+ // merge y axisPointer options
109
+ var y = __assign(__assign(__assign({}, defaultAxisPointer), finalAxisPointer[1]), finalOptionsAxisPointer[1]);
110
+ return [x, y];
111
+ }
112
+ function mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) {
113
+ var finalDataZoom = Array.isArray(dataZoom)
114
+ ? dataZoom // if it's an array, assume that the user has [{...propsToChangeOnX}] OR [ , {...propsToChangeOnY}] OR [{...propsToChangeOnX}, {...propsToChangeOnY}]
115
+ : [dataZoom, dataZoom]; // else if the user only supplies one dataZoom object, we assume they want the props to apply to both x and y zoom objects
116
+ var finalOptionsDataZoom = Array.isArray(optionsDataZoom)
117
+ ? optionsDataZoom
118
+ : [optionsDataZoom, optionsDataZoom];
119
+ // merge x dataZoom options
120
+ var x = __assign(__assign(__assign({}, defaultDataZoom[0]), finalDataZoom[0]), finalOptionsDataZoom === null || finalOptionsDataZoom === void 0 ? void 0 : finalOptionsDataZoom[0]);
121
+ // merge y dataZoom options
122
+ var y = __assign(__assign(__assign({}, defaultDataZoom[1]), finalDataZoom[1]), finalOptionsDataZoom[1]);
123
+ return [x, y];
124
+ }
125
+ function generateDefaultValues(props) {
126
+ var camera = props.camera, height = props.height, symbol = props.symbol, width = props.width, xAxisData = props.xAxisData, yAxisData = props.yAxisData;
65
127
  var defaultGrid = {
66
128
  height: "".concat(height, "px"),
67
129
  left: 0,
@@ -70,76 +132,100 @@ function createChartOptions(_a) {
70
132
  // labels to fixed spacings
71
133
  width: "".concat(width, "px"),
72
134
  };
73
- var customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp;
74
- return {
75
- animation: false,
76
- /**
77
- * Display reference line and axis value under mouse pointer
78
- * https://echarts.apache.org/en/option.html#axisPointer
79
- */
80
- axisPointer: {
81
- label: { show: false },
82
- show: true,
83
- triggerOn: "mousemove",
135
+ var defaultAxisPointer = {
136
+ label: { show: false },
137
+ show: false,
138
+ triggerOn: "mousemove",
139
+ };
140
+ var defaultXAxis = {
141
+ axisLabel: { fontSize: 0, rotate: 90 },
142
+ axisLine: {
143
+ show: false,
84
144
  },
85
- dataset: {
86
- source: data,
145
+ axisTick: {
146
+ show: false,
87
147
  },
88
- grid: customGrid || defaultGrid,
89
- series: [
90
- {
91
- emphasis: {
92
- itemStyle: {
93
- color: "inherit",
94
- },
95
- scale: false,
96
- },
97
- encode: encode,
98
- itemStyle: itemStyle,
99
- legendHoverLink: false,
100
- symbolSize: symbolSize,
101
- type: "scatter",
102
- },
103
- ],
104
- xAxis: [
105
- {
106
- axisLabel: { fontSize: 0, rotate: 90 },
107
- axisLine: {
108
- show: false,
109
- },
110
- axisTick: {
111
- show: false,
112
- },
113
- boundaryGap: true,
114
- data: xAxisData,
115
- splitLine: {
116
- show: false,
117
- },
118
- type: "category",
119
- },
120
- ],
121
- yAxis: [
122
- {
123
- axisLabel: { fontSize: 0 },
124
- axisLine: {
125
- show: false,
126
- },
127
- axisTick: {
128
- show: false,
129
- },
130
- boundaryGap: true,
131
- data: yAxisData,
132
- splitLine: {
133
- show: false,
134
- },
135
- },
136
- ],
148
+ boundaryGap: true,
149
+ data: xAxisData,
150
+ splitLine: {
151
+ show: false,
152
+ },
153
+ type: "category",
154
+ };
155
+ var defaultYAxis = {
156
+ axisLabel: { fontSize: 0 },
157
+ axisLine: {
158
+ show: false,
159
+ },
160
+ axisTick: {
161
+ show: false,
162
+ },
163
+ boundaryGap: true,
164
+ data: yAxisData,
165
+ splitLine: {
166
+ show: false,
167
+ },
168
+ };
169
+ var defaultEmphasis = {
170
+ itemStyle: {
171
+ borderColor: symbol === "circle" ? "black" : "white",
172
+ borderType: "solid",
173
+ borderWidth: symbol === "circle" ? 2 : 4,
174
+ opacity: 1,
175
+ },
176
+ scale: false,
177
+ };
178
+ var defaultCamera = {
179
+ height: camera && camera.height ? camera.height : 20,
180
+ width: camera && camera.width ? camera.width : 40,
181
+ };
182
+ var defaultDataZoom = [
183
+ {
184
+ // end index of the x axis window
185
+ endValue: defaultCamera.width - 1,
186
+ filterMode: "filter",
187
+ moveOnMouseMove: true,
188
+ // There's a PR to allow touchpad panning
189
+ // https://github.com/apache/echarts/pull/19352
190
+ moveOnMouseWheel: false,
191
+ orient: "horizontal",
192
+ preventDefaultMouseMove: true,
193
+ // start index of the x axis window
194
+ startValue: 0,
195
+ throttle: 0,
196
+ type: "inside",
197
+ xAxisIndex: 0,
198
+ zoomOnMouseWheel: false,
199
+ },
200
+ {
201
+ // end index of the y axis window
202
+ endValue: defaultCamera.height - 1,
203
+ filterMode: "filter",
204
+ moveOnMouseMove: true,
205
+ moveOnMouseWheel: true,
206
+ orient: "vertical",
207
+ preventDefaultMouseMove: true,
208
+ // start index of the y axis window
209
+ startValue: 0,
210
+ throttle: 0,
211
+ type: "inside",
212
+ yAxisIndex: 0,
213
+ zoomOnMouseWheel: false,
214
+ },
215
+ ];
216
+ return {
217
+ defaultAxisPointer: defaultAxisPointer,
218
+ defaultDataZoom: defaultDataZoom,
219
+ defaultEmphasis: defaultEmphasis,
220
+ defaultGrid: defaultGrid,
221
+ defaultXAxis: defaultXAxis,
222
+ defaultYAxis: defaultYAxis,
137
223
  };
138
224
  }
139
225
 
140
226
  var UPDATE_THROTTLE_MS = 1 * 100;
141
227
  function useUpdateChart(_a) {
142
- var chart = _a.chart, data = _a.data, xAxisData = _a.xAxisData, yAxisData = _a.yAxisData, width = _a.width, height = _a.height, encode = _a.encode, itemStyle = _a.itemStyle, symbolSize = _a.symbolSize, grid = _a.grid;
228
+ var axisPointer = _a.axisPointer, camera = _a.camera, chart = _a.chart, data = _a.data, emphasis = _a.emphasis, xAxisData = _a.xAxisData, yAxisData = _a.yAxisData, width = _a.width, height = _a.height, encode = _a.encode, itemStyle = _a.itemStyle, symbol = _a.symbol, symbolSize = _a.symbolSize, grid = _a.grid, options = _a.options, onEvents = _a.onEvents;
143
229
  var throttledUpdateChart = useMemo(function () {
144
230
  return throttle(function () {
145
231
  if (!chart || !data || !xAxisData || !yAxisData) {
@@ -148,32 +234,67 @@ function useUpdateChart(_a) {
148
234
  // (thuang): resize() needs to be called before setOption() to prevent
149
235
  // TypeError: Cannot read properties of undefined (reading 'shouldBePainted')
150
236
  chart.resize();
151
- chart.setOption(createChartOptions({
237
+ var chartOptions = createChartOptions({
238
+ axisPointer: axisPointer,
239
+ camera: camera,
152
240
  data: data,
241
+ emphasis: emphasis,
153
242
  encode: encode,
154
243
  grid: grid,
155
244
  height: height,
156
245
  itemStyle: itemStyle,
246
+ options: options,
247
+ symbol: symbol,
157
248
  symbolSize: symbolSize,
158
249
  width: width,
159
250
  xAxisData: xAxisData,
160
251
  yAxisData: yAxisData,
161
- }));
252
+ });
253
+ chart.setOption(chartOptions, {
254
+ replaceMerge: ["dataZoom", "tooltip"],
255
+ });
256
+ /**
257
+ * We need to remove old event listeners and bind new ones to
258
+ * make sure that the event listeners are updated when the props change.
259
+ */
260
+ if (onEvents) {
261
+ var _loop_1 = function (eventName) {
262
+ if (Object.prototype.hasOwnProperty.call(onEvents, eventName) &&
263
+ typeof eventName === "string" &&
264
+ typeof onEvents[eventName] === "function") {
265
+ // Remove old event listener
266
+ chart.off(eventName);
267
+ // Add new event listener
268
+ chart.on(eventName, function (event) {
269
+ onEvents[eventName](event, chart);
270
+ });
271
+ }
272
+ };
273
+ for (var eventName in onEvents) {
274
+ _loop_1(eventName);
275
+ }
276
+ }
162
277
  }, UPDATE_THROTTLE_MS,
163
278
  // (thuang): Trailing guarantees that the last call to the function will
164
279
  // be executed
165
280
  { trailing: true });
166
281
  }, [
282
+ axisPointer,
283
+ camera,
167
284
  chart,
168
285
  data,
286
+ emphasis,
169
287
  xAxisData,
170
288
  yAxisData,
171
289
  width,
172
290
  height,
173
291
  encode,
174
292
  itemStyle,
293
+ symbol,
175
294
  symbolSize,
176
295
  grid,
296
+ options,
297
+ onEvents,
177
298
  ]);
178
299
  useEffect(function () {
179
300
  return function () { return throttledUpdateChart.cancel(); };
@@ -182,8 +303,11 @@ function useUpdateChart(_a) {
182
303
  useEffect(function () {
183
304
  throttledUpdateChart();
184
305
  }, [
306
+ axisPointer,
307
+ camera,
185
308
  chart,
186
309
  data,
310
+ emphasis,
187
311
  xAxisData,
188
312
  yAxisData,
189
313
  throttledUpdateChart,
@@ -191,8 +315,11 @@ function useUpdateChart(_a) {
191
315
  height,
192
316
  encode,
193
317
  itemStyle,
318
+ symbol,
194
319
  symbolSize,
195
320
  grid,
321
+ options,
322
+ onEvents,
196
323
  ]);
197
324
  }
198
325
 
@@ -203,49 +330,121 @@ function getWidthAndHeight(_a) {
203
330
  }
204
331
  var templateObject_1;
205
332
 
206
- function HeatmapChart(props, ref) {
207
- var width = props.width, height = props.height, _a = props.echartsRendererMode, echartsRendererMode = _a === void 0 ? "canvas" : _a, onChartMouseMove = props.onChartMouseMove, xAxisData = props.xAxisData, yAxisData = props.yAxisData, data = props.data, encode = props.encode, itemStyle = props.itemStyle, _b = props.symbolSize, symbolSize = _b === void 0 ? 5 : _b, grid = props.grid, rest = __rest(props, ["width", "height", "echartsRendererMode", "onChartMouseMove", "xAxisData", "yAxisData", "data", "encode", "itemStyle", "symbolSize", "grid"]);
333
+ var HeatmapChart = forwardRef(function (props, ref
334
+ // eslint-disable-next-line sonarjs/cognitive-complexity
335
+ ) {
336
+ var axisPointer = props.axisPointer, width = props.width, height = props.height, _a = props.echartsRendererMode, echartsRendererMode = _a === void 0 ? "svg" : _a, camera = props.camera, onEvents = props.onEvents, xAxisData = props.xAxisData, yAxisData = props.yAxisData, data = props.data, encode = props.encode, emphasis = props.emphasis, itemStyle = props.itemStyle, symbol = props.symbol, _b = props.symbolSize, symbolSize = _b === void 0 ? 5 : _b, grid = props.grid, options = props.options, rest = __rest(props, ["axisPointer", "width", "height", "echartsRendererMode", "camera", "onEvents", "xAxisData", "yAxisData", "data", "encode", "emphasis", "itemStyle", "symbol", "symbolSize", "grid", "options"]);
337
+ // Validate width and height
208
338
  if (!width || !height) {
209
339
  throw Error("Chart must have width and height > 0");
210
340
  }
211
- var _c = useState(false), isChartInitialized = _c[0], setIsChartInitialized = _c[1];
212
- var _d = useState(null), chart = _d[0], setChart = _d[1];
341
+ // Ref for the chart container
213
342
  var innerRef = useRef(null);
214
- // Initialize charts
215
- useEffect(function () {
343
+ /**
344
+ * (thuang): We need both a state and a ref to store the chart instance, so
345
+ * some hooks can opt out of re-rendering when the chart instance changes.
346
+ */
347
+ var _c = useState(null), chart = _c[0], setChart = _c[1];
348
+ var chartRef = useRef(chart);
349
+ /**
350
+ * (thuang): Use this ref to store the onEvents prop to prevent
351
+ * unnecessary re-renders when the onEvents prop changes.
352
+ * NOTE: This implies that `onEvents` prop changes alone from the parent
353
+ * won't re-render the chart
354
+ */
355
+ var onEventsRef = useRef(onEvents);
356
+ /**
357
+ * (thuang): Use this function to dispose the chart instance for both
358
+ * the state and the ref. This is to prevent memory leaks.
359
+ */
360
+ var disposeChart = useCallback(function () {
361
+ var _a;
362
+ (_a = chartRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
363
+ chartRef.current = null;
364
+ setChart(null);
365
+ }, []);
366
+ // Function to initialize the chart
367
+ var initChart = useCallback(function () {
368
+ var onEventsCurrent = onEventsRef.current;
216
369
  var current = innerRef.current;
217
370
  if (!current ||
218
- isChartInitialized ||
371
+ chartRef.current ||
219
372
  // (thuang): echart's `init()` will throw error if the container has 0 width or height
220
373
  (current === null || current === void 0 ? void 0 : current.getAttribute("height")) === "0" ||
221
374
  (current === null || current === void 0 ? void 0 : current.getAttribute("width")) === "0") {
222
375
  return;
223
376
  }
224
- setIsChartInitialized(true);
377
+ // Initialize ECharts instance
225
378
  var rawChart = init(current, EMPTY_OBJECT, {
226
379
  renderer: echartsRendererMode,
227
380
  useDirtyRect: true,
228
381
  });
229
- if (onChartMouseMove) {
230
- rawChart.getZr().on("mousemove", function (event) {
231
- onChartMouseMove(event, rawChart);
232
- });
382
+ // Bind events if provided
383
+ if (onEventsCurrent) {
384
+ bindEvents(rawChart, onEventsCurrent);
233
385
  }
234
386
  setChart(rawChart);
235
- }, [innerRef, isChartInitialized, echartsRendererMode, onChartMouseMove]);
387
+ chartRef.current = rawChart;
388
+ // Cleanup function
389
+ return function () {
390
+ disposeChart();
391
+ // Unbind events if provided
392
+ if (onEventsCurrent) {
393
+ for (var eventName in onEventsCurrent) {
394
+ if (Object.prototype.hasOwnProperty.call(onEventsCurrent, eventName) &&
395
+ typeof eventName === "string" &&
396
+ typeof onEventsCurrent[eventName] === "function") {
397
+ rawChart.off(eventName, onEventsCurrent[eventName]);
398
+ }
399
+ }
400
+ }
401
+ };
402
+ }, [echartsRendererMode, disposeChart]);
403
+ // Initialize charts on component mount
404
+ useEffect(function () {
405
+ disposeChart();
406
+ initChart();
407
+ }, [initChart, disposeChart]);
408
+ // Hook to update chart data and options
236
409
  useUpdateChart({
410
+ axisPointer: axisPointer,
411
+ camera: camera,
237
412
  chart: chart,
238
413
  data: data,
414
+ emphasis: emphasis,
239
415
  encode: encode,
240
416
  grid: grid,
241
417
  height: height,
242
418
  itemStyle: itemStyle,
419
+ onEvents: onEvents,
420
+ options: options,
421
+ symbol: symbol,
243
422
  symbolSize: symbolSize,
244
423
  width: width,
245
424
  xAxisData: xAxisData,
246
425
  yAxisData: yAxisData,
247
426
  });
427
+ // Render the chart container
248
428
  return (jsx(ChartContainer, __assign({ height: height, width: width, ref: handleRef }, rest)));
429
+ // Function to bind events to the ECharts instance
430
+ function bindEvents(instance, events) {
431
+ function innerBindEvent(eventName, func) {
432
+ // Ignore invalid event configurations
433
+ if (typeof eventName === "string" && typeof func === "function") {
434
+ // Bind event
435
+ instance.on(eventName, function (param) {
436
+ func(param, instance);
437
+ });
438
+ }
439
+ }
440
+ // Loop through events and bind them
441
+ for (var eventName in events) {
442
+ if (Object.prototype.hasOwnProperty.call(events, eventName)) {
443
+ innerBindEvent(eventName, events[eventName]);
444
+ }
445
+ }
446
+ }
447
+ // Function to handle the ref of the chart container
249
448
  function handleRef(element) {
250
449
  innerRef.current = element;
251
450
  if (!ref)
@@ -258,7 +457,7 @@ function HeatmapChart(props, ref) {
258
457
  ref.current = element;
259
458
  }
260
459
  }
261
- }
262
- var index = memo(forwardRef(HeatmapChart));
460
+ });
461
+ var index = memo(HeatmapChart);
263
462
 
264
463
  export { index as HeatmapChart };