@easyv/charts 1.6.18 → 1.6.20

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 (63) hide show
  1. package/.babelrc +8 -8
  2. package/CHANGELOG.md +18 -18
  3. package/commitlint.config.js +1 -1
  4. package/lib/components/Background.js +2 -2
  5. package/lib/components/Band.js +2 -2
  6. package/lib/components/Brush.js +2 -2
  7. package/lib/components/CartesianChart.js +6 -3
  8. package/lib/components/Chart.js +3 -2
  9. package/lib/components/ChartContainer.js +2 -2
  10. package/lib/components/ConicalGradient.js +21 -21
  11. package/lib/components/ExtentData.js +2 -2
  12. package/lib/components/Indicator.js +6 -5
  13. package/lib/components/Label.js +3 -3
  14. package/lib/components/Legend.js +2 -2
  15. package/lib/components/Lighter.js +2 -2
  16. package/lib/components/Line.js +2 -2
  17. package/lib/components/LinearGradient.js +2 -2
  18. package/lib/components/StereoBar.js +2 -2
  19. package/lib/components/Tooltip.js +4 -3
  20. package/lib/css/index.module.css +42 -42
  21. package/lib/css/piechart.module.css +26 -26
  22. package/lib/hooks/useAnimateData.js +6 -6
  23. package/lib/hooks/useFilterData.js +5 -5
  24. package/lib/hooks/useStackData.js +5 -5
  25. package/lib/hooks/useTooltip.js +11 -11
  26. package/lib/utils/index.js +81 -61
  27. package/package.json +55 -55
  28. package/src/components/Background.tsx +61 -61
  29. package/src/components/Band.tsx +302 -302
  30. package/src/components/Brush.js +159 -159
  31. package/src/components/CartesianChart.js +3 -0
  32. package/src/components/Chart.js +153 -154
  33. package/src/components/ChartContainer.tsx +71 -71
  34. package/src/components/ConicalGradient.js +258 -258
  35. package/src/components/Control.jsx +241 -241
  36. package/src/components/ExtentData.js +18 -18
  37. package/src/components/Indicator.js +59 -58
  38. package/src/components/Label.js +262 -262
  39. package/src/components/Legend.js +189 -189
  40. package/src/components/Lighter.jsx +173 -173
  41. package/src/components/Line.js +153 -153
  42. package/src/components/LinearGradient.js +29 -29
  43. package/src/components/PieTooltip.jsx +160 -160
  44. package/src/components/StereoBar.tsx +307 -307
  45. package/src/components/Tooltip.js +3 -2
  46. package/src/components/index.js +59 -59
  47. package/src/context/index.js +2 -2
  48. package/src/css/index.module.css +42 -42
  49. package/src/css/piechart.module.css +26 -26
  50. package/src/element/ConicGradient.jsx +55 -55
  51. package/src/element/Line.tsx +33 -33
  52. package/src/element/index.ts +3 -3
  53. package/src/formatter/index.js +1 -1
  54. package/src/formatter/legend.js +114 -114
  55. package/src/hooks/index.js +20 -20
  56. package/src/hooks/useAnimateData.ts +68 -68
  57. package/src/hooks/useFilterData.js +78 -78
  58. package/src/hooks/useStackData.js +102 -102
  59. package/src/hooks/useTooltip.ts +104 -104
  60. package/src/index.js +6 -6
  61. package/src/types/index.d.ts +68 -68
  62. package/src/utils/index.js +800 -782
  63. package/tsconfig.json +23 -23
