@czi-sds/data-viz 0.2.1 → 0.3.1

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,91 @@
1
1
  /// <reference types="react" />
2
- import React from "react";
3
- interface HeatmapProps {
4
- children: React.ReactNode;
2
+ import { ECharts, ElementEvent, DatasetComponentOption, EChartsOption, ScatterSeriesOption } from "echarts";
3
+ import { HTMLAttributes } from "react";
4
+ interface CreateChartOptionsProps {
5
+ /**
6
+ * The data array to be visualized
7
+ * The data point object shape can be whatever you like, but it must be consistent with the `encode` option
8
+ * For example, if the data point shape is:
9
+ * {
10
+ * geneIndex: 0,
11
+ * cellTypeIndex: 0,
12
+ * percentage: 0.5
13
+ * }
14
+ * and you want geneIndex to be encoded to x axis and cellTypeIndex to be encoded to y axis, then make sure your encode option is:
15
+ * encode: {
16
+ * x: 'geneIndex',
17
+ * y: 'cellTypeIndex'
18
+ * }
19
+ */
20
+ data: DatasetComponentOption["source"];
21
+ /**
22
+ * The data for the x axis
23
+ * For example:
24
+ * [{ value: "gene1", textStyle: { color: "red" } }, "gene2", "gene3"]
25
+ */
26
+ xAxisData: CategoryAxisData;
27
+ /**
28
+ * The data for the y axis
29
+ * For example:
30
+ * [{ value: "cellType1", textStyle: { color: "red" } }, "cellType2", "cellType3"]
31
+ */
32
+ yAxisData: CategoryAxisData;
33
+ width: number;
34
+ height: number;
35
+ /**
36
+ * Provide a mapping of data key to x/y axis encoding
37
+ * For example, if the data is:
38
+ * {
39
+ * geneIndex: 0,
40
+ * cellTypeIndex: 0,
41
+ * percentage: 0.5
42
+ * }
43
+ * and we want to encode `geneIndex` to x axis and `cellTypeIndex` to y axis, then
44
+ * encode: {
45
+ * x: 'geneIndex',
46
+ * y: 'cellTypeIndex'
47
+ * }
48
+ * https://echarts.apache.org/en/option.html#series-scatter.encode
49
+ */
50
+ encode?: {
51
+ x: string;
52
+ y: string;
53
+ };
54
+ /**
55
+ * Customize the style of each cell item, such as color, border, opacity, etc.
56
+ * https://echarts.apache.org/en/option.html#series-scatter.itemStyle
57
+ */
58
+ itemStyle?: ScatterSeriesOption["itemStyle"];
59
+ /**
60
+ * `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
+ *
62
+ * If size of symbols needs to be different, you can set with callback function in the following format:
63
+ *
64
+ * (value: Array|number, params: Object) => number|Array
65
+ *
66
+ * The first parameter value is the value in data, and the second parameter params is the rest parameters of data item.
67
+ * https://echarts.apache.org/en/option.html#series-scatter.symbolSize
68
+ */
69
+ symbolSize?: ScatterSeriesOption["symbolSize"];
70
+ /**
71
+ * https://echarts.apache.org/en/option.html#grid
72
+ */
73
+ grid?: EChartsOption["grid"] | ((defaultOption: EChartsOption["grid"]) => EChartsOption["grid"]);
5
74
  }
6
- declare const Heatmap: React.ForwardRefExoticComponent<HeatmapProps & React.RefAttributes<HTMLTableElement>>;
7
- export { HeatmapProps, Heatmap };
75
+ type OrdinalRawValue = string | number;
76
+ /**
77
+ * (thuang): This copies echarts' CategoryAxisBaseOption["data"] type, since it's not exported
78
+ */
79
+ type CategoryAxisData = (OrdinalRawValue | {
80
+ value: OrdinalRawValue;
81
+ /**
82
+ * (thuang): This should be echarts `TextCommonOption` type, but it's not exported
83
+ */
84
+ textStyle?: never;
85
+ })[];
86
+ interface HeatmapChartProps extends HTMLAttributes<HTMLDivElement>, CreateChartOptionsProps {
87
+ echartsRendererMode?: "svg" | "canvas";
88
+ onChartMouseMove?: (event: ElementEvent, chart: ECharts) => void;
89
+ }
90
+ declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<HeatmapChartProps & import("react").RefAttributes<HTMLDivElement>>>;
91
+ export { HeatmapChartProps, _default, _default as HeatmapChart };
package/dist/index.cjs.js CHANGED
@@ -1,7 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var echarts = require('echarts');
4
5
  var react = require('react');
6
+ var throttle = require('lodash/throttle');
5
7
  var styles = require('@mui/material/styles');
6
8
 
7
9
  /******************************************************************************
@@ -32,17 +34,229 @@ var __assign = function() {
32
34
  return __assign.apply(this, arguments);
33
35
  };
34
36
 
37
+ function __rest(s, e) {
38
+ var t = {};
39
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
40
+ t[p] = s[p];
41
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
42
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
43
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
44
+ t[p[i]] = s[p[i]];
45
+ }
46
+ return t;
47
+ }
48
+
35
49
  function __makeTemplateObject(cooked, raw) {
36
50
  if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
37
51
  return cooked;
38
52
  }
39
53
 
40
- var StyledHeatmap = styles.styled("div")(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n width: 100%;\n height: 100px;\n background-color: #212121;\n display: flex;\n justify-content: center;\n align-items: center;\n color: white;\n font-size: 1rem;\n"], ["\n width: 100%;\n height: 100px;\n background-color: #212121;\n display: flex;\n justify-content: center;\n align-items: center;\n color: white;\n font-size: 1rem;\n"])));
54
+ var EMPTY_OBJECT = {};
55
+
56
+ var DEFAULT_ITEM_STYLE = {
57
+ color: function () {
58
+ return "rgb(0, 0, 0)";
59
+ },
60
+ };
61
+ function createChartOptions(_a) {
62
+ 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
+ var defaultGrid = {
64
+ height: "".concat(height, "px"),
65
+ left: 0,
66
+ top: 0,
67
+ // (atarashansky): this is the key change to align x and y axis
68
+ // labels to fixed spacings
69
+ width: "".concat(width, "px"),
70
+ };
71
+ var customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp;
72
+ return {
73
+ animation: false,
74
+ /**
75
+ * Display reference line and axis value under mouse pointer
76
+ * https://echarts.apache.org/en/option.html#axisPointer
77
+ */
78
+ axisPointer: {
79
+ label: { show: false },
80
+ show: true,
81
+ triggerOn: "mousemove",
82
+ },
83
+ dataset: {
84
+ source: data,
85
+ },
86
+ grid: customGrid || defaultGrid,
87
+ series: [
88
+ {
89
+ emphasis: {
90
+ itemStyle: {
91
+ color: "inherit",
92
+ },
93
+ scale: false,
94
+ },
95
+ encode: encode,
96
+ itemStyle: itemStyle,
97
+ legendHoverLink: false,
98
+ symbolSize: symbolSize,
99
+ type: "scatter",
100
+ },
101
+ ],
102
+ xAxis: [
103
+ {
104
+ axisLabel: { fontSize: 0, rotate: 90 },
105
+ axisLine: {
106
+ show: false,
107
+ },
108
+ axisTick: {
109
+ show: false,
110
+ },
111
+ boundaryGap: true,
112
+ data: xAxisData,
113
+ splitLine: {
114
+ show: false,
115
+ },
116
+ type: "category",
117
+ },
118
+ ],
119
+ yAxis: [
120
+ {
121
+ axisLabel: { fontSize: 0 },
122
+ axisLine: {
123
+ show: false,
124
+ },
125
+ axisTick: {
126
+ show: false,
127
+ },
128
+ boundaryGap: true,
129
+ data: yAxisData,
130
+ splitLine: {
131
+ show: false,
132
+ },
133
+ },
134
+ ],
135
+ };
136
+ }
137
+
138
+ var UPDATE_THROTTLE_MS = 1 * 100;
139
+ function useUpdateChart(_a) {
140
+ 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;
141
+ var throttledUpdateChart = react.useMemo(function () {
142
+ return throttle(function () {
143
+ if (!chart || !data || !xAxisData || !yAxisData) {
144
+ return;
145
+ }
146
+ // (thuang): resize() needs to be called before setOption() to prevent
147
+ // TypeError: Cannot read properties of undefined (reading 'shouldBePainted')
148
+ chart.resize();
149
+ chart.setOption(createChartOptions({
150
+ data: data,
151
+ encode: encode,
152
+ grid: grid,
153
+ height: height,
154
+ itemStyle: itemStyle,
155
+ symbolSize: symbolSize,
156
+ width: width,
157
+ xAxisData: xAxisData,
158
+ yAxisData: yAxisData,
159
+ }));
160
+ }, UPDATE_THROTTLE_MS,
161
+ // (thuang): Trailing guarantees that the last call to the function will
162
+ // be executed
163
+ { trailing: true });
164
+ }, [
165
+ chart,
166
+ data,
167
+ xAxisData,
168
+ yAxisData,
169
+ width,
170
+ height,
171
+ encode,
172
+ itemStyle,
173
+ symbolSize,
174
+ grid,
175
+ ]);
176
+ react.useEffect(function () {
177
+ return function () { return throttledUpdateChart.cancel(); };
178
+ }, [throttledUpdateChart]);
179
+ // Update the charts
180
+ react.useEffect(function () {
181
+ throttledUpdateChart();
182
+ }, [
183
+ chart,
184
+ data,
185
+ xAxisData,
186
+ yAxisData,
187
+ throttledUpdateChart,
188
+ width,
189
+ height,
190
+ encode,
191
+ itemStyle,
192
+ symbolSize,
193
+ grid,
194
+ ]);
195
+ }
196
+
197
+ var ChartContainer = styles.styled("div")(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", "\n"], ["\n ", "\n"])), getWidthAndHeight);
198
+ function getWidthAndHeight(_a) {
199
+ var width = _a.width, height = _a.height;
200
+ return "\n width: ".concat(width, "px;\n height: ").concat(height, "px;\n ");
201
+ }
41
202
  var templateObject_1;
42
203
 
43
- var Heatmap = react.forwardRef(function (props, ref) {
44
- var children = props.children;
45
- return (jsxRuntime.jsx(StyledHeatmap, __assign({ ref: ref }, props, { children: children })));
46
- });
204
+ function HeatmapChart(props, ref) {
205
+ 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"]);
206
+ if (!width || !height) {
207
+ throw Error("Chart must have width and height > 0");
208
+ }
209
+ var _c = react.useState(false), isChartInitialized = _c[0], setIsChartInitialized = _c[1];
210
+ var _d = react.useState(null), chart = _d[0], setChart = _d[1];
211
+ var innerRef = react.useRef(null);
212
+ // Initialize charts
213
+ react.useEffect(function () {
214
+ var current = innerRef.current;
215
+ if (!current ||
216
+ isChartInitialized ||
217
+ // (thuang): echart's `init()` will throw error if the container has 0 width or height
218
+ (current === null || current === void 0 ? void 0 : current.getAttribute("height")) === "0" ||
219
+ (current === null || current === void 0 ? void 0 : current.getAttribute("width")) === "0") {
220
+ return;
221
+ }
222
+ setIsChartInitialized(true);
223
+ var rawChart = echarts.init(current, EMPTY_OBJECT, {
224
+ renderer: echartsRendererMode,
225
+ useDirtyRect: true,
226
+ });
227
+ if (onChartMouseMove) {
228
+ rawChart.getZr().on("mousemove", function (event) {
229
+ onChartMouseMove(event, rawChart);
230
+ });
231
+ }
232
+ setChart(rawChart);
233
+ }, [innerRef, isChartInitialized, echartsRendererMode, onChartMouseMove]);
234
+ useUpdateChart({
235
+ chart: chart,
236
+ data: data,
237
+ encode: encode,
238
+ grid: grid,
239
+ height: height,
240
+ itemStyle: itemStyle,
241
+ symbolSize: symbolSize,
242
+ width: width,
243
+ xAxisData: xAxisData,
244
+ yAxisData: yAxisData,
245
+ });
246
+ return (jsxRuntime.jsx(ChartContainer, __assign({ height: height, width: width, ref: handleRef }, rest)));
247
+ function handleRef(element) {
248
+ innerRef.current = element;
249
+ if (!ref)
250
+ return;
251
+ // (thuang): `ref` from `forwardRef` can be a function or a ref object
252
+ if (typeof ref === "function") {
253
+ ref(element);
254
+ }
255
+ else {
256
+ ref.current = element;
257
+ }
258
+ }
259
+ }
260
+ var index = react.memo(react.forwardRef(HeatmapChart));
47
261
 
48
- exports.Heatmap = Heatmap;
262
+ exports.HeatmapChart = index;
@@ -1,7 +1,91 @@
1
1
  /// <reference types="react" />
2
- import React from "react";
3
- interface HeatmapProps {
4
- children: React.ReactNode;
2
+ import { ECharts, ElementEvent, DatasetComponentOption, EChartsOption, ScatterSeriesOption } from "echarts";
3
+ import { HTMLAttributes } from "react";
4
+ interface CreateChartOptionsProps {
5
+ /**
6
+ * The data array to be visualized
7
+ * The data point object shape can be whatever you like, but it must be consistent with the `encode` option
8
+ * For example, if the data point shape is:
9
+ * {
10
+ * geneIndex: 0,
11
+ * cellTypeIndex: 0,
12
+ * percentage: 0.5
13
+ * }
14
+ * and you want geneIndex to be encoded to x axis and cellTypeIndex to be encoded to y axis, then make sure your encode option is:
15
+ * encode: {
16
+ * x: 'geneIndex',
17
+ * y: 'cellTypeIndex'
18
+ * }
19
+ */
20
+ data: DatasetComponentOption["source"];
21
+ /**
22
+ * The data for the x axis
23
+ * For example:
24
+ * [{ value: "gene1", textStyle: { color: "red" } }, "gene2", "gene3"]
25
+ */
26
+ xAxisData: CategoryAxisData;
27
+ /**
28
+ * The data for the y axis
29
+ * For example:
30
+ * [{ value: "cellType1", textStyle: { color: "red" } }, "cellType2", "cellType3"]
31
+ */
32
+ yAxisData: CategoryAxisData;
33
+ width: number;
34
+ height: number;
35
+ /**
36
+ * Provide a mapping of data key to x/y axis encoding
37
+ * For example, if the data is:
38
+ * {
39
+ * geneIndex: 0,
40
+ * cellTypeIndex: 0,
41
+ * percentage: 0.5
42
+ * }
43
+ * and we want to encode `geneIndex` to x axis and `cellTypeIndex` to y axis, then
44
+ * encode: {
45
+ * x: 'geneIndex',
46
+ * y: 'cellTypeIndex'
47
+ * }
48
+ * https://echarts.apache.org/en/option.html#series-scatter.encode
49
+ */
50
+ encode?: {
51
+ x: string;
52
+ y: string;
53
+ };
54
+ /**
55
+ * Customize the style of each cell item, such as color, border, opacity, etc.
56
+ * https://echarts.apache.org/en/option.html#series-scatter.itemStyle
57
+ */
58
+ itemStyle?: ScatterSeriesOption["itemStyle"];
59
+ /**
60
+ * `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
+ *
62
+ * If size of symbols needs to be different, you can set with callback function in the following format:
63
+ *
64
+ * (value: Array|number, params: Object) => number|Array
65
+ *
66
+ * The first parameter value is the value in data, and the second parameter params is the rest parameters of data item.
67
+ * https://echarts.apache.org/en/option.html#series-scatter.symbolSize
68
+ */
69
+ symbolSize?: ScatterSeriesOption["symbolSize"];
70
+ /**
71
+ * https://echarts.apache.org/en/option.html#grid
72
+ */
73
+ grid?: EChartsOption["grid"] | ((defaultOption: EChartsOption["grid"]) => EChartsOption["grid"]);
5
74
  }
6
- declare const Heatmap: React.ForwardRefExoticComponent<HeatmapProps & React.RefAttributes<HTMLTableElement>>;
7
- export { HeatmapProps, Heatmap };
75
+ type OrdinalRawValue = string | number;
76
+ /**
77
+ * (thuang): This copies echarts' CategoryAxisBaseOption["data"] type, since it's not exported
78
+ */
79
+ type CategoryAxisData = (OrdinalRawValue | {
80
+ value: OrdinalRawValue;
81
+ /**
82
+ * (thuang): This should be echarts `TextCommonOption` type, but it's not exported
83
+ */
84
+ textStyle?: never;
85
+ })[];
86
+ interface HeatmapChartProps extends HTMLAttributes<HTMLDivElement>, CreateChartOptionsProps {
87
+ echartsRendererMode?: "svg" | "canvas";
88
+ onChartMouseMove?: (event: ElementEvent, chart: ECharts) => void;
89
+ }
90
+ declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<HeatmapChartProps & import("react").RefAttributes<HTMLDivElement>>>;
91
+ export { HeatmapChartProps, _default, _default as HeatmapChart };
package/dist/index.esm.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { forwardRef } from 'react';
2
+ import { init } from 'echarts';
3
+ import { useMemo, useEffect, memo, forwardRef, useState, useRef } from 'react';
4
+ import throttle from 'lodash/throttle';
3
5
  import { styled } from '@mui/material/styles';
4
6
 
5
7
  /******************************************************************************
@@ -30,17 +32,229 @@ var __assign = function() {
30
32
  return __assign.apply(this, arguments);
31
33
  };
32
34
 
35
+ function __rest(s, e) {
36
+ var t = {};
37
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
38
+ t[p] = s[p];
39
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
40
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
41
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
42
+ t[p[i]] = s[p[i]];
43
+ }
44
+ return t;
45
+ }
46
+
33
47
  function __makeTemplateObject(cooked, raw) {
34
48
  if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
35
49
  return cooked;
36
50
  }
37
51
 
38
- var StyledHeatmap = styled("div")(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n width: 100%;\n height: 100px;\n background-color: #212121;\n display: flex;\n justify-content: center;\n align-items: center;\n color: white;\n font-size: 1rem;\n"], ["\n width: 100%;\n height: 100px;\n background-color: #212121;\n display: flex;\n justify-content: center;\n align-items: center;\n color: white;\n font-size: 1rem;\n"])));
52
+ var EMPTY_OBJECT = {};
53
+
54
+ var DEFAULT_ITEM_STYLE = {
55
+ color: function () {
56
+ return "rgb(0, 0, 0)";
57
+ },
58
+ };
59
+ function createChartOptions(_a) {
60
+ 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;
61
+ var defaultGrid = {
62
+ height: "".concat(height, "px"),
63
+ left: 0,
64
+ top: 0,
65
+ // (atarashansky): this is the key change to align x and y axis
66
+ // labels to fixed spacings
67
+ width: "".concat(width, "px"),
68
+ };
69
+ var customGrid = typeof gridProp === "function" ? gridProp(defaultGrid) : gridProp;
70
+ return {
71
+ animation: false,
72
+ /**
73
+ * Display reference line and axis value under mouse pointer
74
+ * https://echarts.apache.org/en/option.html#axisPointer
75
+ */
76
+ axisPointer: {
77
+ label: { show: false },
78
+ show: true,
79
+ triggerOn: "mousemove",
80
+ },
81
+ dataset: {
82
+ source: data,
83
+ },
84
+ grid: customGrid || defaultGrid,
85
+ series: [
86
+ {
87
+ emphasis: {
88
+ itemStyle: {
89
+ color: "inherit",
90
+ },
91
+ scale: false,
92
+ },
93
+ encode: encode,
94
+ itemStyle: itemStyle,
95
+ legendHoverLink: false,
96
+ symbolSize: symbolSize,
97
+ type: "scatter",
98
+ },
99
+ ],
100
+ xAxis: [
101
+ {
102
+ axisLabel: { fontSize: 0, rotate: 90 },
103
+ axisLine: {
104
+ show: false,
105
+ },
106
+ axisTick: {
107
+ show: false,
108
+ },
109
+ boundaryGap: true,
110
+ data: xAxisData,
111
+ splitLine: {
112
+ show: false,
113
+ },
114
+ type: "category",
115
+ },
116
+ ],
117
+ yAxis: [
118
+ {
119
+ axisLabel: { fontSize: 0 },
120
+ axisLine: {
121
+ show: false,
122
+ },
123
+ axisTick: {
124
+ show: false,
125
+ },
126
+ boundaryGap: true,
127
+ data: yAxisData,
128
+ splitLine: {
129
+ show: false,
130
+ },
131
+ },
132
+ ],
133
+ };
134
+ }
135
+
136
+ var UPDATE_THROTTLE_MS = 1 * 100;
137
+ function useUpdateChart(_a) {
138
+ 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;
139
+ var throttledUpdateChart = useMemo(function () {
140
+ return throttle(function () {
141
+ if (!chart || !data || !xAxisData || !yAxisData) {
142
+ return;
143
+ }
144
+ // (thuang): resize() needs to be called before setOption() to prevent
145
+ // TypeError: Cannot read properties of undefined (reading 'shouldBePainted')
146
+ chart.resize();
147
+ chart.setOption(createChartOptions({
148
+ data: data,
149
+ encode: encode,
150
+ grid: grid,
151
+ height: height,
152
+ itemStyle: itemStyle,
153
+ symbolSize: symbolSize,
154
+ width: width,
155
+ xAxisData: xAxisData,
156
+ yAxisData: yAxisData,
157
+ }));
158
+ }, UPDATE_THROTTLE_MS,
159
+ // (thuang): Trailing guarantees that the last call to the function will
160
+ // be executed
161
+ { trailing: true });
162
+ }, [
163
+ chart,
164
+ data,
165
+ xAxisData,
166
+ yAxisData,
167
+ width,
168
+ height,
169
+ encode,
170
+ itemStyle,
171
+ symbolSize,
172
+ grid,
173
+ ]);
174
+ useEffect(function () {
175
+ return function () { return throttledUpdateChart.cancel(); };
176
+ }, [throttledUpdateChart]);
177
+ // Update the charts
178
+ useEffect(function () {
179
+ throttledUpdateChart();
180
+ }, [
181
+ chart,
182
+ data,
183
+ xAxisData,
184
+ yAxisData,
185
+ throttledUpdateChart,
186
+ width,
187
+ height,
188
+ encode,
189
+ itemStyle,
190
+ symbolSize,
191
+ grid,
192
+ ]);
193
+ }
194
+
195
+ var ChartContainer = styled("div")(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", "\n"], ["\n ", "\n"])), getWidthAndHeight);
196
+ function getWidthAndHeight(_a) {
197
+ var width = _a.width, height = _a.height;
198
+ return "\n width: ".concat(width, "px;\n height: ").concat(height, "px;\n ");
199
+ }
39
200
  var templateObject_1;
40
201
 
41
- var Heatmap = forwardRef(function (props, ref) {
42
- var children = props.children;
43
- return (jsx(StyledHeatmap, __assign({ ref: ref }, props, { children: children })));
44
- });
202
+ function HeatmapChart(props, ref) {
203
+ 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"]);
204
+ if (!width || !height) {
205
+ throw Error("Chart must have width and height > 0");
206
+ }
207
+ var _c = useState(false), isChartInitialized = _c[0], setIsChartInitialized = _c[1];
208
+ var _d = useState(null), chart = _d[0], setChart = _d[1];
209
+ var innerRef = useRef(null);
210
+ // Initialize charts
211
+ useEffect(function () {
212
+ var current = innerRef.current;
213
+ if (!current ||
214
+ isChartInitialized ||
215
+ // (thuang): echart's `init()` will throw error if the container has 0 width or height
216
+ (current === null || current === void 0 ? void 0 : current.getAttribute("height")) === "0" ||
217
+ (current === null || current === void 0 ? void 0 : current.getAttribute("width")) === "0") {
218
+ return;
219
+ }
220
+ setIsChartInitialized(true);
221
+ var rawChart = init(current, EMPTY_OBJECT, {
222
+ renderer: echartsRendererMode,
223
+ useDirtyRect: true,
224
+ });
225
+ if (onChartMouseMove) {
226
+ rawChart.getZr().on("mousemove", function (event) {
227
+ onChartMouseMove(event, rawChart);
228
+ });
229
+ }
230
+ setChart(rawChart);
231
+ }, [innerRef, isChartInitialized, echartsRendererMode, onChartMouseMove]);
232
+ useUpdateChart({
233
+ chart: chart,
234
+ data: data,
235
+ encode: encode,
236
+ grid: grid,
237
+ height: height,
238
+ itemStyle: itemStyle,
239
+ symbolSize: symbolSize,
240
+ width: width,
241
+ xAxisData: xAxisData,
242
+ yAxisData: yAxisData,
243
+ });
244
+ return (jsx(ChartContainer, __assign({ height: height, width: width, ref: handleRef }, rest)));
245
+ function handleRef(element) {
246
+ innerRef.current = element;
247
+ if (!ref)
248
+ return;
249
+ // (thuang): `ref` from `forwardRef` can be a function or a ref object
250
+ if (typeof ref === "function") {
251
+ ref(element);
252
+ }
253
+ else {
254
+ ref.current = element;
255
+ }
256
+ }
257
+ }
258
+ var index = memo(forwardRef(HeatmapChart));
45
259
 
46
- export { Heatmap };
260
+ export { index as HeatmapChart };