@easyv/charts 1.8.27 → 1.8.29

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.
@@ -27,6 +27,7 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
27
27
  var observe = (0, _react.useRef)(null);
28
28
  var speed_ = (0, _react.useRef)(0); //这里必须用一个ref绑定speed,否则animation中获取不到最新的speed
29
29
  var timer = (0, _react.useRef)();
30
+ var overflowRef = (0, _react.useRef)(false); // 使用ref来跟踪overflow状态,避免闭包问题
30
31
  var _useState = (0, _react.useState)(false),
31
32
  _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
32
33
  overflow = _useState2[0],
@@ -41,25 +42,41 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
41
42
  };
42
43
  timer.current = requestAnimationFrame(_animation);
43
44
  };
45
+
46
+ // 检查文本是否溢出的函数
47
+ var checkOverflow = function checkOverflow() {
48
+ if (!target.current || !rootRef.current) return;
49
+
50
+ // 直接比较元素的实际内容宽度和容器的可见宽度
51
+ // scrollWidth 是元素内容的实际宽度(包括溢出部分)
52
+ // clientWidth 是元素可见区域的宽度
53
+ var textWidth = target.current.scrollWidth;
54
+ var containerWidth = rootRef.current.clientWidth;
55
+ if (textWidth <= containerWidth) {
56
+ console.log("文字全部可视");
57
+ //表示文字全部可视
58
+ cancelAnimationFrame(timer.current || 0);
59
+ target.current.style.transform = "translate(0px,0px)"; //重置偏移
60
+ overflowRef.current = false;
61
+ setOverflow(false);
62
+ } else {
63
+ //否则文本溢出
64
+ if (!overflowRef.current) {
65
+ cancelAnimationFrame(timer.current || 0);
66
+ startAnimation(textWidth);
67
+ overflowRef.current = true;
68
+ setOverflow(true);
69
+ }
70
+ }
71
+ };
44
72
  (0, _react.useEffect)(function () {
45
73
  //初始化观察器,利用观察器来监视组件可视区域变化
74
+ // 注意:当外部有3D变换时,boundingClientRect可能不准确
75
+ // 因此我们使用ResizeObserver来监听尺寸变化,并直接比较scrollWidth和clientWidth
46
76
  observe.current = new IntersectionObserver(function (entries) {
47
- var entrie = entries[0];
48
- if (entrie.boundingClientRect.width <= entrie.rootBounds.width) {
49
- //表示文字全部可视
50
- cancelAnimationFrame(timer.current || 0);
51
- target.current.style.transform = "translate(0px,0px)"; //重置偏移
52
- setOverflow(false);
53
- return;
54
- } else {
55
- //否则文本溢出
56
- if (!overflow) {
57
- cancelAnimationFrame(timer.current || 0);
58
- startAnimation(entrie.target.offsetWidth);
59
- //startAnimation(entrie.boundingClientRect.width);
60
- setOverflow(true);
61
- }
62
- }
77
+ // 当元素进入或离开视口时,检查溢出状态
78
+ // 但实际的溢出判断使用checkOverflow函数,它直接比较DOM尺寸
79
+ checkOverflow();
63
80
  }, {
64
81
  root: rootRef.current,
65
82
  rootMargin: "0px 0px 0px 0px",
@@ -67,12 +84,28 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
67
84
  return i / 100;
68
85
  }) //这里设置了[0-1]之间所有的阈值,保证每一帧的变化都能被观察到
69
86
  });
87
+
88
+ // 使用ResizeObserver监听元素尺寸变化,这样即使有3D变换也能准确检测
89
+ var resizeObserver = new ResizeObserver(function () {
90
+ checkOverflow();
91
+ });
92
+
70
93
  // start observing
71
94
  observe.current.observe(target.current);
95
+ if (target.current) {
96
+ resizeObserver.observe(target.current);
97
+ }
98
+ if (rootRef.current) {
99
+ resizeObserver.observe(rootRef.current);
100
+ }
101
+
102
+ // 初始检查
103
+ checkOverflow();
72
104
  return function () {
73
105
  cancelAnimationFrame(timer.current || 0);
74
106
  observe.current.unobserve(target.current);
75
107
  observe.current.disconnect();
108
+ resizeObserver.disconnect();
76
109
  };
