@czi-sds/data-viz 2.2.0 → 2.4.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/HeatmapChart.cjs.d.ts +2 -0
- package/dist/HeatmapChart.cjs.js +8 -0
- package/dist/HeatmapChart.esm.d.ts +2 -0
- package/dist/HeatmapChart.esm.js +3 -0
- package/dist/ProteinStructureViewer.cjs.d.ts +2 -0
- package/dist/ProteinStructureViewer.cjs.js +14 -0
- package/dist/ProteinStructureViewer.esm.d.ts +2 -0
- package/dist/ProteinStructureViewer.esm.js +3 -0
- package/dist/StackedBarChart.cjs.d.ts +2 -0
- package/dist/StackedBarChart.cjs.js +8 -0
- package/dist/StackedBarChart.esm.d.ts +2 -0
- package/dist/StackedBarChart.esm.js +3 -0
- package/dist/colorScales.cjs.d.ts +2 -0
- package/dist/colorScales.cjs.js +6 -0
- package/dist/colorScales.esm.d.ts +2 -0
- package/dist/colorScales.esm.js +3 -0
- package/dist/index.cjs.d.ts +5 -735
- package/dist/index.cjs.js +16 -5465
- package/dist/index.esm.d.ts +5 -737
- package/dist/index.esm.js +5 -5423
- package/dist/shared/HeatmapChart.cjs.js +349 -0
- package/dist/shared/HeatmapChart.esm.js +342 -0
- package/dist/shared/ProteinStructureViewer.cjs.js +4780 -0
- package/dist/shared/ProteinStructureViewer.esm.js +4728 -0
- package/dist/shared/StackedBarChart.cjs.js +489 -0
- package/dist/shared/StackedBarChart.esm.js +483 -0
- package/dist/shared/colorScales.cjs.d.ts +45 -0
- package/dist/shared/colorScales.cjs.js +126 -0
- package/dist/shared/colorScales.esm.d.ts +45 -0
- package/dist/shared/colorScales.esm.js +103 -0
- package/dist/shared/index.cjs.d.ts +183 -0
- package/dist/shared/index.esm.d.ts +183 -0
- package/dist/shared/index2.cjs.d.ts +389 -0
- package/dist/shared/index2.esm.d.ts +391 -0
- package/dist/shared/index3.cjs.d.ts +166 -0
- package/dist/shared/index3.esm.d.ts +166 -0
- package/dist/shared/objectSpread2.cjs.js +124 -0
- package/dist/shared/objectSpread2.esm.js +85 -0
- package/package.json +64 -2
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const require_objectSpread2 = require("./objectSpread2.cjs.js");
|
|
3
|
+
let echarts = require("echarts");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
let lodash = require("lodash");
|
|
6
|
+
let _emotion_styled = require("@emotion/styled");
|
|
7
|
+
_emotion_styled = require_objectSpread2.__toESM(_emotion_styled);
|
|
8
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
+
//#region src/common/utils.ts
|
|
10
|
+
const EMPTY_OBJECT = {};
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/core/HeatmapChart/hooks/utils.ts
|
|
13
|
+
const _excluded$1 = [
|
|
14
|
+
"axisPointer",
|
|
15
|
+
"dataZoom",
|
|
16
|
+
"series",
|
|
17
|
+
"xAxis",
|
|
18
|
+
"yAxis"
|
|
19
|
+
];
|
|
20
|
+
const DEFAULT_ITEM_STYLE = { color() {
|
|
21
|
+
return "rgb(0, 0, 0)";
|
|
22
|
+
} };
|
|
23
|
+
function createChartOptions(props) {
|
|
24
|
+
const { axisPointer, camera, data, dataZoom, emphasis, encode, grid: gridProp, itemStyle = DEFAULT_ITEM_STYLE, options, symbolSize, symbol = "rect" } = props;
|
|
25
|
+
const { defaultAxisPointer, defaultDataZoom, defaultEmphasis, defaultGrid, defaultXAxis, defaultYAxis } = generateDefaultValues(props);
|
|
26
|
+
const customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp;
|
|
27
|
+
const _ref = options || {}, { axisPointer: optionsAxisPointer, dataZoom: optionsDataZoom, series: optionsSeries, xAxis: optionsXAxis, yAxis: optionsYAxis } = _ref, optionsRest = require_objectSpread2._objectWithoutProperties(_ref, _excluded$1);
|
|
28
|
+
return require_objectSpread2._objectSpread2({
|
|
29
|
+
animation: false,
|
|
30
|
+
axisPointer: mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer),
|
|
31
|
+
dataZoom: (camera === null || camera === void 0 ? void 0 : camera.active) ? mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) : [],
|
|
32
|
+
dataset: { source: data },
|
|
33
|
+
grid: customGrid || defaultGrid,
|
|
34
|
+
series: [Object.assign({
|
|
35
|
+
emphasis: Object.assign(defaultEmphasis, emphasis),
|
|
36
|
+
encode,
|
|
37
|
+
itemStyle,
|
|
38
|
+
legendHoverLink: false,
|
|
39
|
+
symbol,
|
|
40
|
+
symbolSize
|
|
41
|
+
}, optionsSeries ? Array.isArray(optionsSeries) ? optionsSeries[0] : optionsSeries : [], {
|
|
42
|
+
symbol,
|
|
43
|
+
type: "scatter"
|
|
44
|
+
})],
|
|
45
|
+
xAxis: [Object.assign(defaultXAxis, optionsXAxis ? Array.isArray(optionsXAxis) ? optionsXAxis[0] : optionsXAxis : {})],
|
|
46
|
+
yAxis: [Object.assign(defaultYAxis, optionsYAxis ? Array.isArray(optionsYAxis) ? optionsYAxis[0] : optionsYAxis : {})]
|
|
47
|
+
}, optionsRest);
|
|
48
|
+
}
|
|
49
|
+
function mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer) {
|
|
50
|
+
const finalAxisPointer = Array.isArray(axisPointer) ? axisPointer : [axisPointer, axisPointer];
|
|
51
|
+
const finalOptionsAxisPointer = Array.isArray(optionsAxisPointer) ? optionsAxisPointer : [optionsAxisPointer, optionsAxisPointer];
|
|
52
|
+
return [require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, defaultAxisPointer), finalAxisPointer[0]), finalOptionsAxisPointer === null || finalOptionsAxisPointer === void 0 ? void 0 : finalOptionsAxisPointer[0]), require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, defaultAxisPointer), finalAxisPointer[1]), finalOptionsAxisPointer[1])];
|
|
53
|
+
}
|
|
54
|
+
function mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) {
|
|
55
|
+
const finalDataZoom = Array.isArray(dataZoom) ? dataZoom : [dataZoom, dataZoom];
|
|
56
|
+
const finalOptionsDataZoom = Array.isArray(optionsDataZoom) ? optionsDataZoom : [optionsDataZoom, optionsDataZoom];
|
|
57
|
+
return [require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, defaultDataZoom[0]), finalDataZoom[0]), finalOptionsDataZoom === null || finalOptionsDataZoom === void 0 ? void 0 : finalOptionsDataZoom[0]), require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, defaultDataZoom[1]), finalDataZoom[1]), finalOptionsDataZoom[1])];
|
|
58
|
+
}
|
|
59
|
+
function generateDefaultValues(props) {
|
|
60
|
+
const { camera, height, symbol, width, xAxisData, yAxisData } = props;
|
|
61
|
+
const defaultGrid = {
|
|
62
|
+
height: `${height}px`,
|
|
63
|
+
left: 0,
|
|
64
|
+
top: 0,
|
|
65
|
+
width: `${width}px`
|
|
66
|
+
};
|
|
67
|
+
const defaultAxisPointer = {
|
|
68
|
+
label: { show: false },
|
|
69
|
+
show: false,
|
|
70
|
+
triggerOn: "mousemove"
|
|
71
|
+
};
|
|
72
|
+
const defaultXAxis = {
|
|
73
|
+
axisLabel: {
|
|
74
|
+
fontSize: 0,
|
|
75
|
+
rotate: 90
|
|
76
|
+
},
|
|
77
|
+
axisLine: { show: false },
|
|
78
|
+
axisTick: { show: false },
|
|
79
|
+
boundaryGap: true,
|
|
80
|
+
data: xAxisData,
|
|
81
|
+
splitLine: { show: false },
|
|
82
|
+
type: "category"
|
|
83
|
+
};
|
|
84
|
+
const defaultYAxis = {
|
|
85
|
+
axisLabel: { fontSize: 0 },
|
|
86
|
+
axisLine: { show: false },
|
|
87
|
+
axisTick: { show: false },
|
|
88
|
+
boundaryGap: true,
|
|
89
|
+
data: yAxisData,
|
|
90
|
+
splitLine: { show: false }
|
|
91
|
+
};
|
|
92
|
+
const defaultEmphasis = {
|
|
93
|
+
itemStyle: {
|
|
94
|
+
borderColor: symbol === "circle" ? "black" : "white",
|
|
95
|
+
borderType: "solid",
|
|
96
|
+
borderWidth: symbol === "circle" ? 2 : 4,
|
|
97
|
+
opacity: 1
|
|
98
|
+
},
|
|
99
|
+
scale: false
|
|
100
|
+
};
|
|
101
|
+
const defaultCamera = {
|
|
102
|
+
height: camera && camera.height ? camera.height : 20,
|
|
103
|
+
width: camera && camera.width ? camera.width : 40
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
defaultAxisPointer,
|
|
107
|
+
defaultDataZoom: [{
|
|
108
|
+
endValue: defaultCamera.width - 1,
|
|
109
|
+
filterMode: "filter",
|
|
110
|
+
moveOnMouseMove: true,
|
|
111
|
+
moveOnMouseWheel: false,
|
|
112
|
+
orient: "horizontal",
|
|
113
|
+
preventDefaultMouseMove: true,
|
|
114
|
+
startValue: 0,
|
|
115
|
+
throttle: 0,
|
|
116
|
+
type: "inside",
|
|
117
|
+
xAxisIndex: 0,
|
|
118
|
+
zoomOnMouseWheel: false
|
|
119
|
+
}, {
|
|
120
|
+
endValue: defaultCamera.height - 1,
|
|
121
|
+
filterMode: "filter",
|
|
122
|
+
moveOnMouseMove: true,
|
|
123
|
+
moveOnMouseWheel: true,
|
|
124
|
+
orient: "vertical",
|
|
125
|
+
preventDefaultMouseMove: true,
|
|
126
|
+
startValue: 0,
|
|
127
|
+
throttle: 0,
|
|
128
|
+
type: "inside",
|
|
129
|
+
yAxisIndex: 0,
|
|
130
|
+
zoomOnMouseWheel: false
|
|
131
|
+
}],
|
|
132
|
+
defaultEmphasis,
|
|
133
|
+
defaultGrid,
|
|
134
|
+
defaultXAxis,
|
|
135
|
+
defaultYAxis
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/core/HeatmapChart/hooks/useUpdateChart.ts
|
|
140
|
+
const UPDATE_THROTTLE_MS = 100;
|
|
141
|
+
function useUpdateChart({ axisPointer, camera, chart, data, dataZoom, emphasis, xAxisData, yAxisData, width, height, encode, itemStyle, symbol, symbolSize, grid, options, onEvents }) {
|
|
142
|
+
const throttledUpdateChart = (0, react.useMemo)(() => {
|
|
143
|
+
return (0, lodash.throttle)(() => {
|
|
144
|
+
if (!chart || !data || !xAxisData || !yAxisData) return;
|
|
145
|
+
chart.resize();
|
|
146
|
+
const chartOptions = createChartOptions({
|
|
147
|
+
axisPointer,
|
|
148
|
+
camera,
|
|
149
|
+
data,
|
|
150
|
+
dataZoom,
|
|
151
|
+
emphasis,
|
|
152
|
+
encode,
|
|
153
|
+
grid,
|
|
154
|
+
height,
|
|
155
|
+
itemStyle,
|
|
156
|
+
options,
|
|
157
|
+
symbol,
|
|
158
|
+
symbolSize,
|
|
159
|
+
width,
|
|
160
|
+
xAxisData,
|
|
161
|
+
yAxisData
|
|
162
|
+
});
|
|
163
|
+
chart.setOption(chartOptions, { replaceMerge: ["dataZoom", "tooltip"] });
|
|
164
|
+
/**
|
|
165
|
+
* We need to remove old event listeners and bind new ones to
|
|
166
|
+
* make sure that the event listeners are updated when the props change.
|
|
167
|
+
*/
|
|
168
|
+
if (onEvents) {
|
|
169
|
+
for (const eventName in onEvents) if (Object.prototype.hasOwnProperty.call(onEvents, eventName) && typeof eventName === "string" && typeof onEvents[eventName] === "function") {
|
|
170
|
+
chart.off(eventName);
|
|
171
|
+
chart.on(eventName, (event) => {
|
|
172
|
+
onEvents[eventName](event, chart);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}, UPDATE_THROTTLE_MS, { trailing: true });
|
|
177
|
+
}, [
|
|
178
|
+
axisPointer,
|
|
179
|
+
camera,
|
|
180
|
+
chart,
|
|
181
|
+
data,
|
|
182
|
+
dataZoom,
|
|
183
|
+
emphasis,
|
|
184
|
+
xAxisData,
|
|
185
|
+
yAxisData,
|
|
186
|
+
width,
|
|
187
|
+
height,
|
|
188
|
+
encode,
|
|
189
|
+
itemStyle,
|
|
190
|
+
symbol,
|
|
191
|
+
symbolSize,
|
|
192
|
+
grid,
|
|
193
|
+
options,
|
|
194
|
+
onEvents
|
|
195
|
+
]);
|
|
196
|
+
(0, react.useEffect)(() => {
|
|
197
|
+
return () => throttledUpdateChart.cancel();
|
|
198
|
+
}, [throttledUpdateChart]);
|
|
199
|
+
(0, react.useEffect)(() => {
|
|
200
|
+
throttledUpdateChart();
|
|
201
|
+
}, [
|
|
202
|
+
axisPointer,
|
|
203
|
+
camera,
|
|
204
|
+
chart,
|
|
205
|
+
data,
|
|
206
|
+
dataZoom,
|
|
207
|
+
emphasis,
|
|
208
|
+
xAxisData,
|
|
209
|
+
yAxisData,
|
|
210
|
+
throttledUpdateChart,
|
|
211
|
+
width,
|
|
212
|
+
height,
|
|
213
|
+
encode,
|
|
214
|
+
itemStyle,
|
|
215
|
+
symbol,
|
|
216
|
+
symbolSize,
|
|
217
|
+
grid,
|
|
218
|
+
options,
|
|
219
|
+
onEvents
|
|
220
|
+
]);
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/core/HeatmapChart/style.ts
|
|
224
|
+
const ChartContainer = (0, _emotion_styled.default)("div")`
|
|
225
|
+
${getWidthAndHeight}
|
|
226
|
+
`;
|
|
227
|
+
function getWidthAndHeight({ width, height }) {
|
|
228
|
+
return `
|
|
229
|
+
width: ${width}px;
|
|
230
|
+
height: ${height}px;
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
233
|
+
//#endregion
|
|
234
|
+
//#region src/core/HeatmapChart/index.tsx
|
|
235
|
+
const _excluded = [
|
|
236
|
+
"axisPointer",
|
|
237
|
+
"width",
|
|
238
|
+
"height",
|
|
239
|
+
"echartsRendererMode",
|
|
240
|
+
"camera",
|
|
241
|
+
"dataZoom",
|
|
242
|
+
"onEvents",
|
|
243
|
+
"xAxisData",
|
|
244
|
+
"yAxisData",
|
|
245
|
+
"data",
|
|
246
|
+
"encode",
|
|
247
|
+
"emphasis",
|
|
248
|
+
"itemStyle",
|
|
249
|
+
"symbol",
|
|
250
|
+
"symbolSize",
|
|
251
|
+
"grid",
|
|
252
|
+
"options"
|
|
253
|
+
];
|
|
254
|
+
const HeatmapChart = (0, react.forwardRef)((props, ref) => {
|
|
255
|
+
const { axisPointer, width, height, echartsRendererMode = "svg", camera, dataZoom, onEvents, xAxisData, yAxisData, data, encode, emphasis, itemStyle, symbol, symbolSize = 5, grid, options } = props, rest = require_objectSpread2._objectWithoutProperties(props, _excluded);
|
|
256
|
+
if (!width || !height) throw Error("Heatmap must have width and height bigger than Zero!");
|
|
257
|
+
const innerRef = (0, react.useRef)(null);
|
|
258
|
+
/**
|
|
259
|
+
* (thuang): We need both a state and a ref to store the chart instance, so
|
|
260
|
+
* some hooks can opt out of re-rendering when the chart instance changes.
|
|
261
|
+
*/
|
|
262
|
+
const [chart, setChart] = (0, react.useState)(null);
|
|
263
|
+
const chartRef = (0, react.useRef)(chart);
|
|
264
|
+
/**
|
|
265
|
+
* (thuang): Use this ref to store the onEvents prop to prevent
|
|
266
|
+
* unnecessary re-renders when the onEvents prop changes.
|
|
267
|
+
* NOTE: This implies that `onEvents` prop changes alone from the parent
|
|
268
|
+
* won't re-render the chart
|
|
269
|
+
*/
|
|
270
|
+
const onEventsRef = (0, react.useRef)(onEvents);
|
|
271
|
+
/**
|
|
272
|
+
* (thuang): Use this function to dispose the chart instance for both
|
|
273
|
+
* the state and the ref. This is to prevent memory leaks.
|
|
274
|
+
*/
|
|
275
|
+
const disposeChart = (0, react.useCallback)(() => {
|
|
276
|
+
var _chartRef$current;
|
|
277
|
+
(_chartRef$current = chartRef.current) === null || _chartRef$current === void 0 || _chartRef$current.dispose();
|
|
278
|
+
chartRef.current = null;
|
|
279
|
+
setChart(null);
|
|
280
|
+
}, []);
|
|
281
|
+
const initChart = (0, react.useCallback)(() => {
|
|
282
|
+
const onEventsCurrent = onEventsRef.current;
|
|
283
|
+
const { current } = innerRef;
|
|
284
|
+
if (!current || chartRef.current || (current === null || current === void 0 ? void 0 : current.getAttribute("height")) === "0" || (current === null || current === void 0 ? void 0 : current.getAttribute("width")) === "0") return;
|
|
285
|
+
const rawChart = (0, echarts.init)(current, EMPTY_OBJECT, {
|
|
286
|
+
renderer: echartsRendererMode,
|
|
287
|
+
useDirtyRect: true
|
|
288
|
+
});
|
|
289
|
+
if (onEventsCurrent) bindEvents(rawChart, onEventsCurrent);
|
|
290
|
+
setChart(rawChart);
|
|
291
|
+
chartRef.current = rawChart;
|
|
292
|
+
return () => {
|
|
293
|
+
disposeChart();
|
|
294
|
+
if (onEventsCurrent) {
|
|
295
|
+
for (const eventName in onEventsCurrent) if (Object.prototype.hasOwnProperty.call(onEventsCurrent, eventName) && typeof eventName === "string" && typeof onEventsCurrent[eventName] === "function") rawChart.off(eventName, onEventsCurrent[eventName]);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}, [echartsRendererMode, disposeChart]);
|
|
299
|
+
(0, react.useEffect)(() => {
|
|
300
|
+
disposeChart();
|
|
301
|
+
initChart();
|
|
302
|
+
}, [initChart, disposeChart]);
|
|
303
|
+
useUpdateChart({
|
|
304
|
+
axisPointer,
|
|
305
|
+
camera,
|
|
306
|
+
chart,
|
|
307
|
+
data,
|
|
308
|
+
dataZoom,
|
|
309
|
+
emphasis,
|
|
310
|
+
encode,
|
|
311
|
+
grid,
|
|
312
|
+
height,
|
|
313
|
+
itemStyle,
|
|
314
|
+
onEvents,
|
|
315
|
+
options,
|
|
316
|
+
symbol,
|
|
317
|
+
symbolSize,
|
|
318
|
+
width,
|
|
319
|
+
xAxisData,
|
|
320
|
+
yAxisData
|
|
321
|
+
});
|
|
322
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartContainer, require_objectSpread2._objectSpread2({
|
|
323
|
+
height,
|
|
324
|
+
width,
|
|
325
|
+
ref: handleRef
|
|
326
|
+
}, rest));
|
|
327
|
+
function bindEvents(instance, events) {
|
|
328
|
+
function innerBindEvent(eventName, func) {
|
|
329
|
+
if (typeof eventName === "string" && typeof func === "function") instance.on(eventName, (param) => {
|
|
330
|
+
func(param, instance);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
for (const eventName in events) if (Object.prototype.hasOwnProperty.call(events, eventName)) innerBindEvent(eventName, events[eventName]);
|
|
334
|
+
}
|
|
335
|
+
function handleRef(element) {
|
|
336
|
+
innerRef.current = element;
|
|
337
|
+
if (!ref) return;
|
|
338
|
+
if (typeof ref === "function") ref(element);
|
|
339
|
+
else ref.current = element;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
var HeatmapChart_default = (0, react.memo)(HeatmapChart);
|
|
343
|
+
//#endregion
|
|
344
|
+
Object.defineProperty(exports, "HeatmapChart_default", {
|
|
345
|
+
enumerable: true,
|
|
346
|
+
get: function() {
|
|
347
|
+
return HeatmapChart_default;
|
|
348
|
+
}
|
|
349
|
+
});
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { n as _objectWithoutProperties, t as _objectSpread2 } from "./objectSpread2.esm.js";
|
|
3
|
+
import { init } from "echarts";
|
|
4
|
+
import { forwardRef, memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { throttle } from "lodash";
|
|
6
|
+
import styled from "@emotion/styled";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
//#region src/common/utils.ts
|
|
9
|
+
const EMPTY_OBJECT = {};
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/core/HeatmapChart/hooks/utils.ts
|
|
12
|
+
const _excluded$1 = [
|
|
13
|
+
"axisPointer",
|
|
14
|
+
"dataZoom",
|
|
15
|
+
"series",
|
|
16
|
+
"xAxis",
|
|
17
|
+
"yAxis"
|
|
18
|
+
];
|
|
19
|
+
const DEFAULT_ITEM_STYLE = { color() {
|
|
20
|
+
return "rgb(0, 0, 0)";
|
|
21
|
+
} };
|
|
22
|
+
function createChartOptions(props) {
|
|
23
|
+
const { axisPointer, camera, data, dataZoom, emphasis, encode, grid: gridProp, itemStyle = DEFAULT_ITEM_STYLE, options, symbolSize, symbol = "rect" } = props;
|
|
24
|
+
const { defaultAxisPointer, defaultDataZoom, defaultEmphasis, defaultGrid, defaultXAxis, defaultYAxis } = generateDefaultValues(props);
|
|
25
|
+
const customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp;
|
|
26
|
+
const _ref = options || {}, { axisPointer: optionsAxisPointer, dataZoom: optionsDataZoom, series: optionsSeries, xAxis: optionsXAxis, yAxis: optionsYAxis } = _ref, optionsRest = _objectWithoutProperties(_ref, _excluded$1);
|
|
27
|
+
return _objectSpread2({
|
|
28
|
+
animation: false,
|
|
29
|
+
axisPointer: mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer),
|
|
30
|
+
dataZoom: (camera === null || camera === void 0 ? void 0 : camera.active) ? mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) : [],
|
|
31
|
+
dataset: { source: data },
|
|
32
|
+
grid: customGrid || defaultGrid,
|
|
33
|
+
series: [Object.assign({
|
|
34
|
+
emphasis: Object.assign(defaultEmphasis, emphasis),
|
|
35
|
+
encode,
|
|
36
|
+
itemStyle,
|
|
37
|
+
legendHoverLink: false,
|
|
38
|
+
symbol,
|
|
39
|
+
symbolSize
|
|
40
|
+
}, optionsSeries ? Array.isArray(optionsSeries) ? optionsSeries[0] : optionsSeries : [], {
|
|
41
|
+
symbol,
|
|
42
|
+
type: "scatter"
|
|
43
|
+
})],
|
|
44
|
+
xAxis: [Object.assign(defaultXAxis, optionsXAxis ? Array.isArray(optionsXAxis) ? optionsXAxis[0] : optionsXAxis : {})],
|
|
45
|
+
yAxis: [Object.assign(defaultYAxis, optionsYAxis ? Array.isArray(optionsYAxis) ? optionsYAxis[0] : optionsYAxis : {})]
|
|
46
|
+
}, optionsRest);
|
|
47
|
+
}
|
|
48
|
+
function mergeAxisPointer(defaultAxisPointer, axisPointer, optionsAxisPointer) {
|
|
49
|
+
const finalAxisPointer = Array.isArray(axisPointer) ? axisPointer : [axisPointer, axisPointer];
|
|
50
|
+
const finalOptionsAxisPointer = Array.isArray(optionsAxisPointer) ? optionsAxisPointer : [optionsAxisPointer, optionsAxisPointer];
|
|
51
|
+
return [_objectSpread2(_objectSpread2(_objectSpread2({}, defaultAxisPointer), finalAxisPointer[0]), finalOptionsAxisPointer === null || finalOptionsAxisPointer === void 0 ? void 0 : finalOptionsAxisPointer[0]), _objectSpread2(_objectSpread2(_objectSpread2({}, defaultAxisPointer), finalAxisPointer[1]), finalOptionsAxisPointer[1])];
|
|
52
|
+
}
|
|
53
|
+
function mergeDataZoom(defaultDataZoom, dataZoom, optionsDataZoom) {
|
|
54
|
+
const finalDataZoom = Array.isArray(dataZoom) ? dataZoom : [dataZoom, dataZoom];
|
|
55
|
+
const finalOptionsDataZoom = Array.isArray(optionsDataZoom) ? optionsDataZoom : [optionsDataZoom, optionsDataZoom];
|
|
56
|
+
return [_objectSpread2(_objectSpread2(_objectSpread2({}, defaultDataZoom[0]), finalDataZoom[0]), finalOptionsDataZoom === null || finalOptionsDataZoom === void 0 ? void 0 : finalOptionsDataZoom[0]), _objectSpread2(_objectSpread2(_objectSpread2({}, defaultDataZoom[1]), finalDataZoom[1]), finalOptionsDataZoom[1])];
|
|
57
|
+
}
|
|
58
|
+
function generateDefaultValues(props) {
|
|
59
|
+
const { camera, height, symbol, width, xAxisData, yAxisData } = props;
|
|
60
|
+
const defaultGrid = {
|
|
61
|
+
height: `${height}px`,
|
|
62
|
+
left: 0,
|
|
63
|
+
top: 0,
|
|
64
|
+
width: `${width}px`
|
|
65
|
+
};
|
|
66
|
+
const defaultAxisPointer = {
|
|
67
|
+
label: { show: false },
|
|
68
|
+
show: false,
|
|
69
|
+
triggerOn: "mousemove"
|
|
70
|
+
};
|
|
71
|
+
const defaultXAxis = {
|
|
72
|
+
axisLabel: {
|
|
73
|
+
fontSize: 0,
|
|
74
|
+
rotate: 90
|
|
75
|
+
},
|
|
76
|
+
axisLine: { show: false },
|
|
77
|
+
axisTick: { show: false },
|
|
78
|
+
boundaryGap: true,
|
|
79
|
+
data: xAxisData,
|
|
80
|
+
splitLine: { show: false },
|
|
81
|
+
type: "category"
|
|
82
|
+
};
|
|
83
|
+
const defaultYAxis = {
|
|
84
|
+
axisLabel: { fontSize: 0 },
|
|
85
|
+
axisLine: { show: false },
|
|
86
|
+
axisTick: { show: false },
|
|
87
|
+
boundaryGap: true,
|
|
88
|
+
data: yAxisData,
|
|
89
|
+
splitLine: { show: false }
|
|
90
|
+
};
|
|
91
|
+
const defaultEmphasis = {
|
|
92
|
+
itemStyle: {
|
|
93
|
+
borderColor: symbol === "circle" ? "black" : "white",
|
|
94
|
+
borderType: "solid",
|
|
95
|
+
borderWidth: symbol === "circle" ? 2 : 4,
|
|
96
|
+
opacity: 1
|
|
97
|
+
},
|
|
98
|
+
scale: false
|
|
99
|
+
};
|
|
100
|
+
const defaultCamera = {
|
|
101
|
+
height: camera && camera.height ? camera.height : 20,
|
|
102
|
+
width: camera && camera.width ? camera.width : 40
|
|
103
|
+
};
|
|
104
|
+
return {
|
|
105
|
+
defaultAxisPointer,
|
|
106
|
+
defaultDataZoom: [{
|
|
107
|
+
endValue: defaultCamera.width - 1,
|
|
108
|
+
filterMode: "filter",
|
|
109
|
+
moveOnMouseMove: true,
|
|
110
|
+
moveOnMouseWheel: false,
|
|
111
|
+
orient: "horizontal",
|
|
112
|
+
preventDefaultMouseMove: true,
|
|
113
|
+
startValue: 0,
|
|
114
|
+
throttle: 0,
|
|
115
|
+
type: "inside",
|
|
116
|
+
xAxisIndex: 0,
|
|
117
|
+
zoomOnMouseWheel: false
|
|
118
|
+
}, {
|
|
119
|
+
endValue: defaultCamera.height - 1,
|
|
120
|
+
filterMode: "filter",
|
|
121
|
+
moveOnMouseMove: true,
|
|
122
|
+
moveOnMouseWheel: true,
|
|
123
|
+
orient: "vertical",
|
|
124
|
+
preventDefaultMouseMove: true,
|
|
125
|
+
startValue: 0,
|
|
126
|
+
throttle: 0,
|
|
127
|
+
type: "inside",
|
|
128
|
+
yAxisIndex: 0,
|
|
129
|
+
zoomOnMouseWheel: false
|
|
130
|
+
}],
|
|
131
|
+
defaultEmphasis,
|
|
132
|
+
defaultGrid,
|
|
133
|
+
defaultXAxis,
|
|
134
|
+
defaultYAxis
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/core/HeatmapChart/hooks/useUpdateChart.ts
|
|
139
|
+
const UPDATE_THROTTLE_MS = 100;
|
|
140
|
+
function useUpdateChart({ axisPointer, camera, chart, data, dataZoom, emphasis, xAxisData, yAxisData, width, height, encode, itemStyle, symbol, symbolSize, grid, options, onEvents }) {
|
|
141
|
+
const throttledUpdateChart = useMemo(() => {
|
|
142
|
+
return throttle(() => {
|
|
143
|
+
if (!chart || !data || !xAxisData || !yAxisData) return;
|
|
144
|
+
chart.resize();
|
|
145
|
+
const chartOptions = createChartOptions({
|
|
146
|
+
axisPointer,
|
|
147
|
+
camera,
|
|
148
|
+
data,
|
|
149
|
+
dataZoom,
|
|
150
|
+
emphasis,
|
|
151
|
+
encode,
|
|
152
|
+
grid,
|
|
153
|
+
height,
|
|
154
|
+
itemStyle,
|
|
155
|
+
options,
|
|
156
|
+
symbol,
|
|
157
|
+
symbolSize,
|
|
158
|
+
width,
|
|
159
|
+
xAxisData,
|
|
160
|
+
yAxisData
|
|
161
|
+
});
|
|
162
|
+
chart.setOption(chartOptions, { replaceMerge: ["dataZoom", "tooltip"] });
|
|
163
|
+
/**
|
|
164
|
+
* We need to remove old event listeners and bind new ones to
|
|
165
|
+
* make sure that the event listeners are updated when the props change.
|
|
166
|
+
*/
|
|
167
|
+
if (onEvents) {
|
|
168
|
+
for (const eventName in onEvents) if (Object.prototype.hasOwnProperty.call(onEvents, eventName) && typeof eventName === "string" && typeof onEvents[eventName] === "function") {
|
|
169
|
+
chart.off(eventName);
|
|
170
|
+
chart.on(eventName, (event) => {
|
|
171
|
+
onEvents[eventName](event, chart);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}, UPDATE_THROTTLE_MS, { trailing: true });
|
|
176
|
+
}, [
|
|
177
|
+
axisPointer,
|
|
178
|
+
camera,
|
|
179
|
+
chart,
|
|
180
|
+
data,
|
|
181
|
+
dataZoom,
|
|
182
|
+
emphasis,
|
|
183
|
+
xAxisData,
|
|
184
|
+
yAxisData,
|
|
185
|
+
width,
|
|
186
|
+
height,
|
|
187
|
+
encode,
|
|
188
|
+
itemStyle,
|
|
189
|
+
symbol,
|
|
190
|
+
symbolSize,
|
|
191
|
+
grid,
|
|
192
|
+
options,
|
|
193
|
+
onEvents
|
|
194
|
+
]);
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
return () => throttledUpdateChart.cancel();
|
|
197
|
+
}, [throttledUpdateChart]);
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
throttledUpdateChart();
|
|
200
|
+
}, [
|
|
201
|
+
axisPointer,
|
|
202
|
+
camera,
|
|
203
|
+
chart,
|
|
204
|
+
data,
|
|
205
|
+
dataZoom,
|
|
206
|
+
emphasis,
|
|
207
|
+
xAxisData,
|
|
208
|
+
yAxisData,
|
|
209
|
+
throttledUpdateChart,
|
|
210
|
+
width,
|
|
211
|
+
height,
|
|
212
|
+
encode,
|
|
213
|
+
itemStyle,
|
|
214
|
+
symbol,
|
|
215
|
+
symbolSize,
|
|
216
|
+
grid,
|
|
217
|
+
options,
|
|
218
|
+
onEvents
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/core/HeatmapChart/style.ts
|
|
223
|
+
const ChartContainer = styled("div")`
|
|
224
|
+
${getWidthAndHeight}
|
|
225
|
+
`;
|
|
226
|
+
function getWidthAndHeight({ width, height }) {
|
|
227
|
+
return `
|
|
228
|
+
width: ${width}px;
|
|
229
|
+
height: ${height}px;
|
|
230
|
+
`;
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/core/HeatmapChart/index.tsx
|
|
234
|
+
const _excluded = [
|
|
235
|
+
"axisPointer",
|
|
236
|
+
"width",
|
|
237
|
+
"height",
|
|
238
|
+
"echartsRendererMode",
|
|
239
|
+
"camera",
|
|
240
|
+
"dataZoom",
|
|
241
|
+
"onEvents",
|
|
242
|
+
"xAxisData",
|
|
243
|
+
"yAxisData",
|
|
244
|
+
"data",
|
|
245
|
+
"encode",
|
|
246
|
+
"emphasis",
|
|
247
|
+
"itemStyle",
|
|
248
|
+
"symbol",
|
|
249
|
+
"symbolSize",
|
|
250
|
+
"grid",
|
|
251
|
+
"options"
|
|
252
|
+
];
|
|
253
|
+
var HeatmapChart_default = memo(forwardRef((props, ref) => {
|
|
254
|
+
const { axisPointer, width, height, echartsRendererMode = "svg", camera, dataZoom, onEvents, xAxisData, yAxisData, data, encode, emphasis, itemStyle, symbol, symbolSize = 5, grid, options } = props, rest = _objectWithoutProperties(props, _excluded);
|
|
255
|
+
if (!width || !height) throw Error("Heatmap must have width and height bigger than Zero!");
|
|
256
|
+
const innerRef = useRef(null);
|
|
257
|
+
/**
|
|
258
|
+
* (thuang): We need both a state and a ref to store the chart instance, so
|
|
259
|
+
* some hooks can opt out of re-rendering when the chart instance changes.
|
|
260
|
+
*/
|
|
261
|
+
const [chart, setChart] = useState(null);
|
|
262
|
+
const chartRef = useRef(chart);
|
|
263
|
+
/**
|
|
264
|
+
* (thuang): Use this ref to store the onEvents prop to prevent
|
|
265
|
+
* unnecessary re-renders when the onEvents prop changes.
|
|
266
|
+
* NOTE: This implies that `onEvents` prop changes alone from the parent
|
|
267
|
+
* won't re-render the chart
|
|
268
|
+
*/
|
|
269
|
+
const onEventsRef = useRef(onEvents);
|
|
270
|
+
/**
|
|
271
|
+
* (thuang): Use this function to dispose the chart instance for both
|
|
272
|
+
* the state and the ref. This is to prevent memory leaks.
|
|
273
|
+
*/
|
|
274
|
+
const disposeChart = useCallback(() => {
|
|
275
|
+
var _chartRef$current;
|
|
276
|
+
(_chartRef$current = chartRef.current) === null || _chartRef$current === void 0 || _chartRef$current.dispose();
|
|
277
|
+
chartRef.current = null;
|
|
278
|
+
setChart(null);
|
|
279
|
+
}, []);
|
|
280
|
+
const initChart = useCallback(() => {
|
|
281
|
+
const onEventsCurrent = onEventsRef.current;
|
|
282
|
+
const { current } = innerRef;
|
|
283
|
+
if (!current || chartRef.current || (current === null || current === void 0 ? void 0 : current.getAttribute("height")) === "0" || (current === null || current === void 0 ? void 0 : current.getAttribute("width")) === "0") return;
|
|
284
|
+
const rawChart = init(current, EMPTY_OBJECT, {
|
|
285
|
+
renderer: echartsRendererMode,
|
|
286
|
+
useDirtyRect: true
|
|
287
|
+
});
|
|
288
|
+
if (onEventsCurrent) bindEvents(rawChart, onEventsCurrent);
|
|
289
|
+
setChart(rawChart);
|
|
290
|
+
chartRef.current = rawChart;
|
|
291
|
+
return () => {
|
|
292
|
+
disposeChart();
|
|
293
|
+
if (onEventsCurrent) {
|
|
294
|
+
for (const eventName in onEventsCurrent) if (Object.prototype.hasOwnProperty.call(onEventsCurrent, eventName) && typeof eventName === "string" && typeof onEventsCurrent[eventName] === "function") rawChart.off(eventName, onEventsCurrent[eventName]);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
}, [echartsRendererMode, disposeChart]);
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
disposeChart();
|
|
300
|
+
initChart();
|
|
301
|
+
}, [initChart, disposeChart]);
|
|
302
|
+
useUpdateChart({
|
|
303
|
+
axisPointer,
|
|
304
|
+
camera,
|
|
305
|
+
chart,
|
|
306
|
+
data,
|
|
307
|
+
dataZoom,
|
|
308
|
+
emphasis,
|
|
309
|
+
encode,
|
|
310
|
+
grid,
|
|
311
|
+
height,
|
|
312
|
+
itemStyle,
|
|
313
|
+
onEvents,
|
|
314
|
+
options,
|
|
315
|
+
symbol,
|
|
316
|
+
symbolSize,
|
|
317
|
+
width,
|
|
318
|
+
xAxisData,
|
|
319
|
+
yAxisData
|
|
320
|
+
});
|
|
321
|
+
return /* @__PURE__ */ jsx(ChartContainer, _objectSpread2({
|
|
322
|
+
height,
|
|
323
|
+
width,
|
|
324
|
+
ref: handleRef
|
|
325
|
+
}, rest));
|
|
326
|
+
function bindEvents(instance, events) {
|
|
327
|
+
function innerBindEvent(eventName, func) {
|
|
328
|
+
if (typeof eventName === "string" && typeof func === "function") instance.on(eventName, (param) => {
|
|
329
|
+
func(param, instance);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
for (const eventName in events) if (Object.prototype.hasOwnProperty.call(events, eventName)) innerBindEvent(eventName, events[eventName]);
|
|
333
|
+
}
|
|
334
|
+
function handleRef(element) {
|
|
335
|
+
innerRef.current = element;
|
|
336
|
+
if (!ref) return;
|
|
337
|
+
if (typeof ref === "function") ref(element);
|
|
338
|
+
else ref.current = element;
|
|
339
|
+
}
|
|
340
|
+
}));
|
|
341
|
+
//#endregion
|
|
342
|
+
export { HeatmapChart_default as t };
|