@easyv/charts 1.6.20 → 1.6.21

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