77
110
  }, []);
78
111
  var textList = [value, value];
@@ -30,21 +30,21 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
30
30
  needTitle = _config$needTitle === void 0 ? true : _config$needTitle;
31
31
  var getTextOverflow = function getTextOverflow(type) {
32
32
  switch (type) {
33
- case 'ellipsis':
33
+ case "ellipsis":
34
34
  return {
35
- overflow: 'hidden',
36
- textOverflow: 'ellipsis',
37
- whiteSpace: 'nowrap'
35
+ overflow: "hidden",
36
+ textOverflow: "ellipsis",
37
+ whiteSpace: "nowrap"
38
38
  };
39
- case 'break-word':
39
+ case "break-word":
40
40
  return {
41
- wordBreak: 'break-all',
42
- wordWrap: 'break-word',
41
+ wordBreak: "break-all",
42
+ wordWrap: "break-word",
43
43
  whiteSpace: "pre-line"
44
44
  };
45
- case 'marquee':
45
+ case "marquee":
46
46
  return {
47
- whiteSpace: 'nowrap'
47
+ whiteSpace: "nowrap"
48
48
  };
49
49
  default:
50
50
  return {};
@@ -54,7 +54,8 @@ var _default = exports["default"] = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(
54
54
  var textDom = document.createElement("div");
55
55
  textDom.innerHTML = value;
56
56
  var text = textDom.innerText;
57
- return type == 'marquee' ? /*#__PURE__*/_react["default"].createElement(_Marquee["default"], {
57
+ console.log(type);
58
+ return type == "marquee" ? /*#__PURE__*/_react["default"].createElement(_Marquee["default"], {
58
59
  value: value,
59
60
  speed: speed,
60
61
  style: styles,
@@ -94,7 +94,7 @@ var _default = exports["default"] = function _default(_ref) {
94
94
  type = _xAxis$config$label.format.type;
95
95
  if (type == "date" && autoSort) {
96
96
  x.sort(function (a, b) {
97
- return a > b ? 1 : -1;
97
+ return new Date(a).getTime() - new Date(b).getTime();
98
98
  });
99
99
  // const groupBySeries = group(data, (d) => d.s);
100
100
  // data=[...groupBySeries].flatMap(d=>{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easyv/charts",
3
- "version": "1.8.27",
3
+ "version": "1.8.29",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -1,101 +1,146 @@
1
- import React, { useEffect, memo, useRef, useState, forwardRef, CSSProperties } from "react";
1
+ import React, {
2
+ useEffect,
3
+ memo,
4
+ useRef,
5
+ useState,
6
+ forwardRef,
7
+ CSSProperties,
8
+ } from "react";
2
9
 
3
10
  /**
4
11
  * 文字跑马灯组件
5
12
  * eg: <Marquee value={文本内容} speed={跑马灯速度} style={额外样式}></Marquee>
6
13
  */
7
- interface marquee{
8
- value:string,
9
- style:CSSProperties,
10
- speed:number
14
+ interface marquee {
15
+ value: string;
16
+ style: CSSProperties;
17
+ speed: number;
11
18
  }
12
19
 
13
- export default memo(forwardRef((props:marquee, ref:any) => {
14
- const {
15
- value, // 文本
16
- style, // 样式
17
- speed = 5, // 动画速度
18
- } = props;
19
-
20
- const rootRef = ref || useRef();
21
- const target = useRef<any>(null);
22
- const observe = useRef<any>(null);
23
- const speed_ = useRef<number>(0); //这里必须用一个ref绑定speed,否则animation中获取不到最新的speed
24
- const timer = useRef<number>();
25
- const [overflow, setOverflow] = useState<boolean>(false);
26
- speed_.current = speed;
20
+ export default memo(
21
+ forwardRef((props: marquee, ref: any) => {
22
+ const {
23
+ value, // 文本
24
+ style, // 样式
25
+ speed = 5, // 动画速度
26
+ } = props;
27
27
 
28
- const startAnimation = (lineWidth:number)=>{
29
- const animation = (timestamp:number) => {
30
- let frame = Math.round(((timestamp*speed_.current)%(lineWidth*100))/100);
31
- target.current.style.transform = `translate(-${frame}px,0px)`;
32
- target.current.nextSibling.style.transform = `translate(-${frame}px,0px)`;
28
+ const rootRef = ref || useRef();
29
+ const target = useRef<any>(null);
30
+ const observe = useRef<any>(null);
31
+ const speed_ = useRef<number>(0); //这里必须用一个ref绑定speed,否则animation中获取不到最新的speed
32
+ const timer = useRef<number>();
33
+ const overflowRef = useRef<boolean>(false); // 使用ref来跟踪overflow状态,避免闭包问题
34
+ const [overflow, setOverflow] = useState<boolean>(false);
35
+ speed_.current = speed;
36
+
37
+ const startAnimation = (lineWidth: number) => {
38
+ const animation = (timestamp: number) => {
39
+ let frame = Math.round(
40
+ ((timestamp * speed_.current) % (lineWidth * 100)) / 100
41
+ );
42
+ target.current.style.transform = `translate(-${frame}px,0px)`;
43
+ target.current.nextSibling.style.transform = `translate(-${frame}px,0px)`;
44
+ timer.current = requestAnimationFrame(animation);
45
+ };
33
46
  timer.current = requestAnimationFrame(animation);
34
47
  };
35
- timer.current = requestAnimationFrame(animation);
36
- }
37
-
38
- useEffect(() => {
39
- //初始化观察器,利用观察器来监视组件可视区域变化
40
- observe.current = new IntersectionObserver(
41
- function (entries:any) {
42
- let entrie = entries[0];
43
- if (entrie.boundingClientRect.width <= entrie.rootBounds.width) {
44
- //表示文字全部可视
45
- cancelAnimationFrame(timer.current||0);
46
- target.current!.style.transform = "translate(0px,0px)"; //重置偏移
47
- setOverflow(false);
48
- return;
49
- } else {
50
- //否则文本溢出
51
- if (!overflow) {
52
- cancelAnimationFrame(timer.current || 0);
53
- startAnimation(entrie.target.offsetWidth);
54
- //startAnimation(entrie.boundingClientRect.width);
55
- setOverflow(true);
56
- }
48
+
49
+ // 检查文本是否溢出的函数
50
+ const checkOverflow = () => {
51
+ if (!target.current || !rootRef.current) return;
52
+
53
+ // 直接比较元素的实际内容宽度和容器的可见宽度
54
+ // scrollWidth 是元素内容的实际宽度(包括溢出部分)
55
+ // clientWidth 是元素可见区域的宽度
56
+ const textWidth = target.current.scrollWidth;
57
+ const containerWidth = rootRef.current.clientWidth;
58
+
59
+ if (textWidth <= containerWidth) {
60
+ console.log("文字全部可视");
61
+ //表示文字全部可视
62
+ cancelAnimationFrame(timer.current || 0);
63
+ target.current.style.transform = "translate(0px,0px)"; //重置偏移
64
+ overflowRef.current = false;
65
+ setOverflow(false);
66
+ } else {
67
+ //否则文本溢出
68
+ if (!overflowRef.current) {
69
+ cancelAnimationFrame(timer.current || 0);
70
+ startAnimation(textWidth);
71
+ overflowRef.current = true;
72
+ setOverflow(true);
57
73
  }
58
- },
59
- {
60
- root: rootRef.current,
61
- rootMargin: "0px 0px 0px 0px",
62
- threshold: new Array(101).fill(0).map((d, i) => i / 100), //这里设置了[0-1]之间所有的阈值,保证每一帧的变化都能被观察到
63
74
  }
64
- );
65
- // start observing
66
- observe.current.observe(target.current);
67
- return () => {
68
- cancelAnimationFrame(timer.current || 0);
69
- observe.current.unobserve(target.current);
70
- observe.current.disconnect();
71
75
  };
72
- }, []);
73
- let textList = [value, value];
74
- return (
75
- <div
76
- style={{
77
- width: "100%",
78
- ...style,
79
- display: "flex",
80
- whiteSpace: "nowrap",
81
- overflow: "hidden",
82
- justifyContent: overflow ? "start" : style.justifyContent || "",
83
- }}
84
- ref={rootRef}
85
- >
86
- {textList.map((item, i) => {
87
- return (
88
- <span
89
- key={i}
90
- ref={i == 0 ? target : null}
91
- style={{ display: i == 1 && !overflow ? "none" : "inline" }}
92
- dangerouslySetInnerHTML={{
93
- __html:item+(overflow?`<span>&nbsp;</span>`:"")
94
- }}
95
- >
96
- </span>
97
- );
98
- })}
99
- </div>
100
- );
101
- }));
76
+
77
+ useEffect(() => {
78
+ //初始化观察器,利用观察器来监视组件可视区域变化
79
+ // 注意:当外部有3D变换时,boundingClientRect可能不准确
80
+ // 因此我们使用ResizeObserver来监听尺寸变化,并直接比较scrollWidth和clientWidth
81
+ observe.current = new IntersectionObserver(
82
+ function (entries: any) {
83
+ // 当元素进入或离开视口时,检查溢出状态
84
+ // 但实际的溢出判断使用checkOverflow函数,它直接比较DOM尺寸
85
+ checkOverflow();
86
+ },
87
+ {
88
+ root: rootRef.current,
89
+ rootMargin: "0px 0px 0px 0px",
90
+ threshold: new Array(101).fill(0).map((d, i) => i / 100), //这里设置了[0-1]之间所有的阈值,保证每一帧的变化都能被观察到
91
+ }
92
+ );
93
+
94
+ // 使用ResizeObserver监听元素尺寸变化,这样即使有3D变换也能准确检测
95
+ const resizeObserver = new ResizeObserver(() => {
96
+ checkOverflow();
97
+ });
98
+
99
+ // start observing
100
+ observe.current.observe(target.current);
101
+ if (target.current) {
102
+ resizeObserver.observe(target.current);
103
+ }
104
+ if (rootRef.current) {
105
+ resizeObserver.observe(rootRef.current);
106
+ }
107
+
108
+ // 初始检查
109
+ checkOverflow();
110
+
111
+ return () => {
112
+ cancelAnimationFrame(timer.current || 0);
113
+ observe.current.unobserve(target.current);
114
+ observe.current.disconnect();
115
+ resizeObserver.disconnect();
116
+ };
117
+ }, []);
118
+ let textList = [value, value];
119
+ return (
120
+ <div
121
+ style={{
122
+ width: "100%",
123
+ ...style,
124
+ display: "flex",
125
+ whiteSpace: "nowrap",
126
+ overflow: "hidden",
127
+ justifyContent: overflow ? "start" : style.justifyContent || "",
128
+ }}
129
+ ref={rootRef}
130
+ >
131
+ {textList.map((item, i) => {
132
+ return (
133
+ <span
134
+ key={i}
135
+ ref={i == 0 ? target : null}
136
+ style={{ display: i == 1 && !overflow ? "none" : "inline" }}
137
+ dangerouslySetInnerHTML={{
138
+ __html: item + (overflow ? `<span>&nbsp;</span>` : ""),
139
+ }}
140
+ ></span>
141
+ );
142
+ })}
143
+ </div>
144
+ );
145
+ })
146
+ );
@@ -1,68 +1,74 @@
1
- import React, { memo, forwardRef, CSSProperties } from 'react';
2
- import Marquee from './Marquee'
1
+ import React, { memo, forwardRef, CSSProperties } from "react";
2
+ import Marquee from "./Marquee";
3
3
  /**
4
4
  * 文本溢出组件
5
5
  * eg: <TextOverflow type={溢出形式} value={文本内容} speed={跑马灯速度} style={额外样式}></Marquee>
6
6
  */
7
7
 
8
- interface flowText{
9
- type:string,
10
- value:string,
11
- speed:number,
12
- style:CSSProperties,
13
- config?:any,
14
- ShowType:string
8
+ interface flowText {
9
+ type: string;
10
+ value: string;
11
+ speed: number;
12
+ style: CSSProperties;
13
+ config?: any;
14
+ ShowType: string;
15
15
  }
16
16
 
17
- export default memo(forwardRef((props:flowText, ref:any) => {
18
- const {
19
- type, //形式:跑马灯marquee /省略号 ellipsis/换行 break-word
20
- value, // 文本
21
- style, // 样式
22
- speed = 5, // 动画速度
23
- config = {},
24
- ShowType
25
- } = props;
26
- const { needTitle = true } = config;
17
+ export default memo(
18
+ forwardRef((props: flowText, ref: any) => {
19
+ const {
20
+ type, //形式:跑马灯marquee /省略号 ellipsis/换行 break-word
21
+ value, // 文本
22
+ style, // 样式
23
+ speed = 5, // 动画速度
24
+ config = {},
25
+ ShowType,
26
+ } = props;
27
+ const { needTitle = true } = config;
27
28
 
28
- const getTextOverflow = (type:string):CSSProperties => {
29
- switch (type) {
30
- case 'ellipsis':
31
- return {
32
- overflow: 'hidden',
33
- textOverflow: 'ellipsis',
34
- whiteSpace: 'nowrap',
35
- };
36
- case 'break-word':
37
- return {
38
- wordBreak: 'break-all',
39
- wordWrap: 'break-word',
40
- whiteSpace: "pre-line"
41
- };
42
- case 'marquee':
43
- return {
44
- whiteSpace: 'nowrap',
45
- };
46
- default:
47
- return {}
48
- }
49
- };
29
+ const getTextOverflow = (type: string): CSSProperties => {
30
+ switch (type) {
31
+ case "ellipsis":
32
+ return {
33
+ overflow: "hidden",
34
+ textOverflow: "ellipsis",
35
+ whiteSpace: "nowrap",
36
+ };
37
+ case "break-word":
38
+ return {
39
+ wordBreak: "break-all",
40
+ wordWrap: "break-word",
41
+ whiteSpace: "pre-line",
42
+ };
43
+ case "marquee":
44
+ return {
45
+ whiteSpace: "nowrap",
46
+ };
47
+ default:
48
+ return {};
49
+ }
50
+ };
50
51
 
51
- const styles = {
52
- ...getTextOverflow(type),
53
- ...style
54
- }
55
- const textDom = document.createElement("div");
56
- textDom.innerHTML = value;
57
- const text = textDom.innerText;
58
- return type == 'marquee' ? (
59
- <Marquee
60
- value={value}
61
- speed={speed}
62
- style={styles}
63
- ref={ref} />
64
- ) : (
65
- <div style={{...styles,
66
- whiteSpace:ShowType=="Adaptive"?"normal":styles.whiteSpace}} ref={ref} title={needTitle && type=="ellipsis"?text || undefined:undefined} dangerouslySetInnerHTML={{__html:value}}></div>
67
- );
68
- }));
52
+ const styles = {
53
+ ...getTextOverflow(type),
54
+ ...style,
55
+ };
56
+ const textDom = document.createElement("div");
57
+ textDom.innerHTML = value;
58
+ const text = textDom.innerText;
59
+ console.log(type);
60
+ return type == "marquee" ? (
61
+ <Marquee value={value} speed={speed} style={styles} ref={ref} />
62
+ ) : (
63
+ <div
64
+ style={{
65
+ ...styles,
66
+ whiteSpace: ShowType == "Adaptive" ? "normal" : styles.whiteSpace,
67
+ }}
68
+ ref={ref}
69
+ title={needTitle && type == "ellipsis" ? text || undefined : undefined}
70
+ dangerouslySetInnerHTML={{ __html: value }}
71
+ ></div>
72
+ );
73
+ })
74
+ );
@@ -86,7 +86,7 @@ export default ({ axes, series, data }) => {
86
86
  },
87
87
  } = xAxis;
88
88
  if (type == "date" && autoSort) {
89
- x.sort((a, b) => (a > b ? 1 : -1));
89
+ x.sort((a, b) => new Date(a).getTime() - new Date(b).getTime());
90
90
  // const groupBySeries = group(data, (d) => d.s);
91
91
  // data=[...groupBySeries].flatMap(d=>{
92
92
  // return d[1].sort((a,b)=>a.x>b.x?1:-1)