@czi-sds/data-viz 0.5.0 → 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.
- package/dist/index.cjs.d.ts +64 -2
- package/dist/index.cjs.js +281 -82
- package/dist/index.esm.d.ts +64 -2
- package/dist/index.esm.js +282 -83
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -3
package/dist/index.esm.d.ts
CHANGED
|
@@ -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,
|
|
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(
|
|
64
|
-
var
|
|
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
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
86
|
-
|
|
145
|
+
axisTick: {
|
|
146
|
+
show: false,
|
|
87
147
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
207
|
-
|
|
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
|
-
|
|
212
|
-
var _d = useState(null), chart = _d[0], setChart = _d[1];
|
|
341
|
+
// Ref for the chart container
|
|
213
342
|
var innerRef = useRef(null);
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
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
|
-
|
|
377
|
+
// Initialize ECharts instance
|
|
225
378
|
var rawChart = init(current, EMPTY_OBJECT, {
|
|
226
379
|
renderer: echartsRendererMode,
|
|
227
380
|
useDirtyRect: true,
|
|
228
381
|
});
|
|
229
|
-
if
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
});
|
|
382
|
+
// Bind events if provided
|
|
383
|
+
if (onEventsCurrent) {
|
|
384
|
+
bindEvents(rawChart, onEventsCurrent);
|
|
233
385
|
}
|
|
234
386
|
setChart(rawChart);
|
|
235
|
-
|
|
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(
|
|
460
|
+
});
|
|
461
|
+
var index = memo(HeatmapChart);
|
|
263
462
|
|
|
264
463
|
export { index as HeatmapChart };
|