@easyv/charts 1.8.24 → 1.8.25

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,18 +1,26 @@
1
1
  /**
2
2
  * 总入口,通过外面传进来的type来确定渲染哪种图表,饼环图表为“pie”,否则为轴类图表
3
3
  */
4
- import React, { memo, useMemo, useRef, createRef, useState, useEffect, useCallback } from 'react';
5
- import { chartContext } from '../context';
6
- import { PieChart, CartesianChart } from '.';
7
- import { group } from 'd3v7';
4
+ import React, {
5
+ memo,
6
+ useMemo,
7
+ useRef,
8
+ createRef,
9
+ useState,
10
+ useEffect,
11
+ useCallback,
12
+ } from "react";
13
+ import { chartContext } from "../context";
14
+ import { PieChart, CartesianChart } from ".";
15
+ import { group } from "d3v7";
8
16
 
9
- const getCallbackData = (action,callbacks, data) => {
10
- const callbackData={};
17
+ const getCallbackData = (action, callbacks, data) => {
18
+ const callbackData = {};
11
19
  if (callbacks && Array.isArray(callbacks) && callbacks.length && data) {
12
- callbacks.forEach(({ origin, target, actions:_action }) => {
13
- if(action === _action){
14
- callbackData[target] = data[origin];
15
- }
20
+ callbacks.forEach(({ origin, target, actions: _action }) => {
21
+ if (action === _action) {
22
+ callbackData[target] = origin ? data[origin] : data;
23
+ }
16
24
  });
17
25
  }
18
26
  return callbackData;
@@ -30,7 +38,7 @@ const Chart = memo(
30
38
  },
31
39
  interaction,
32
40
  },
33
- data:originData,
41
+ data: originData,
34
42
  onRelative,
35
43
  emit,
36
44
  emitEvent,
@@ -46,13 +54,14 @@ const Chart = memo(
46
54
  const chartWidth = width - marginLeft - marginRight;
47
55
  const chartHeight = height - marginTop - marginBottom;
48
56
  const [active, setActive] = useState(true);
49
- const scaleRef = useRef([1,1]);
57
+ const scaleRef = useRef([1, 1]);
58
+ const screenPosRef = useRef({ left: 0, top: 0 });
50
59
  const triggerOnRelative = useCallback(
51
- (action,data) => {
60
+ (action, data) => {
52
61
  if (!interaction) return;
53
62
  const { callbacks, remoteControls } = interaction;
54
63
  const callbackData = getCallbackData(action, callbacks, data);
55
- if (JSON.stringify(callbackData)!="{}") {
64
+ if (Object.keys(callbackData).length > 0) {
56
65
  onRelative && onRelative(id, callbackData);
57
66
  remoteControls &&
58
67
  emitEvent &&
@@ -61,30 +70,31 @@ const Chart = memo(
61
70
  if (
62
71
  control.screen &&
63
72
  control.type &&
64
- control.type === 'callback'
73
+ control.type === "callback"
65
74
  ) {
66
75
  emitEvent({
67
76
  screen: control.screen,
68
- type: 'callback',
77
+ type: "callback",
69
78
  callbackData,
70
79
  });
71
80
  }
72
81
  });
73
82
  }
74
83
  },
75
- [ JSON.stringify(interaction)]
84
+ [JSON.stringify(interaction)]
76
85
  );
77
86
 
78
87
  const onEmit = useCallback(
79
- (type = 'click', data) => emit && emit(type, data),
88
+ (type = "click", data) => emit && emit(type, data),
80
89
  [emit]
81
90
  );
82
91
 
83
92
  const context = useMemo(
84
93
  () => ({
85
94
  id,
86
- isIOS:isIOS.current, //是否为IOS设备
87
- scale:scaleRef, //大屏的缩放比
95
+ isIOS: isIOS.current, //是否为IOS设备
96
+ scale: scaleRef, //大屏的缩放比
97
+ screenPos: screenPosRef, //大屏的偏移位置
88
98
  width: chartWidth,
89
99
  height: chartHeight,
90
100
  triggerOnRelative,
@@ -93,62 +103,86 @@ const Chart = memo(
93
103
  }),
94
104
  [id, chartWidth, chartHeight, triggerOnRelative, svg, onEmit]
95
105
  );
96
-
97
- useEffect(()=>{
98
- let isAnimation = window.screenConfig?window.screenConfig.isAnimation:true; //大屏的全局设置是否允许开启动画,false为不允许
99
- if(!isAnimation) setActive(false);
100
- const activeHandler=(e)=>{
106
+
107
+ useEffect(() => {
108
+ let isAnimation = window.screenConfig
109
+ ? window.screenConfig.isAnimation
110
+ : true; //大屏的全局设置是否允许开启动画,false为不允许
111
+ if (!isAnimation) setActive(false);
112
+ const activeHandler = (e) => {
101
113
  const { dynamicData = true } = e;
102
114
  isAnimation && setActive(dynamicData);
103
- }
115
+ };
104
116
  getScreenScale();
105
- document.addEventListener(`switchActive_${id}`,activeHandler);
106
- document.addEventListener("resize",getScreenScale);
107
- return ()=>{
108
- document.removeEventListener(`switchActive_${id}`,activeHandler);
109
- document.removeEventListener("resize",getScreenScale);
110
- }
111
- },[]);
112
-
117
+ document.addEventListener(`switchActive_${id}`, activeHandler);
118
+ document.addEventListener("resize", getScreenScale);
119
+ return () => {
120
+ document.removeEventListener(`switchActive_${id}`, activeHandler);
121
+ document.removeEventListener("resize", getScreenScale);
122
+ };
123
+ }, []);
124
+
113
125
  let data = checkData(originData);
114
-
126
+
115
127
  return (
116
128
  <chartContext.Provider value={context}>
117
- {type == 'pie' ? (
118
- <PieChart id={id} config={config} data={data} active={active} {...props} />
129
+ {type == "pie" ? (
130
+ <PieChart
131
+ id={id}
132
+ config={config}
133
+ data={data}
134
+ active={active}
135
+ {...props}
136
+ />
119
137
  ) : (
120
- <CartesianChart id={id} config={config} data={data} active={active} {...props} />
121
- )}
138
+ <CartesianChart
139
+ id={id}
140
+ config={config}
141
+ data={data}
142
+ active={active}
143
+ {...props}
144
+ />
145
+ )}
122
146
  </chartContext.Provider>
123
-
124
147
  );
125
148
  //获取大屏缩放系数
126
- function getScreenScale(){
127
- setTimeout(()=>{
128
- //获取大屏缩放系数
129
- let dom = document.getElementById("bigscreen-container") || document.getElementById("m-simulator");
130
- if(dom){
131
- const transform = dom.style.transform;
132
- const scale = transform?transform.match(/^scale\((.+)\)$/)[1]:"1,1";
133
- const arr = scale.split(",");
134
- scaleRef.current = [1/arr[0],1/(arr.length===1?arr[0]:arr[1])]; //这里做一次除法,后面就可以用乘法计算值了
135
- }
136
- },50);
149
+ function getScreenScale() {
150
+ setTimeout(() => {
151
+ //获取大屏缩放系数
152
+ let dom =
153
+ document.getElementById("bigscreen-container") ||
154
+ document.getElementById("m-simulator");
155
+ if (dom) {
156
+ const transform = dom.style.transform;
157
+ const scale = transform
158
+ ? transform.match(/^scale\((.+)\)$/)[1]
159
+ : "1,1";
160
+ const arr = scale.split(",");
161
+ scaleRef.current = [
162
+ 1 / arr[0],
163
+ 1 / (arr.length === 1 ? arr[0] : arr[1]),
164
+ ]; //这里做一次除法,后面就可以用乘法计算值了
165
+ screenPosRef.current = {
166
+ left: parseFloat(dom.style.left),
167
+ top: parseFloat(dom.style.top),
168
+ };
169
+ }
170
+ }, 100);
137
171
  }
138
172
  //预检数据格式是否规范
139
- function checkData(data){
140
- try{
141
- const hasS = data.some(d=>d.s);
142
- if(!hasS){
143
- return data.map(d=>{
173
+ function checkData(data) {
174
+ try {
175
+ const hasS = data.some((d) => d.s);
176
+ if (!hasS) {
177
+ return data.map((d) => {
144
178
  return {
145
179
  ...d,
146
- s:"系列一"
147
- }
148
- })
180
+ s: "系列一",
181
+ };
182
+ });
149
183
  }
150
184
  return data;
151
- }catch(e){}
185
+ } catch (e) {}
152
186
  return [];
153
187
  }
154
188
  }
@@ -3,7 +3,12 @@
3
3
  */
4
4
  import { memo, useContext } from "react";
5
5
  import { min, max } from "d3v7";
6
- import { getTranslate2d, getSeriesInfo, getFontStyle, formatFont } from "../utils";
6
+ import {
7
+ getTranslate2d,
8
+ getSeriesInfo,
9
+ getFontStyle,
10
+ formatFont,
11
+ } from "../utils";
7
12
  import { chartContext } from "../context";
8
13
 
9
14
  const getHighlightData = (data, extent) => {
@@ -31,8 +36,8 @@ export default memo(
31
36
  config: {
32
37
  seriesIntervalWidth: paddingInner = 0,
33
38
  paddingInner: paddingOuter = 0,
34
- showType:seriesType = 'bar',
35
- highlight: { show: showHighlight, extent, ...highlightStyle }={},//配置项不存在的处理
39
+ showType: seriesType = "bar",
40
+ highlight: { show: showHighlight, extent, ...highlightStyle } = {}, //配置项不存在的处理
36
41
  ...other
37
42
  },
38
43
  config,
@@ -42,25 +47,25 @@ export default memo(
42
47
  data,
43
48
  xAxis: { scaler: xScaler, step, direction },
44
49
  yAxis: { scaler: yScaler, isClipAxis, clipValue },
45
- triggerClick
50
+ triggerEvents,
46
51
  }) => {
47
52
  let selectConfig = other;
48
- if(selectStyle){
49
- const { show, showType, icon, numlabel:label } = selectStyle;
50
- if(show && seriesType==showType){
51
- if(showType=="bar"){
53
+ if (selectStyle) {
54
+ const { show, showType, icon, numlabel: label } = selectStyle;
55
+ if (show && seriesType == showType) {
56
+ if (showType == "bar") {
52
57
  selectConfig = { label };
53
- }else{
58
+ } else {
54
59
  selectConfig = { icon, label };
55
60
  }
56
61
  }
57
62
  }
58
63
  let highlightConfig = other;
59
- if(highlightStyle){
60
- highlightConfig = { ...other, label:highlightStyle.numlabel };
64
+ if (highlightStyle) {
65
+ highlightConfig = { ...other, label: highlightStyle.numlabel };
61
66
  }
62
67
  const lineType = config.hasOwnProperty("line"); // 堆叠处理
63
-
68
+
64
69
  if (!data.length) return null;
65
70
  const { width, height } = useContext(chartContext);
66
71
 
@@ -72,19 +77,27 @@ export default memo(
72
77
  });
73
78
  const _data = showHighlight ? getHighlightData(data, extent) : data;
74
79
  const isVertical = direction === "vertical";
75
-
80
+
76
81
  return (
77
82
  <g className="__easyv-label">
78
83
  {_data.map(
79
84
  (
80
- { flag, index, bound: [start, end], data, data: { x, y, showY, s } },
85
+ {
86
+ flag,
87
+ index,
88
+ bound: [start, end],
89
+ data,
90
+ data: { x, y, showY, s },
91
+ },
81
92
  i
82
93
  ) => {
83
94
  let y1, y2;
84
- const { icon, label } = x==curXLabel?selectConfig:flag?highlightConfig:other;
95
+ const { icon, label } =
96
+ x == curXLabel ? selectConfig : flag ? highlightConfig : other;
85
97
  const showIcon = icon && icon.show;
86
98
  const showLabel = label && label.show;
87
- const { position:_position="outerStart", reverse=true } = label || {};
99
+ const { position: _position = "outerStart", reverse = true } =
100
+ label || {};
88
101
  if (isClipAxis) {
89
102
  if (end > +clipValue) {
90
103
  y1 = yScaler[1](start);
@@ -108,7 +121,9 @@ export default memo(
108
121
  xScaler(x) - step / 2 + seriesStart + index * seriesStep;
109
122
 
110
123
  if (isNaN(positionX)) return null;
111
- const position =isXRepeat?positionX + (config.line ? step : seriesWidth) / 2: xScaler(x);
124
+ const position = isXRepeat
125
+ ? positionX + (config.line ? step : seriesWidth) / 2
126
+ : xScaler(x);
112
127
  const labelPosition = isVertical
113
128
  ? getVerticalLabel({
114
129
  position: _position,
@@ -116,7 +131,7 @@ export default memo(
116
131
  y1,
117
132
  y2,
118
133
  width,
119
- reverse
134
+ reverse,
120
135
  })
121
136
  : getHorizontalLabel({
122
137
  position: _position,
@@ -124,7 +139,7 @@ export default memo(
124
139
  y1,
125
140
  y2,
126
141
  height,
127
- reverse
142
+ reverse,
128
143
  });
129
144
  const attr = isVertical
130
145
  ? {
@@ -140,14 +155,23 @@ export default memo(
140
155
  return (
141
156
  <g
142
157
  key={i}
143
- onClick={e=>triggerClick(e,"setCurrent")}
158
+ onClick={(e) => triggerEvents(e, "setCurrent")}
159
+ onMouseMove={(e) => triggerEvents(e, "mouseenter")}
160
+ onMouseLeave={(e) => triggerEvents(e, "mouseleave")}
144
161
  style={{ cursor: "pointer" }}
145
162
  data-data={JSON.stringify(data)}
146
163
  >
147
164
  {showIcon && !isNaN(attr.y) && (
148
165
  <Icon cx={attr.x} cy={y2} config={icon} />
149
166
  )}
150
- {showLabel && <Label value={showY} config={label} reverse={reverse} {...attr} />}
167
+ {showLabel && (
168
+ <Label
169
+ value={showY}
170
+ config={label}
171
+ reverse={reverse}
172
+ {...attr}
173
+ />
174
+ )}
151
175
  </g>
152
176
  );
153
177
  }
@@ -164,13 +188,15 @@ const Label = ({
164
188
  config: {
165
189
  font,
166
190
  translate: { x: translateX = 0, y: translateY = 0 },
167
- suffix:{
168
- content, font:suffixFont, translate:{ x:suffixX, y:suffixY }
169
- }
191
+ suffix: {
192
+ content,
193
+ font: suffixFont,
194
+ translate: { x: suffixX, y: suffixY },
195
+ },
170
196
  },
171
197
  textAnchor = "middle",
172
198
  dominantBaseline = "middle",
173
- reverse
199
+ reverse,
174
200
  }) => {
175
201
  return (
176
202
  <text
@@ -182,12 +208,18 @@ const Label = ({
182
208
  })}
183
209
  textAnchor={textAnchor}
184
210
  dominantBaseline={dominantBaseline}
185
- style={{...formatFont(font,"svg")}}
211
+ style={{ ...formatFont(font, "svg") }}
186
212
  >
187
213
  <tspan>{value}</tspan>
188
- <tspan dx={suffixX} dy={suffixY} style={{
189
- ...getFontStyle(suffixFont,"svg")
190
- }}>{content}</tspan>
214
+ <tspan
215
+ dx={suffixX}
216
+ dy={suffixY}
217
+ style={{
218
+ ...getFontStyle(suffixFont, "svg"),
219
+ }}
220
+ >
221
+ {content}
222
+ </tspan>
191
223
  </text>
192
224
  );
193
225
  };
@@ -227,13 +259,20 @@ const Circle = ({ cx, cy, color, radius }) => (
227
259
  <circle cx={cx} cy={cy} fill={color} r={radius} stroke="none" />
228
260
  );
229
261
 
230
- const getVerticalLabel = ({ position = "outerStart", width, y, y1, y2, reverse = true }) => {
231
- const needReverse = reverse && y<0;
262
+ const getVerticalLabel = ({
263
+ position = "outerStart",
264
+ width,
265
+ y,
266
+ y1,
267
+ y2,
268
+ reverse = true,
269
+ }) => {
270
+ const needReverse = reverse && y < 0;
232
271
  switch (position) {
233
272
  case "start":
234
273
  return {
235
274
  x: y2,
236
- textAnchor: needReverse?"end":"start",
275
+ textAnchor: needReverse ? "end" : "start",
237
276
  };
238
277
  case "middle":
239
278
  return {
@@ -243,12 +282,12 @@ const getVerticalLabel = ({ position = "outerStart", width, y, y1, y2, reverse =
243
282
  case "end":
244
283
  return {
245
284
  x: y1,
246
- textAnchor: needReverse?"start":"end",
285
+ textAnchor: needReverse ? "start" : "end",
247
286
  };
248
287
  case "outerStart":
249
288
  return {
250
289
  x: y1,
251
- textAnchor: needReverse?"end":"start",
290
+ textAnchor: needReverse ? "end" : "start",
252
291
  };
253
292
  case "chartStart":
254
293
  return {
@@ -257,13 +296,20 @@ const getVerticalLabel = ({ position = "outerStart", width, y, y1, y2, reverse =
257
296
  };
258
297
  }
259
298
  };
260
- const getHorizontalLabel = ({ position = "outerStart", height, y, y1, y2, reverse = true }) => {
261
- const needReverse = reverse && y<0;
299
+ const getHorizontalLabel = ({
300
+ position = "outerStart",
301
+ height,
302
+ y,
303
+ y1,
304
+ y2,
305
+ reverse = true,
306
+ }) => {
307
+ const needReverse = reverse && y < 0;
262
308
  switch (position) {
263
309
  case "start":
264
310
  return {
265
311
  y: y1,
266
- dominantBaseline: needReverse?"text-before-edge":"text-after-edge",
312
+ dominantBaseline: needReverse ? "text-before-edge" : "text-after-edge",
267
313
  };
268
314
  case "middle":
269
315
  return {
@@ -273,12 +319,12 @@ const getHorizontalLabel = ({ position = "outerStart", height, y, y1, y2, revers
273
319
  case "end":
274
320
  return {
275
321
  y: y2,
276
- dominantBaseline: needReverse?"text-after-edge":"text-before-edge",
322
+ dominantBaseline: needReverse ? "text-after-edge" : "text-before-edge",
277
323
  };
278
324
  case "outerStart":
279
325
  return {
280
326
  y: y2,
281
- dominantBaseline: needReverse?"text-before-edge":"text-after-edge",
327
+ dominantBaseline: needReverse ? "text-before-edge" : "text-after-edge",
282
328
  };
283
329
  case "chartStart":
284
330
  return {