@@ -1,302 +1,302 @@
1
- /**
2
- * (柱状/条形)图柱子
3
- */
4
- import React, { memo } from "react";
5
- import { min, max } from "d3v7";
6
- import { getBandBackground, getSeriesInfo } from "../utils";
7
-
8
- const getHighlightData = (data: Array<DataWithBoundType>, extent: string) => {
9
- switch (extent) {
10
- case "min":
11
- const minData = min(data, (d: DataWithBoundType) => d.data.y);
12
- return data.map((item) => ({
13
- ...item,
14
- flag: minData == item.data.y ? "min" : "",
15
- }));
16
- case "max":
17
- const maxData = max(data, (d: DataWithBoundType) => d.data.y);
18
- return data.map((item) => ({
19
- ...item,
20
- flag: maxData == item.data.y ? "max" : "",
21
- }));
22
- default:
23
- return data;
24
- }
25
- };
26
-
27
- const getAttr = ({
28
- isVertical,
29
- seriesWidth,
30
- length,
31
- x,
32
- y,
33
- }: {
34
- isVertical: boolean;
35
- seriesWidth: number;
36
- length: number;
37
- x: number;
38
- y: number;
39
- }) => {
40
- if (isVertical) return { width: length, height: seriesWidth, x: y, y: x };
41
- return {
42
- x,
43
- y,
44
- width: seriesWidth,
45
- height: length?length:0.1,
46
- };
47
- };
48
-
49
- const getBorderRadius = ({
50
- isVertical,
51
- positive,
52
- seriesWidth,
53
- }: {
54
- isVertical: boolean;
55
- positive: boolean;
56
- seriesWidth: number;
57
- }) => {
58
- return isVertical
59
- ? positive
60
- ? "0px " + seriesWidth + "px " + seriesWidth + "px 0"
61
- : seriesWidth + "px 0 0 " + seriesWidth + "px"
62
- : positive
63
- ? seriesWidth / 2 + "px " + seriesWidth / 2 + "px 0 0"
64
- : "0 0 " + seriesWidth / 2 + "px " + seriesWidth / 2 + "px";
65
- };
66
-
67
- export default memo(
68
- ({
69
- //控制图部分,主要是为了控制图的指示器,在悬浮的时候显示
70
- triggerClick,
71
- indicatorWidth,
72
- isControlChart = false,
73
- setCtlTip,
74
- config: {
75
- pattern = {},
76
- seriesIntervalWidth: paddingInner = 0,
77
- paddingInner: paddingOuter = 0,
78
- highlight: { show: showHighlight, extent, fill: highlightFill },
79
- ...other
80
- },
81
- curXLabel,
82
- selectStyle,
83
- bandLength = 0,
84
- data,
85
- xAxis: { scaler: normalScaler, step:normalStep, controlStep, direction, controlDragScaler },
86
- yAxis: { scaler: yScaler, isClipAxis, clipValue, reverse },
87
- }: any) => {
88
- if (!data.length) return null;
89
- let selectConfig = other;
90
- if(selectStyle){
91
- const { show, showType, barStyle, headDecorate } = selectStyle;
92
- if(show && showType=="bar"){
93
- selectConfig = { ...barStyle, headDecorate };
94
- }
95
- }
96
- const step = isControlChart?controlStep:normalStep;
97
- const xScaler = isControlChart?controlDragScaler:normalScaler;
98
- const { seriesWidth, seriesStep, seriesStart } = getSeriesInfo({
99
- step,
100
- bandLength,
101
- paddingInner,
102
- paddingOuter,
103
- });
104
- const _data = showHighlight ? getHighlightData(data, extent) : data;
105
- const isVertical = direction === "vertical";
106
-
107
- return (
108
- <g className="__easyv-band">
109
- {_data.map(
110
- (
111
- {
112
- flag,
113
- index,
114
- bound: [start, end],
115
- data,
116
- data: { x, y, s },
117
- }: DataWithBoundType,
118
- i: number
119
- ) => {
120
- let y1: number, y2: number;
121
- //断轴图相关,断轴图的scaler是一个数组,内含上断轴下断轴的scaler
122
- if (isClipAxis) {
123
- if (end > +clipValue) {
124
- y1 = yScaler[1](start);
125
- y2 = yScaler[0](end);
126
- } else {
127
- y1 = yScaler[1](start);
128
- y2 = yScaler[1](end);
129
- }
130
- } else {
131
- y1 = yScaler(isVertical ? end : start);
132
- y2 = yScaler(isVertical ? start : end);
133
- }
134
- const {
135
- style,
136
- fillType,
137
- url,
138
- size,
139
- fill,
140
- border,
141
- opacity,
142
- headDecorate
143
- } = x==curXLabel?selectConfig:other;
144
- const borderStr = `${border.borderColor} solid ${border.borderWidth}px`;
145
- const positionX = xScaler(x) - step / 2 + seriesStart + index * seriesStep;
146
-
147
- let showHead, headType, headUrl, headVideo, headWidth, headHeight, headTranslate;
148
- if (headDecorate) {
149
- (showHead = headDecorate.show),
150
- (headType = headDecorate.type),
151
- (headUrl = headDecorate.url),
152
- (headVideo = headDecorate.video),
153
- (headWidth = headDecorate.size.width),
154
- (headHeight = headDecorate.size.height),
155
- (headTranslate = headDecorate.translate);
156
- }
157
- //断轴图相关,将柱形在断轴处切开
158
- const setClipPath = () => {
159
- if (isClipAxis && end > +clipValue) {
160
- let clipValueY2 = yScaler[0](clipValue); //上方
161
- let clipValueY1 = yScaler[1](clipValue); //下方
162
- let top = Math.abs((y2 - clipValueY2) / (y1 - y2)) * 100;
163
- let bottom = Math.abs((y2 - clipValueY1) / (y1 - y2)) * 100;
164
-
165
- //clip path属性
166
- return `polygon(0% 0%, 0% 100%, 0 100%, 0 ${top}%, 100% ${top}%, 100% ${bottom}%, 0 ${bottom}%, 0 100%, 100% 100%, 100% 0%)`;
167
- } else {
168
- return "none";
169
- }
170
- };
171
- if (isNaN(positionX)) return null;
172
- const positionY = reverse?
173
- y > 0 ? y1 : y2:
174
- y < 0 ? y1 : y2;
175
- const attr = getAttr({
176
- isVertical,
177
- x: positionX,
178
- y: positionY,
179
- length: Math.abs(y1 - y2),
180
- seriesWidth,
181
- });
182
- return (
183
- <foreignObject
184
- key={i}
185
- style={{
186
- overflow: "visible",
187
- position: "relative",
188
- cursor: "pointer",
189
- }}
190
- {...attr}
191
- onClick={e=>triggerClick(e,"setCurrent")}
192
- //enter和leave事件,用于控制图的提示框
193
- onMouseEnter={() => {
194
- if(isControlChart){
195
- setCtlTip((pre:any)=>({
196
- show:true,
197
- x:xScaler(x),
198
- xName:data.x,
199
- indicatorList:pre.indicatorList.map((item:any)=>{
200
- if (item.tick === data.x) {
201
- return { ...item, isShow: true };
202
- } else {
203
- return item;
204
- }
205
- })
206
- }))
207
- }
208
- }}
209
- onMouseLeave={() => {
210
- if(isControlChart){
211
- setCtlTip((pre:any)=>({
212
- show:false,
213
- x:undefined,
214
- xName:undefined,
215
- indicatorList:pre.indicatorList.map((item:any)=>{
216
- return { ...item, isShow:false }
217
- })
218
- }))
219
- }
220
- }}
221
- data-data={JSON.stringify(data)}
222
- >
223
- {(headUrl || headVideo) && showHead && (
224
- headType=="image"?<div
225
- style={{
226
- position: "absolute",
227
- background: `url(${
228
- //@ts-ignore
229
- window.appConfig.ASSETS_URL + headUrl
230
- }) 0 0/100% 100%`,
231
- width: headWidth,
232
- height: headHeight,
233
- left: isVertical ? "100%" : "50%",
234
- top: isVertical ? "50%" : "0",
235
- zIndex: 1,
236
- transform: `translate(calc(-50% + ${headTranslate.x}px), calc(-50% + ${headTranslate.y}px))`,
237
- }}
238
- ></div>:<video
239
- width={headWidth} height={headHeight}
240
- //@ts-ignore
241
- src={window.appConfig.ASSETS_URL + headVideo}
242
- // controls={true}
243
- loop={true}
244
- muted={true}
245
- autoPlay={true}
246
- style={{
247
- position: "absolute",
248
- left: isVertical ? "100%" : "50%",
249
- top: isVertical ? "50%" : "0",
250
- zIndex: 1,
251
- transform: `translate(calc(-50% + ${headTranslate.x}px), calc(-50% + ${headTranslate.y}px))`,
252
- }}
253
- ></video>
254
- )}
255
- <div
256
- style={{
257
- width: "100%",
258
- height: "100%",
259
- /** Safari Bug **/
260
- // position: "fixed",
261
- clipPath: setClipPath(),
262
- opacity: fillType == "pattern" ? opacity : 1,
263
- background:
264
- fillType == "pattern"
265
- ? `50% 50% / ${size.width}px ${size.height}px repeat ` +
266
- "url(" +
267
- //@ts-ignore
268
- window.appConfig.ASSETS_URL + url +
269
- ")"
270
- : getBandBackground(
271
- pattern,
272
- extent === flag ? highlightFill : fill
273
- ),
274
- borderRadius:
275
- style == "square"
276
- ? "0 0 0 0"
277
- : getBorderRadius({
278
- isVertical,
279
- positive: y > 0,
280
- seriesWidth,
281
- }),
282
- ...(isVertical
283
- ? {
284
- borderTop: borderStr,
285
- borderRight: borderStr,
286
- borderBottom: borderStr,
287
- }
288
- : {
289
- borderTop: borderStr,
290
- borderRight: borderStr,
291
- borderLeft: borderStr,
292
- }),
293
- }}
294
- />
295
- </foreignObject>
296
- );
297
- }
298
- )}
299
- </g>
300
- );
301
- }
302
- );
1
+ /**
2
+ * (柱状/条形)图柱子
3
+ */
4
+ import React, { memo } from "react";
5
+ import { min, max } from "d3v7";
6
+ import { getBandBackground, getSeriesInfo } from "../utils";
7
+
8
+ const getHighlightData = (data: Array<DataWithBoundType>, extent: string) => {
9
+ switch (extent) {
10
+ case "min":
11
+ const minData = min(data, (d: DataWithBoundType) => d.data.y);
12
+ return data.map((item) => ({
13
+ ...item,
14
+ flag: minData == item.data.y ? "min" : "",
15
+ }));
16
+ case "max":
17
+ const maxData = max(data, (d: DataWithBoundType) => d.data.y);
18
+ return data.map((item) => ({
19
+ ...item,
20
+ flag: maxData == item.data.y ? "max" : "",
21
+ }));
22
+ default:
23
+ return data;
24
+ }
25
+ };
26
+
27
+ const getAttr = ({
28
+ isVertical,
29
+ seriesWidth,
30
+ length,
31
+ x,
32
+ y,
33
+ }: {
34
+ isVertical: boolean;
35
+ seriesWidth: number;
36
+ length: number;
37
+ x: number;
38
+ y: number;
39
+ }) => {
40
+ if (isVertical) return { width: length, height: seriesWidth, x: y, y: x };
41
+ return {
42
+ x,
43
+ y,
44
+ width: seriesWidth,
45
+ height: length?length:0.1,
46
+ };
47
+ };
48
+
49
+ const getBorderRadius = ({
50
+ isVertical,
51
+ positive,
52
+ seriesWidth,
53
+ }: {
54
+ isVertical: boolean;
55
+ positive: boolean;
56
+ seriesWidth: number;
57
+ }) => {
58
+ return isVertical
59
+ ? positive
60
+ ? "0px " + seriesWidth + "px " + seriesWidth + "px 0"
61
+ : seriesWidth + "px 0 0 " + seriesWidth + "px"
62
+ : positive
63
+ ? seriesWidth / 2 + "px " + seriesWidth / 2 + "px 0 0"
64
+ : "0 0 " + seriesWidth / 2 + "px " + seriesWidth / 2 + "px";
65
+ };
66
+
67
+ export default memo(
68
+ ({
69
+ //控制图部分,主要是为了控制图的指示器,在悬浮的时候显示
70
+ triggerClick,
71
+ indicatorWidth,
72
+ isControlChart = false,
73
+ setCtlTip,
74
+ config: {
75
+ pattern = {},
76
+ seriesIntervalWidth: paddingInner = 0,
77
+ paddingInner: paddingOuter = 0,
78
+ highlight: { show: showHighlight, extent, fill: highlightFill },
79
+ ...other
80
+ },
81
+ curXLabel,
82
+ selectStyle,
83
+ bandLength = 0,
84
+ data,
85
+ xAxis: { scaler: normalScaler, step:normalStep, controlStep, direction, controlDragScaler },
86
+ yAxis: { scaler: yScaler, isClipAxis, clipValue, reverse },
87
+ }: any) => {
88
+ if (!data.length) return null;
89
+ let selectConfig = other;
90
+ if(selectStyle){
91
+ const { show, showType, barStyle, headDecorate } = selectStyle;
92
+ if(show && showType=="bar"){
93
+ selectConfig = { ...barStyle, headDecorate };
94
+ }
95
+ }
96
+ const step = isControlChart?controlStep:normalStep;
97
+ const xScaler = isControlChart?controlDragScaler:normalScaler;
98
+ const { seriesWidth, seriesStep, seriesStart } = getSeriesInfo({
99
+ step,
100
+ bandLength,
101
+ paddingInner,
102
+ paddingOuter,
103
+ });
104
+ const _data = showHighlight ? getHighlightData(data, extent) : data;
105
+ const isVertical = direction === "vertical";
106
+
107
+ return (
108
+ <g className="__easyv-band">
109
+ {_data.map(
110
+ (
111
+ {
112
+ flag,
113
+ index,
114
+ bound: [start, end],
115
+ data,
116
+ data: { x, y, s },
117
+ }: DataWithBoundType,
118
+ i: number
119
+ ) => {
120
+ let y1: number, y2: number;
121
+ //断轴图相关,断轴图的scaler是一个数组,内含上断轴下断轴的scaler
122
+ if (isClipAxis) {
123
+ if (end > +clipValue) {
124
+ y1 = yScaler[1](start);
125
+ y2 = yScaler[0](end);
126
+ } else {
127
+ y1 = yScaler[1](start);
128
+ y2 = yScaler[1](end);
129
+ }
130
+ } else {
131
+ y1 = yScaler(isVertical ? end : start);
132
+ y2 = yScaler(isVertical ? start : end);
133
+ }
134
+ const {
135
+ style,
136
+ fillType,
137
+ url,
138
+ size,
139
+ fill,
140
+ border,
141
+ opacity,
142
+ headDecorate
143
+ } = x==curXLabel?selectConfig:other;
144
+ const borderStr = `${border.borderColor} solid ${border.borderWidth}px`;
145
+ const positionX = xScaler(x) - step / 2 + seriesStart + index * seriesStep;
146
+
147
+ let showHead, headType, headUrl, headVideo, headWidth, headHeight, headTranslate;
148
+ if (headDecorate) {
149
+ (showHead = headDecorate.show),
150
+ (headType = headDecorate.type),
151
+ (headUrl = headDecorate.url),
152
+ (headVideo = headDecorate.video),
153
+ (headWidth = headDecorate.size.width),
154
+ (headHeight = headDecorate.size.height),
155
+ (headTranslate = headDecorate.translate);
156
+ }
157
+ //断轴图相关,将柱形在断轴处切开
158
+ const setClipPath = () => {
159
+ if (isClipAxis && end > +clipValue) {
160
+ let clipValueY2 = yScaler[0](clipValue); //上方
161
+ let clipValueY1 = yScaler[1](clipValue); //下方
162
+ let top = Math.abs((y2 - clipValueY2) / (y1 - y2)) * 100;
163
+ let bottom = Math.abs((y2 - clipValueY1) / (y1 - y2)) * 100;
164
+
165
+ //clip path属性
166
+ return `polygon(0% 0%, 0% 100%, 0 100%, 0 ${top}%, 100% ${top}%, 100% ${bottom}%, 0 ${bottom}%, 0 100%, 100% 100%, 100% 0%)`;
167
+ } else {
168
+ return "none";
169
+ }
170
+ };
171
+ if (isNaN(positionX)) return null;
172
+ const positionY = reverse?
173
+ y > 0 ? y1 : y2:
174
+ y < 0 ? y1 : y2;
175
+ const attr = getAttr({
176
+ isVertical,
177
+ x: positionX,
178
+ y: positionY,
179
+ length: Math.abs(y1 - y2),
180
+ seriesWidth,
181
+ });
182
+ return (
183
+ <foreignObject
184
+ key={i}
185
+ style={{
186
+ overflow: "visible",
187
+ position: "relative",
188
+ cursor: "pointer",
189
+ }}
190
+ {...attr}
191
+ onClick={e=>triggerClick(e,"setCurrent")}
192
+ //enter和leave事件,用于控制图的提示框
193
+ onMouseEnter={() => {
194
+ if(isControlChart){
195
+ setCtlTip((pre:any)=>({
196
+ show:true,
197
+ x:xScaler(x),
198
+ xName:data.x,
199
+ indicatorList:pre.indicatorList.map((item:any)=>{
200
+ if (item.tick === data.x) {
201
+ return { ...item, isShow: true };
202
+ } else {
203
+ return item;
204
+ }
205
+ })
206
+ }))
207
+ }
208
+ }}
209
+ onMouseLeave={() => {
210
+ if(isControlChart){
211
+ setCtlTip((pre:any)=>({
212
+ show:false,
213
+ x:undefined,
214
+ xName:undefined,
215
+ indicatorList:pre.indicatorList.map((item:any)=>{
216
+ return { ...item, isShow:false }
217
+ })
218
+ }))
219
+ }
220
+ }}
221
+ data-data={JSON.stringify(data)}
222
+ >
223
+ {(headUrl || headVideo) && showHead && (
224
+ headType=="image"?<div
225
+ style={{
226
+ position: "absolute",
227
+ background: `url(${
228
+ //@ts-ignore
229
+ window.appConfig.ASSETS_URL + headUrl
230
+ }) 0 0/100% 100%`,
231
+ width: headWidth,
232
+ height: headHeight,
233
+ left: isVertical ? "100%" : "50%",
234
+ top: isVertical ? "50%" : "0",
235
+ zIndex: 1,
236
+ transform: `translate(calc(-50% + ${headTranslate.x}px), calc(-50% + ${headTranslate.y}px))`,
237
+ }}
238
+ ></div>:<video
239
+ width={headWidth} height={headHeight}
240
+ //@ts-ignore
241
+ src={window.appConfig.ASSETS_URL + headVideo}
242
+ // controls={true}
243
+ loop={true}
244
+ muted={true}
245
+ autoPlay={true}
246
+ style={{
247
+ position: "absolute",
248
+ left: isVertical ? "100%" : "50%",
249
+ top: isVertical ? "50%" : "0",
250
+ zIndex: 1,
251
+ transform: `translate(calc(-50% + ${headTranslate.x}px), calc(-50% + ${headTranslate.y}px))`,
252
+ }}
253
+ ></video>
254
+ )}
255
+ <div
256
+ style={{
257
+ width: "100%",
258
+ height: "100%",
259
+ /** Safari Bug **/
260
+ // position: "fixed",
261
+ clipPath: setClipPath(),
262
+ opacity: fillType == "pattern" ? opacity : 1,
263
+ background:
264
+ fillType == "pattern"
265
+ ? `50% 50% / ${size.width}px ${size.height}px repeat ` +
266
+ "url(" +
267
+ //@ts-ignore
268
+ window.appConfig.ASSETS_URL + url +
269
+ ")"
270
+ : getBandBackground(
271
+ pattern,
272
+ extent === flag ? highlightFill : fill
273
+ ),
274
+ borderRadius:
275
+ style == "square"
276
+ ? "0 0 0 0"
277
+ : getBorderRadius({
278
+ isVertical,
279
+ positive: y > 0,
280
+ seriesWidth,
281
+ }),
282
+ ...(isVertical
283
+ ? {
284
+ borderTop: borderStr,
285
+ borderRight: borderStr,
286
+ borderBottom: borderStr,
287
+ }
288
+ : {
289
+ borderTop: borderStr,
290
+ borderRight: borderStr,
291
+ borderLeft: borderStr,
292
+ }),
293
+ }}
294
+ />
295
+ </foreignObject>
296
+ );
297
+ }
298
+ )}
299
+ </g>
300
+ );
301
+ }
302
+ );