@easyv/charts 1.4.21 → 1.4.24

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.
Files changed (90) hide show
  1. package/.babelrc +8 -8
  2. package/.husky/commit-msg +3 -3
  3. package/CHANGELOG.md +18 -18
  4. package/commitlint.config.js +1 -1
  5. package/lib/components/AnimateData.js +8 -16
  6. package/lib/components/Axis.js +106 -138
  7. package/lib/components/Background.js +18 -26
  8. package/lib/components/Band.js +105 -91
  9. package/lib/components/BaseLine.js +33 -46
  10. package/lib/components/Brush.js +29 -46
  11. package/lib/components/Carousel.js +13 -40
  12. package/lib/components/CartesianChart.js +292 -113
  13. package/lib/components/Chart.js +23 -36
  14. package/lib/components/ChartContainer.js +21 -29
  15. package/lib/components/ConicalGradient.js +56 -89
  16. package/lib/components/Control.js +65 -0
  17. package/lib/components/ExtentData.js +9 -17
  18. package/lib/components/FilterData.js +16 -27
  19. package/lib/components/Indicator.js +66 -12
  20. package/lib/components/Label.js +128 -118
  21. package/lib/components/Legend.js +41 -66
  22. package/lib/components/Lighter.js +21 -50
  23. package/lib/components/Line.js +39 -59
  24. package/lib/components/LinearGradient.js +16 -22
  25. package/lib/components/Mapping.js +9 -34
  26. package/lib/components/Marquee.js +14 -30
  27. package/lib/components/PieChart.js +312 -406
  28. package/lib/components/StackData.js +8 -18
  29. package/lib/components/StereoBar.js +65 -105
  30. package/lib/components/TextOverflow.js +8 -21
  31. package/lib/components/Tooltip.js +41 -55
  32. package/lib/components/index.js +7 -27
  33. package/lib/context/index.js +0 -2
  34. package/lib/css/index.module.css +42 -42
  35. package/lib/css/piechart.module.css +26 -26
  36. package/lib/element/ConicGradient.js +29 -35
  37. package/lib/element/Line.js +9 -13
  38. package/lib/element/index.js +0 -2
  39. package/lib/formatter/index.js +0 -2
  40. package/lib/formatter/legend.js +30 -41
  41. package/lib/hooks/index.js +0 -9
  42. package/lib/hooks/useAiData.js +12 -20
  43. package/lib/hooks/useAnimateData.js +8 -21
  44. package/lib/hooks/useAxes.js +69 -115
  45. package/lib/hooks/useCarouselAxisX.js +47 -68
  46. package/lib/hooks/useExtentData.js +14 -46
  47. package/lib/hooks/useFilterData.js +13 -34
  48. package/lib/hooks/useStackData.js +12 -35
  49. package/lib/hooks/useTooltip.js +37 -54
  50. package/lib/index.js +0 -15
  51. package/lib/utils/index.js +95 -247
  52. package/package.json +55 -55
  53. package/src/components/Axis.tsx +223 -183
  54. package/src/components/Background.tsx +61 -61
  55. package/src/components/Band.tsx +274 -239
  56. package/src/components/Brush.js +159 -159
  57. package/src/components/CartesianChart.js +320 -44
  58. package/src/components/Chart.js +99 -99
  59. package/src/components/ChartContainer.tsx +71 -64
  60. package/src/components/ConicalGradient.js +258 -258
  61. package/src/components/Control.jsx +51 -0
  62. package/src/components/ExtentData.js +17 -17
  63. package/src/components/Indicator.js +61 -13
  64. package/src/components/Label.js +275 -242
  65. package/src/components/Legend.js +165 -165
  66. package/src/components/Lighter.jsx +173 -173
  67. package/src/components/Line.js +150 -150
  68. package/src/components/LinearGradient.js +29 -29
  69. package/src/components/PieChart.js +8 -4
  70. package/src/components/StereoBar.tsx +307 -307
  71. package/src/components/index.js +57 -55
  72. package/src/context/index.js +2 -2
  73. package/src/css/index.module.css +42 -42
  74. package/src/css/piechart.module.css +26 -26
  75. package/src/element/ConicGradient.jsx +55 -55
  76. package/src/element/Line.tsx +33 -33
  77. package/src/element/index.ts +3 -3
  78. package/src/formatter/index.js +1 -1
  79. package/src/formatter/legend.js +92 -92
  80. package/src/hooks/index.js +20 -20
  81. package/src/hooks/useAnimateData.ts +67 -67
  82. package/src/hooks/useAxes.js +9 -2
  83. package/src/hooks/useCarouselAxisX.js +35 -18
  84. package/src/hooks/useFilterData.js +72 -72
  85. package/src/hooks/useStackData.js +101 -101
  86. package/src/hooks/useTooltip.ts +100 -100
  87. package/src/index.js +6 -6
  88. package/src/types/index.d.ts +67 -67
  89. package/src/utils/index.js +757 -757
  90. package/tsconfig.json +23 -23
@@ -8,10 +8,11 @@ import React, {
8
8
  useRef,
9
9
  useContext,
10
10
  useCallback,
11
- useEffect
12
- } from 'react';
13
- import { useAxes, useTooltip, useCarouselAxisX, useAiData } from '../hooks';
14
- import { chartContext } from '../context';
11
+ useEffect,
12
+ forwardRef,
13
+ } from "react";
14
+ import { useAxes, useTooltip, useCarouselAxisX,useAiData } from "../hooks";
15
+ import { chartContext } from "../context";
15
16
  import {
16
17
  ChartContainer,
17
18
  Legend,
@@ -27,7 +28,9 @@ import {
27
28
  Label,
28
29
  Mapping,
29
30
  BaseLine,
30
- } from '.';
31
+ Control,
32
+ } from ".";
33
+ import { getMousePos } from "../utils";
31
34
 
32
35
  const Chart = memo(
33
36
  ({
@@ -46,7 +49,7 @@ const Chart = memo(
46
49
  bandLength,
47
50
  tooltip,
48
51
  baseLine: {
49
- orientation: baseLineOri = '',
52
+ orientation: baseLineOri = "",
50
53
  config: baseLineConfig = {},
51
54
  data: baseLineData = [],
52
55
  },
@@ -54,7 +57,9 @@ const Chart = memo(
54
57
  config: tooltipConfig = {},
55
58
  config: { auto, manual, indicator = {} } = {},
56
59
  } = {},
57
- brush
60
+ brush,
61
+ isControlChart = false,
62
+ control = null,
58
63
  },
59
64
  style,
60
65
  originData,
@@ -71,11 +76,22 @@ const Chart = memo(
71
76
  onEmit,
72
77
  } = useContext(chartContext);
73
78
  const svg = useRef();
74
- const axes = useAxes({ axes: axesConfig, context });
79
+ const axes = useAxes({
80
+ axes: axesConfig,
81
+ context,
82
+ isControlChart,
83
+ control,
84
+ });
75
85
  const aiData = aiFormatter?aiFormatter(originData, axes, series):useAiData(originData, axes, series);
76
- const axisX = useCarouselAxisX(axes.get('x'), animation, isHover);
77
- const xLineRange = width-marginLeft-marginRight;
78
- const yLineRange = height-marginTop-marginBottom;
86
+ const axisX = useCarouselAxisX(
87
+ axes.get("x"),
88
+ animation,
89
+ isHover,
90
+ isControlChart,
91
+ control
92
+ );
93
+ const xLineRange = width - marginLeft - marginRight;
94
+ const yLineRange = height - marginTop - marginBottom;
79
95
 
80
96
  useEffect(()=>{
81
97
  if(aiData.length){
@@ -89,7 +105,7 @@ const Chart = memo(
89
105
  }
90
106
  }
91
107
  return ()=>{
92
- delete window.aiData[id];
108
+ window.aiData && window.aiData[id] && delete window.aiData[id];
93
109
  }
94
110
  },[JSON.stringify(aiData),id]);
95
111
 
@@ -108,7 +124,8 @@ const Chart = memo(
108
124
  config: tooltipConfig,
109
125
  });
110
126
  const tooltipData = useMemo(
111
- () => tickName !== undefined && originData.filter((d) => d.x === tickName),
127
+ () =>
128
+ tickName !== undefined && originData.filter((d) => d.x === tickName),
112
129
  [tickName, originData]
113
130
  );
114
131
 
@@ -118,7 +135,7 @@ const Chart = memo(
118
135
  (auto || manual)
119
136
  );
120
137
 
121
- const isVertical = axisX.direction === 'vertical';
138
+ const isVertical = axisX.direction === "vertical";
122
139
 
123
140
  const indicatorWidth = (indicator.width * axisX.step) / 100;
124
141
  const position = axisX.scaler(tickName) - indicatorWidth / 2;
@@ -136,11 +153,160 @@ const Chart = memo(
136
153
  const { data } = e.currentTarget.dataset;
137
154
  const _data = JSON.parse(data);
138
155
  triggerOnRelative(_data);
139
- onEmit('click', _data);
156
+ onEmit("click", _data);
140
157
  },
141
158
  [triggerOnRelative, onEmit]
142
159
  );
143
-
160
+
161
+ /**
162
+ * 控制图相关
163
+ */
164
+ const controlEl = useRef();
165
+ const seriesEl = useRef(null);
166
+ const axisElList = useRef([]);
167
+ const curControlPercent = useRef(0);
168
+ useEffect(() => {
169
+ if (controlEl.current && isControlChart) {
170
+ let isDragging = false;
171
+ let movementX = 0;
172
+ let rawTranslateX = 0;
173
+ let percent = 0;
174
+ const controlWidth = (xLineRange * control.drag.width) / 100;
175
+ const range = (num) => {
176
+ let _num = num;
177
+ const min = 0;
178
+ const max = xLineRange - controlWidth;
179
+ _num = Math.max(_num, min);
180
+ _num = Math.min(_num, max);
181
+ return _num;
182
+ };
183
+ const setControlTranslate = (x) => {
184
+ const moveLen = range(x);
185
+ controlEl.current.style.transform = `translateX(${moveLen}px)`;
186
+ //计算出当前位移的百分比
187
+ percent = moveLen / (xLineRange - controlWidth);
188
+ curControlPercent.current = percent;
189
+ seriesEl.current.style.transform = `translate(${
190
+ -(axisX.controlEnd - axisX.end) * percent
191
+ }px,${marginTop}px)`;
192
+ axisElList.current[2].style.transform = `translate(${
193
+ -(axisX.controlEnd - axisX.end) * percent
194
+ }px,${0}px)`;
195
+ };
196
+ const mouseDownHandle = (e) => {
197
+ const mouseMoveHandle = (e) => {
198
+ //当前位移的距离
199
+ if (isDragging) {
200
+ movementX += e.movementX;
201
+ setControlTranslate(movementX + rawTranslateX);
202
+ }
203
+ };
204
+ const mouseUpHandle = (e) => {
205
+ rawTranslateX = range(movementX + rawTranslateX);
206
+ movementX = 0;
207
+ isDragging = false;
208
+ document.removeEventListener("mousemove", mouseMoveHandle);
209
+ document.removeEventListener("mouseup", mouseUpHandle);
210
+ };
211
+ document.addEventListener("mousemove", mouseMoveHandle);
212
+ document.addEventListener("mouseup", mouseUpHandle);
213
+ isDragging = true;
214
+ };
215
+
216
+ let animationHoverStop;
217
+ const setAnimationHoverStopTrue = () => {
218
+ animationHoverStop = true;
219
+ };
220
+ const setAnimationHoverStopFalse = () => {
221
+ animationHoverStop = false;
222
+ };
223
+ svg.current.addEventListener("mouseenter", setAnimationHoverStopTrue);
224
+ svg.current.addEventListener("mouseleave", setAnimationHoverStopFalse);
225
+
226
+ //控制图轮播动画逻辑
227
+ const { show, duration, interval, hover } = animation;
228
+ const times = Math.floor(xLineRange / controlWidth);
229
+ let animatePos = [];
230
+ for (let i = 0; i <= times; i++) {
231
+ if (i * controlWidth <= xLineRange) {
232
+ animatePos.push(i * controlWidth);
233
+ } else {
234
+ animatePos.push(xLineRange - controlWidth);
235
+ }
236
+ }
237
+ let index = 0;
238
+ let animationId;
239
+ if (animation.show) {
240
+ let initTime, timeGap;
241
+ const animation = (timestamp) => {
242
+ if (!initTime) {
243
+ initTime = timestamp;
244
+ }
245
+ if (animationHoverStop && hover) {
246
+ initTime = timestamp - timeGap;
247
+ }
248
+ timeGap = timestamp - initTime;
249
+ if (timeGap < (interval + duration) * 1000) {
250
+ if (timeGap < duration * 1000) {
251
+ const p = timeGap / (duration * 1000);
252
+ let nextIndex = index + 1;
253
+ let v;
254
+ if (nextIndex < animatePos.length) {
255
+ v =
256
+ p * (animatePos[nextIndex] - animatePos[index]) +
257
+ animatePos[index];
258
+ } else {
259
+ nextIndex = 0;
260
+ v = (1 - p) * animatePos[index];
261
+ }
262
+ setControlTranslate(v);
263
+ }
264
+ animationId = window.requestAnimationFrame(animation);
265
+ } else {
266
+ index = index < times ? index + 1 : 0;
267
+ initTime = 0;
268
+ animationId = window.requestAnimationFrame(animation);
269
+ }
270
+ };
271
+ animationId = window.requestAnimationFrame(animation);
272
+ }
273
+ controlEl.current.addEventListener("mousedown", mouseDownHandle);
274
+
275
+ return () => {
276
+ controlEl.current.removeEventListener("mousedown", mouseDownHandle);
277
+ svg.current.removeEventListener(
278
+ "mouseenter",
279
+ setAnimationHoverStopTrue
280
+ );
281
+ svg.current.removeEventListener(
282
+ "mouseleave",
283
+ setAnimationHoverStopFalse
284
+ );
285
+
286
+ window.cancelAnimationFrame(animationId);
287
+ };
288
+ }
289
+ }, [JSON.stringify(animation), control]);
290
+
291
+ const [controlChartTooltipShow, setControlChartTooltipShow] =
292
+ useState(false);
293
+ const [controlChartTooltipXName, setControlChartTooltipXName] =
294
+ useState(undefined);
295
+ const [controlChartTooltipX, setControlChartTooltipX] = useState(undefined);
296
+ const controlChartTooltipData = useMemo(
297
+ () =>
298
+ controlChartTooltipXName !== undefined &&
299
+ originData.filter((d) => d.x === controlChartTooltipXName),
300
+ [controlChartTooltipXName, originData]
301
+ );
302
+ const [controlChartIndicatorList, setControlChartIndicatorList] = useState(
303
+ axisX.ticks.map((tick) => {
304
+ return {
305
+ tick: tick,
306
+ isShow: false,
307
+ };
308
+ })
309
+ );
144
310
  return (
145
311
  <>
146
312
  <ChartContainer
@@ -149,16 +315,22 @@ const Chart = memo(
149
315
  height={height}
150
316
  marginLeft={marginLeft}
151
317
  marginTop={marginTop}
152
- onMouseEnter={()=>{setIsHover(true)}}
153
- onMouseMove={setIndex}
154
- onMouseLeave={(e)=>{setIsHover(false);setIndex(e)}}
318
+ onMouseEnter={() => {
319
+ setIsHover(true);
320
+ }}
321
+ onMouseLeave={(e) => {
322
+ setIsHover(false);
323
+ setIndex(e);
324
+ }}
155
325
  ref={svg}
156
326
  >
157
327
  {background && (
158
- <foreignObject style={{
159
- width:xLineRange,
160
- height:yLineRange
161
- }}>
328
+ <foreignObject
329
+ style={{
330
+ width: xLineRange,
331
+ height: yLineRange,
332
+ }}
333
+ >
162
334
  <svg width="100%" height="100%">
163
335
  <Background
164
336
  length={isVertical ? chartWidth : chartHeight}
@@ -169,19 +341,100 @@ const Chart = memo(
169
341
  </svg>
170
342
  </foreignObject>
171
343
  )}
172
- {showTooltip && <Indicator {...indicator} {...indicatorAttr} />}
173
- <foreignObject style={isVertical?{
174
- width:xLineRange+marginRight+marginLeft,
175
- height:yLineRange,
176
- transform:`translateX(${-marginRight}px)`,
177
- }:{
178
- width:xLineRange,
179
- height:yLineRange+marginTop+marginBottom,
180
- transform:`translateY(${-marginTop}px)`,
181
- // overflow:'visible'
182
- // paddingTop:marginTop
183
- }}>
184
- <svg width="100%" height="100%" style={{overflow:"visible",transform:isVertical?`translateX(${marginRight}px)`:`translateY(${marginTop}px)`}}>
344
+ {[...axes.values()].reverse().map((item, index) => {
345
+ const config = item.axisType == "x" ? axisX : item;
346
+
347
+ return (
348
+ <Axis
349
+ ref={(d) => {
350
+ axisElList.current[index] = d;
351
+ }}
352
+ triggerClick={onInteraction}
353
+ xLineRange={xLineRange}
354
+ yLineRange={yLineRange}
355
+ isControlChart={isControlChart}
356
+ controlConfig={control}
357
+ {...config}
358
+ key={index}
359
+ />
360
+ );
361
+ })}
362
+ {/* 控制条逻辑 */}
363
+ {isControlChart && control && (
364
+ <Control
365
+ ref={controlEl}
366
+ props={{
367
+ control,
368
+ axes,
369
+ series,
370
+ xLineRange,
371
+ yLineRange,
372
+ marginTop,
373
+ axisX,
374
+ bandLength,
375
+ }}
376
+ ></Control>
377
+ )}
378
+ {showTooltip && !isControlChart && (
379
+ <Indicator {...indicator} {...indicatorAttr} />
380
+ )}
381
+
382
+ <foreignObject
383
+ style={
384
+ isVertical
385
+ ? {
386
+ width: xLineRange + marginRight + marginLeft,
387
+ height: yLineRange,
388
+ transform: `translateX(${-marginRight}px)`,
389
+ }
390
+ : {
391
+ width: xLineRange,
392
+ height: yLineRange + marginTop + marginBottom,
393
+ transform: `translateY(${-marginTop}px)`,
394
+ }
395
+ }
396
+ >
397
+ <svg
398
+ width="100%"
399
+ height="100%"
400
+ ref={seriesEl}
401
+ style={{
402
+ overflow: "visible",
403
+ transform: isVertical
404
+ ? `translateX(${marginRight}px)`
405
+ : `translateY(${marginTop}px)`,
406
+ }}
407
+ >
408
+ {/* 控制图指示器部分 */}
409
+ <g>
410
+ {isControlChart &&
411
+ controlChartIndicatorList.map((item, index) => {
412
+ const x = axisX.scaler(item.tick);
413
+ return (
414
+ <Indicator
415
+ key={index}
416
+ {...indicator}
417
+ {...{
418
+ height: chartHeight,
419
+ width: indicatorWidth,
420
+ x: x - indicatorWidth / 2,
421
+ }}
422
+ isControlChart={isControlChart}
423
+ xName={item.tick}
424
+ setControlChartTooltipXName={
425
+ setControlChartTooltipXName
426
+ }
427
+ setControlChartTooltipX={setControlChartTooltipX}
428
+ setControlChartTooltipShow={setControlChartTooltipShow}
429
+ controlChartIndicatorList={controlChartIndicatorList}
430
+ setControlChartIndicatorList={
431
+ setControlChartIndicatorList
432
+ }
433
+ />
434
+ );
435
+ })}
436
+ </g>
437
+
185
438
  {series.map(({ Component, yOrZ, ...config }, index) => {
186
439
  const yAxis = axes.get(yOrZ);
187
440
  return (
@@ -193,11 +446,21 @@ const Chart = memo(
193
446
  bandLength={bandLength}
194
447
  xAxis={axisX}
195
448
  yAxis={yAxis}
449
+ // 控制图部分,主要是为了,当鼠标悬浮在指示器上时,显示对应的tooltip
450
+ isControlChart={isControlChart}
451
+ setControlChartTooltipXName={setControlChartTooltipXName}
452
+ setControlChartTooltipX={setControlChartTooltipX}
453
+ setControlChartTooltipShow={setControlChartTooltipShow}
454
+ indicatorWidth={indicatorWidth}
196
455
  triggerClick={onInteraction}
456
+ setControlChartIndicatorList={
457
+ setControlChartIndicatorList
458
+ }
197
459
  />
198
460
  )
199
461
  );
200
- })}
462
+ })}
463
+
201
464
  {series.map(({ Component, yOrZ, ...config }, index) => {
202
465
  const yAxis = axes.get(yOrZ);
203
466
  return (
@@ -215,12 +478,7 @@ const Chart = memo(
215
478
  })}
216
479
  </svg>
217
480
  </foreignObject>
218
- {[...axes.values()].reverse().map((item, index) => {
219
- const config = item.axisType == 'x' ? axisX : item;
220
- return (
221
- <Axis triggerClick={onInteraction} xLineRange={xLineRange} yLineRange={yLineRange} {...config} key={index} />
222
- );
223
- })}
481
+
224
482
  {baseLineData &&
225
483
  baseLineData.length > 0 &&
226
484
  baseLineData.map((item, index) => {
@@ -246,7 +504,7 @@ const Chart = memo(
246
504
  })}
247
505
  </ChartContainer>
248
506
  <Legend {...legend} filterData={filterData} series={series} />
249
- {showTooltip && (
507
+ {showTooltip && !isControlChart && (
250
508
  <Tooltip
251
509
  isVertical={isVertical}
252
510
  {...tooltip}
@@ -260,6 +518,24 @@ const Chart = memo(
260
518
  height={height}
261
519
  />
262
520
  )}
521
+
522
+ {controlChartTooltipShow && isControlChart && (
523
+ <Tooltip
524
+ isVertical={isVertical}
525
+ {...tooltip}
526
+ data={controlChartTooltipData}
527
+ x={
528
+ controlChartTooltipX -
529
+ (axisX.controlEnd - axisX.end) * curControlPercent.current
530
+ }
531
+ marginLeft={marginLeft}
532
+ marginTop={marginTop}
533
+ tickName={controlChartTooltipXName}
534
+ series={series}
535
+ width={width}
536
+ height={height}
537
+ />
538
+ )}
263
539
  {brush && <Brush config={brush} width={width} />}
264
540
  </>
265
541
  );
@@ -1,99 +1,99 @@
1
- /**
2
- * 总入口,通过外面传进来的type来确定渲染哪种图表,饼环图表为“pie”,否则为轴类图表
3
- */
4
- import React, { memo, useMemo, createRef, useCallback } from 'react';
5
- import { chartContext } from '../context';
6
- import { PieChart, CartesianChart } from '.';
7
-
8
- const getCallbackData = (callbacks, data) => {
9
- let callbackData;
10
- if (callbacks && Array.isArray(callbacks) && callbacks.length && data) {
11
- callbackData = {};
12
- callbacks.forEach(({ origin, target }) => {
13
- callbackData[target] = data[origin];
14
- });
15
- }
16
- return callbackData;
17
- };
18
-
19
- const Chart = memo(
20
- ({
21
- id,
22
- type,
23
- config,
24
- config: {
25
- chart: {
26
- dimension: {
27
- chartDimension: { height, width },
28
- },
29
- margin: { marginRight, marginLeft, marginBottom, marginTop },
30
- },
31
- interaction,
32
- },
33
- data,
34
- onRelative,
35
- emit,
36
- emitEvent,
37
- ...props
38
- }) => {
39
- const svg = createRef();
40
- const chartWidth = width - marginLeft - marginRight;
41
- const chartHeight = height - marginTop - marginBottom;
42
-
43
- const triggerOnRelative = useCallback(
44
- (data) => {
45
- if (!interaction) return;
46
- const { callbacks, remoteControls } = interaction;
47
- const callbackData = getCallbackData(callbacks, data);
48
- if (callbackData) {
49
- onRelative && onRelative(id, callbackData);
50
- remoteControls &&
51
- emitEvent &&
52
- remoteControls.forEach((o) => {
53
- const control = JSON.parse(o.control);
54
- if (
55
- control.screen &&
56
- control.type &&
57
- control.type === 'callback'
58
- ) {
59
- emitEvent({
60
- screen: control.screen,
61
- type: 'callback',
62
- callbackData,
63
- });
64
- }
65
- });
66
- }
67
- },
68
- [ JSON.stringify(interaction)]
69
- );
70
-
71
- const onEmit = useCallback(
72
- (type = 'click', data) => emit && emit(type, data),
73
- [emit]
74
- );
75
-
76
- const context = useMemo(
77
- () => ({
78
- id,
79
- width: chartWidth,
80
- height: chartHeight,
81
- triggerOnRelative,
82
- svg,
83
- onEmit,
84
- }),
85
- [id, chartWidth, chartHeight, triggerOnRelative, svg, onEmit]
86
- );
87
- return (
88
- <chartContext.Provider value={context}>
89
- {type == 'pie' ? (
90
- <PieChart id={id} config={config} data={data} {...props} />
91
- ) : (
92
- <CartesianChart id={id} config={config} data={data} {...props} />
93
- )}
94
- </chartContext.Provider>
95
- );
96
- }
97
- );
98
-
99
- export default Chart;
1
+ /**
2
+ * 总入口,通过外面传进来的type来确定渲染哪种图表,饼环图表为“pie”,否则为轴类图表
3
+ */
4
+ import React, { memo, useMemo, createRef, useCallback } from 'react';
5
+ import { chartContext } from '../context';
6
+ import { PieChart, CartesianChart } from '.';
7
+
8
+ const getCallbackData = (callbacks, data) => {
9
+ let callbackData;
10
+ if (callbacks && Array.isArray(callbacks) && callbacks.length && data) {
11
+ callbackData = {};
12
+ callbacks.forEach(({ origin, target }) => {
13
+ callbackData[target] = data[origin];
14
+ });
15
+ }
16
+ return callbackData;
17
+ };
18
+
19
+ const Chart = memo(
20
+ ({
21
+ id,
22
+ type,
23
+ config,
24
+ config: {
25
+ chart: {
26
+ dimension: {
27
+ chartDimension: { height, width },
28
+ },
29
+ margin: { marginRight, marginLeft, marginBottom, marginTop },
30
+ },
31
+ interaction,
32
+ },
33
+ data,
34
+ onRelative,
35
+ emit,
36
+ emitEvent,
37
+ ...props
38
+ }) => {
39
+ const svg = createRef();
40
+ const chartWidth = width - marginLeft - marginRight;
41
+ const chartHeight = height - marginTop - marginBottom;
42
+
43
+ const triggerOnRelative = useCallback(
44
+ (data) => {
45
+ if (!interaction) return;
46
+ const { callbacks, remoteControls } = interaction;
47
+ const callbackData = getCallbackData(callbacks, data);
48
+ if (callbackData) {
49
+ onRelative && onRelative(id, callbackData);
50
+ remoteControls &&
51
+ emitEvent &&
52
+ remoteControls.forEach((o) => {
53
+ const control = JSON.parse(o.control);
54
+ if (
55
+ control.screen &&
56
+ control.type &&
57
+ control.type === 'callback'
58
+ ) {
59
+ emitEvent({
60
+ screen: control.screen,
61
+ type: 'callback',
62
+ callbackData,
63
+ });
64
+ }
65
+ });
66
+ }
67
+ },
68
+ [ JSON.stringify(interaction)]
69
+ );
70
+
71
+ const onEmit = useCallback(
72
+ (type = 'click', data) => emit && emit(type, data),
73
+ [emit]
74
+ );
75
+
76
+ const context = useMemo(
77
+ () => ({
78
+ id,
79
+ width: chartWidth,
80
+ height: chartHeight,
81
+ triggerOnRelative,
82
+ svg,
83
+ onEmit,
84
+ }),
85
+ [id, chartWidth, chartHeight, triggerOnRelative, svg, onEmit]
86
+ );
87
+ return (
88
+ <chartContext.Provider value={context}>
89
+ {type == 'pie' ? (
90
+ <PieChart id={id} config={config} data={data} {...props} />
91
+ ) : (
92
+ <CartesianChart id={id} config={config} data={data} {...props} />
93
+ )}
94
+ </chartContext.Provider>
95
+ );
96
+ }
97
+ );
98
+
99
+ export default Chart;