@agions/taroviz 1.7.0 → 1.9.0
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.
- package/README.md +7 -3
- package/dist/cjs/index.js +1 -1
- package/dist/esm/index.js +384 -103
- package/package.json +1 -1
- package/src/adapters/__tests__/index.test.ts +4 -2
- package/src/adapters/h5/index.ts +16 -0
- package/src/adapters/types.ts +28 -120
- package/src/charts/common/BaseChartWrapper.tsx +193 -32
- package/src/charts/liquid/index.tsx +6 -5
- package/src/charts/liquid/types.ts +4 -4
- package/src/charts/types.ts +1 -1
- package/src/core/animation/AnimationManager.ts +69 -42
- package/src/core/components/BaseChart.tsx +72 -9
- package/src/core/types/common.ts +21 -110
- package/src/core/types/index.ts +4 -135
- package/src/core/types/platform.ts +38 -230
- package/src/core/utils/export/ExportUtils.ts +10 -1
- package/src/core/utils/performance/PerformanceAnalyzer.ts +21 -1
- package/src/core/utils/performance/types.ts +5 -0
- package/src/hooks/__tests__/index.test.tsx +7 -5
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useAnimation.ts +427 -0
- package/src/hooks/usePerformance.ts +291 -0
- package/src/themes/__tests__/index.test.ts +7 -13
package/dist/esm/index.js
CHANGED
|
@@ -346,6 +346,21 @@ var H5Adapter = /** @class */function () {
|
|
|
346
346
|
this.instance = null;
|
|
347
347
|
}
|
|
348
348
|
};
|
|
349
|
+
/**
|
|
350
|
+
* 触发图表行为
|
|
351
|
+
*/
|
|
352
|
+
H5Adapter.prototype.dispatchAction = function (payload) {
|
|
353
|
+
if (this.instance) {
|
|
354
|
+
this.instance.dispatchAction(payload);
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* 获取DataURL
|
|
359
|
+
*/
|
|
360
|
+
H5Adapter.prototype.getDataURL = function (opts) {
|
|
361
|
+
var _a;
|
|
362
|
+
return (_a = this.instance) === null || _a === void 0 ? void 0 : _a.getDataURL(opts);
|
|
363
|
+
};
|
|
349
364
|
/**
|
|
350
365
|
* 处理图表大小变化
|
|
351
366
|
*/
|
|
@@ -685,16 +700,12 @@ var ChartEventType;
|
|
|
685
700
|
ChartEventType["BRUSHSELECTED"] = "brushselected";
|
|
686
701
|
ChartEventType["RENDERED"] = "rendered";
|
|
687
702
|
ChartEventType["FINISHED"] = "finished";
|
|
688
|
-
// 自定义事件
|
|
689
703
|
ChartEventType["CHART_READY"] = "chartReady";
|
|
690
704
|
ChartEventType["CHART_RESIZE"] = "chartResize";
|
|
691
705
|
ChartEventType["CHART_ERROR"] = "chartError";
|
|
692
706
|
ChartEventType["CHART_DISPOSE"] = "chartDispose";
|
|
693
707
|
})(ChartEventType || (ChartEventType = {}));
|
|
694
708
|
;// ./src/core/types/platform.ts
|
|
695
|
-
/**
|
|
696
|
-
* 支持的平台类型
|
|
697
|
-
*/
|
|
698
709
|
var PlatformType;
|
|
699
710
|
(function (PlatformType) {
|
|
700
711
|
PlatformType["H5"] = "h5";
|
|
@@ -1579,43 +1590,171 @@ var __generator = undefined && undefined.__generator || function (thisArg, body)
|
|
|
1579
1590
|
/**
|
|
1580
1591
|
* 基础图表包装组件
|
|
1581
1592
|
* 提供统一的图表初始化、渲染和生命周期管理
|
|
1593
|
+
*
|
|
1594
|
+
* 无障碍支持 (WCAG):
|
|
1595
|
+
* - role="application" + keyboard navigation for zoom/pan
|
|
1596
|
+
* - Hidden data table with aria-live for screen readers
|
|
1597
|
+
* - Respects prefers-reduced-motion
|
|
1582
1598
|
*/
|
|
1583
1599
|
|
|
1584
1600
|
|
|
1585
1601
|
|
|
1586
1602
|
|
|
1587
|
-
/**
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1603
|
+
/** Extract series data from an ECharts option for screen reader exposure */
|
|
1604
|
+
function extractSeriesData(option) {
|
|
1605
|
+
var opt = option;
|
|
1606
|
+
if (!(opt === null || opt === void 0 ? void 0 : opt.series) || !Array.isArray(opt.series)) return [];
|
|
1607
|
+
return opt.series.filter(function (s) {
|
|
1608
|
+
return (s === null || s === void 0 ? void 0 : s.data) && Array.isArray(s.data);
|
|
1609
|
+
}).map(function (s) {
|
|
1610
|
+
return {
|
|
1611
|
+
name: s.name || '系列',
|
|
1612
|
+
data: s.data
|
|
1613
|
+
};
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
/** Build a human-readable aria-label from chart option */
|
|
1617
|
+
function buildAriaLabel(chartType, option) {
|
|
1618
|
+
var seriesData = extractSeriesData(option);
|
|
1619
|
+
if (!seriesData.length) {
|
|
1620
|
+
return chartType === 'chart' ? '空图表' : "".concat(chartType, " \u7A7A\u56FE\u8868");
|
|
1621
|
+
}
|
|
1622
|
+
var totalPoints = seriesData.reduce(function (sum, s) {
|
|
1623
|
+
return sum + s.data.length;
|
|
1624
|
+
}, 0);
|
|
1625
|
+
var seriesNames = seriesData.map(function (s) {
|
|
1626
|
+
return s.name;
|
|
1627
|
+
}).join('、');
|
|
1628
|
+
return "".concat(chartType, "\u56FE\u8868\uFF0C\u5305\u542B").concat(seriesData.length, "\u4E2A\u7CFB\u5217\uFF08").concat(seriesNames, "\uFF09\uFF0C\u5171").concat(totalPoints, "\u4E2A\u6570\u636E\u70B9");
|
|
1629
|
+
}
|
|
1630
|
+
// ─── Keyboard navigation step sizes ───────────────────────────────────────
|
|
1631
|
+
var ZOOM_STEP = 5; // % per key press
|
|
1632
|
+
var PAN_STEP = 10; // % pan per arrow key
|
|
1591
1633
|
var BaseChartWrapper = function (_a) {
|
|
1634
|
+
var _b, _c;
|
|
1592
1635
|
var option = _a.option,
|
|
1593
|
-
|
|
1594
|
-
width =
|
|
1595
|
-
|
|
1596
|
-
height =
|
|
1636
|
+
_d = _a.width,
|
|
1637
|
+
width = _d === void 0 ? '100%' : _d,
|
|
1638
|
+
_e = _a.height,
|
|
1639
|
+
height = _e === void 0 ? '300px' : _e,
|
|
1597
1640
|
theme = _a.theme,
|
|
1598
|
-
|
|
1599
|
-
style =
|
|
1600
|
-
|
|
1601
|
-
className =
|
|
1602
|
-
|
|
1603
|
-
autoResize =
|
|
1604
|
-
|
|
1605
|
-
loading =
|
|
1641
|
+
_f = _a.style,
|
|
1642
|
+
style = _f === void 0 ? {} : _f,
|
|
1643
|
+
_g = _a.className,
|
|
1644
|
+
className = _g === void 0 ? '' : _g,
|
|
1645
|
+
_h = _a.autoResize,
|
|
1646
|
+
autoResize = _h === void 0 ? true : _h,
|
|
1647
|
+
_j = _a.loading,
|
|
1648
|
+
loading = _j === void 0 ? false : _j,
|
|
1606
1649
|
loadingOption = _a.loadingOption,
|
|
1607
1650
|
onChartInit = _a.onChartInit,
|
|
1608
1651
|
onChartReady = _a.onChartReady,
|
|
1609
|
-
|
|
1610
|
-
renderer =
|
|
1611
|
-
|
|
1612
|
-
onEvents =
|
|
1613
|
-
|
|
1614
|
-
chartType =
|
|
1652
|
+
_k = _a.renderer,
|
|
1653
|
+
renderer = _k === void 0 ? 'canvas' : _k,
|
|
1654
|
+
_l = _a.onEvents,
|
|
1655
|
+
onEvents = _l === void 0 ? {} : _l,
|
|
1656
|
+
_m = _a.chartType,
|
|
1657
|
+
chartType = _m === void 0 ? 'chart' : _m;
|
|
1615
1658
|
var chartId = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)("".concat(chartType, "-").concat((0,_core_utils__WEBPACK_IMPORTED_MODULE_2__/* .uuid */ .uR)()));
|
|
1616
1659
|
var chartInstance = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
1617
1660
|
var containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
1618
|
-
|
|
1661
|
+
var isMountedRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(true);
|
|
1662
|
+
var cleanupRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
|
|
1663
|
+
var tableId = (0,react__WEBPACK_IMPORTED_MODULE_0__.useId)(); // unique id for aria-describedby
|
|
1664
|
+
var seriesData = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(function () {
|
|
1665
|
+
return extractSeriesData(option);
|
|
1666
|
+
}, [option]);
|
|
1667
|
+
var ariaLabel = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(function () {
|
|
1668
|
+
return buildAriaLabel(chartType, option);
|
|
1669
|
+
}, [chartType, option]);
|
|
1670
|
+
// Keyboard handler for zoom/pan — attached to the chart container
|
|
1671
|
+
var handleKeyDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function (e) {
|
|
1672
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1673
|
+
var instance = chartInstance.current;
|
|
1674
|
+
if (!instance) return;
|
|
1675
|
+
// ECharts dataZoom dispatch — works for any chart with dataZoom axis
|
|
1676
|
+
var dispatchZoom = function (startDelta, endDelta) {
|
|
1677
|
+
instance.dispatchAction({
|
|
1678
|
+
type: 'dataZoom',
|
|
1679
|
+
startDelta: startDelta,
|
|
1680
|
+
endDelta: endDelta
|
|
1681
|
+
});
|
|
1682
|
+
};
|
|
1683
|
+
// Home = reset zoom to full range
|
|
1684
|
+
if (e.key === 'Home') {
|
|
1685
|
+
e.preventDefault();
|
|
1686
|
+
instance.dispatchAction({
|
|
1687
|
+
type: 'dataZoom',
|
|
1688
|
+
start: 0,
|
|
1689
|
+
end: 100
|
|
1690
|
+
});
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
switch (e.key) {
|
|
1694
|
+
case '+':
|
|
1695
|
+
case '=':
|
|
1696
|
+
{
|
|
1697
|
+
e.preventDefault();
|
|
1698
|
+
// Zoom in (narrow range) — decrease end by ZOOM_STEP
|
|
1699
|
+
var end = instance.getOption();
|
|
1700
|
+
var dz = (_a = end === null || end === void 0 ? void 0 : end.dataZoom) === null || _a === void 0 ? void 0 : _a[0];
|
|
1701
|
+
if (dz) {
|
|
1702
|
+
var newEnd = Math.max(0, ((_b = dz.end) !== null && _b !== void 0 ? _b : 100) - ZOOM_STEP);
|
|
1703
|
+
var newStart = Math.max(0, ((_c = dz.start) !== null && _c !== void 0 ? _c : 0) - ZOOM_STEP);
|
|
1704
|
+
instance.dispatchAction({
|
|
1705
|
+
type: 'dataZoom',
|
|
1706
|
+
start: newStart,
|
|
1707
|
+
end: newEnd
|
|
1708
|
+
});
|
|
1709
|
+
}
|
|
1710
|
+
break;
|
|
1711
|
+
}
|
|
1712
|
+
case '-':
|
|
1713
|
+
case '_':
|
|
1714
|
+
{
|
|
1715
|
+
e.preventDefault();
|
|
1716
|
+
// Zoom out (expand range) — increase end by ZOOM_STEP
|
|
1717
|
+
var end = instance.getOption();
|
|
1718
|
+
var dz = (_d = end === null || end === void 0 ? void 0 : end.dataZoom) === null || _d === void 0 ? void 0 : _d[0];
|
|
1719
|
+
if (dz) {
|
|
1720
|
+
var newEnd = Math.min(100, ((_e = dz.end) !== null && _e !== void 0 ? _e : 100) + ZOOM_STEP);
|
|
1721
|
+
var newStart = Math.min(((_f = dz.start) !== null && _f !== void 0 ? _f : 0) + ZOOM_STEP, newEnd);
|
|
1722
|
+
instance.dispatchAction({
|
|
1723
|
+
type: 'dataZoom',
|
|
1724
|
+
start: newStart,
|
|
1725
|
+
end: newEnd
|
|
1726
|
+
});
|
|
1727
|
+
}
|
|
1728
|
+
break;
|
|
1729
|
+
}
|
|
1730
|
+
case 'ArrowLeft':
|
|
1731
|
+
{
|
|
1732
|
+
e.preventDefault();
|
|
1733
|
+
dispatchZoom(-PAN_STEP, 0);
|
|
1734
|
+
break;
|
|
1735
|
+
}
|
|
1736
|
+
case 'ArrowRight':
|
|
1737
|
+
{
|
|
1738
|
+
e.preventDefault();
|
|
1739
|
+
dispatchZoom(PAN_STEP, 0);
|
|
1740
|
+
break;
|
|
1741
|
+
}
|
|
1742
|
+
case 'ArrowUp':
|
|
1743
|
+
{
|
|
1744
|
+
e.preventDefault();
|
|
1745
|
+
dispatchZoom(0, -PAN_STEP);
|
|
1746
|
+
break;
|
|
1747
|
+
}
|
|
1748
|
+
case 'ArrowDown':
|
|
1749
|
+
{
|
|
1750
|
+
e.preventDefault();
|
|
1751
|
+
dispatchZoom(0, PAN_STEP);
|
|
1752
|
+
break;
|
|
1753
|
+
}
|
|
1754
|
+
// No default — let other keys pass through for accessibility tools
|
|
1755
|
+
}
|
|
1756
|
+
}, []);
|
|
1757
|
+
// Use memo to cache adapter config
|
|
1619
1758
|
var adapterConfig = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(function () {
|
|
1620
1759
|
return (0,_utils__WEBPACK_IMPORTED_MODULE_3__/* .processAdapterConfig */ .X)({
|
|
1621
1760
|
canvasId: chartId.current,
|
|
@@ -1628,8 +1767,9 @@ var BaseChartWrapper = function (_a) {
|
|
|
1628
1767
|
option: option
|
|
1629
1768
|
});
|
|
1630
1769
|
}, [width, height, theme, autoResize, renderer, option]);
|
|
1631
|
-
//
|
|
1770
|
+
// Handle chart initialization
|
|
1632
1771
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
1772
|
+
isMountedRef.current = true;
|
|
1633
1773
|
var initChart = function () {
|
|
1634
1774
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
1635
1775
|
var initConfig, adapter;
|
|
@@ -1638,18 +1778,21 @@ var BaseChartWrapper = function (_a) {
|
|
|
1638
1778
|
case 0:
|
|
1639
1779
|
initConfig = (0,_utils__WEBPACK_IMPORTED_MODULE_3__/* .processAdapterConfig */ .X)(__assign(__assign({}, adapterConfig), {
|
|
1640
1780
|
onInit: function (instance) {
|
|
1781
|
+
if (!isMountedRef.current) {
|
|
1782
|
+
instance.dispose();
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1641
1785
|
chartInstance.current = instance;
|
|
1642
|
-
// 绑定事件
|
|
1643
1786
|
if (onEvents) {
|
|
1644
|
-
Object.
|
|
1645
|
-
|
|
1787
|
+
Object.entries(onEvents).forEach(function (_a) {
|
|
1788
|
+
var eventName = _a[0],
|
|
1789
|
+
handler = _a[1];
|
|
1790
|
+
instance.on(eventName, handler);
|
|
1646
1791
|
});
|
|
1647
1792
|
}
|
|
1648
|
-
// 初始化回调
|
|
1649
1793
|
if (onChartInit) {
|
|
1650
1794
|
onChartInit(instance);
|
|
1651
1795
|
}
|
|
1652
|
-
// 准备好回调
|
|
1653
1796
|
if (onChartReady) {
|
|
1654
1797
|
onChartReady(instance);
|
|
1655
1798
|
}
|
|
@@ -1658,41 +1801,43 @@ var BaseChartWrapper = function (_a) {
|
|
|
1658
1801
|
return [4 /*yield*/, (0,_adapters__WEBPACK_IMPORTED_MODULE_1__/* .getAdapter */ .cK)(initConfig)];
|
|
1659
1802
|
case 1:
|
|
1660
1803
|
adapter = _a.sent();
|
|
1804
|
+
if (!isMountedRef.current) {
|
|
1805
|
+
return [2 /*return*/];
|
|
1806
|
+
}
|
|
1661
1807
|
adapter.init();
|
|
1662
|
-
|
|
1663
|
-
return [2 /*return*/, function () {
|
|
1808
|
+
cleanupRef.current = function () {
|
|
1664
1809
|
if (chartInstance.current) {
|
|
1665
|
-
// 解绑事件
|
|
1666
1810
|
if (onEvents) {
|
|
1667
|
-
Object.
|
|
1668
|
-
var _a;
|
|
1669
|
-
|
|
1811
|
+
Object.entries(onEvents).forEach(function (_a) {
|
|
1812
|
+
var eventName = _a[0];
|
|
1813
|
+
chartInstance.current.off(eventName);
|
|
1670
1814
|
});
|
|
1671
1815
|
}
|
|
1672
1816
|
chartInstance.current.dispose();
|
|
1673
1817
|
chartInstance.current = null;
|
|
1674
1818
|
}
|
|
1675
|
-
}
|
|
1819
|
+
};
|
|
1820
|
+
return [2 /*return*/];
|
|
1676
1821
|
}
|
|
1677
1822
|
});
|
|
1678
1823
|
});
|
|
1679
1824
|
};
|
|
1680
|
-
|
|
1681
|
-
var cleanupPromise = initChart();
|
|
1682
|
-
// 返回清理函数
|
|
1825
|
+
initChart();
|
|
1683
1826
|
return function () {
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1827
|
+
isMountedRef.current = false;
|
|
1828
|
+
if (cleanupRef.current) {
|
|
1829
|
+
cleanupRef.current();
|
|
1830
|
+
cleanupRef.current = null;
|
|
1831
|
+
}
|
|
1687
1832
|
};
|
|
1688
1833
|
}, [adapterConfig, onChartInit, onChartReady, onEvents]);
|
|
1689
|
-
//
|
|
1834
|
+
// Update config
|
|
1690
1835
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
1691
1836
|
if (chartInstance.current && option) {
|
|
1692
1837
|
chartInstance.current.setOption(option, true);
|
|
1693
1838
|
}
|
|
1694
1839
|
}, [option]);
|
|
1695
|
-
//
|
|
1840
|
+
// Loading state
|
|
1696
1841
|
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
|
|
1697
1842
|
if (chartInstance.current) {
|
|
1698
1843
|
if (loading) {
|
|
@@ -1702,16 +1847,51 @@ var BaseChartWrapper = function (_a) {
|
|
|
1702
1847
|
}
|
|
1703
1848
|
}
|
|
1704
1849
|
}, [loading, loadingOption]);
|
|
1705
|
-
//
|
|
1850
|
+
// Merged style
|
|
1706
1851
|
var mergedStyle = __assign({
|
|
1707
1852
|
width: typeof width === 'number' ? "".concat(width, "px") : width,
|
|
1708
1853
|
height: typeof height === 'number' ? "".concat(height, "px") : height
|
|
1709
1854
|
}, style);
|
|
1710
|
-
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("
|
|
1855
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("table", {
|
|
1856
|
+
id: tableId,
|
|
1857
|
+
"aria-label": "".concat(chartType, " \u56FE\u8868\u6570\u636E"),
|
|
1858
|
+
style: {
|
|
1859
|
+
position: 'absolute',
|
|
1860
|
+
width: 1,
|
|
1861
|
+
height: 1,
|
|
1862
|
+
overflow: 'hidden',
|
|
1863
|
+
clip: 'rect(0,0,0,0)',
|
|
1864
|
+
clipPath: 'inset(50%)',
|
|
1865
|
+
whiteSpace: 'nowrap'
|
|
1866
|
+
},
|
|
1867
|
+
"aria-live": "polite",
|
|
1868
|
+
"aria-atomic": "false"
|
|
1869
|
+
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("caption", null, ariaLabel), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("thead", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tr", null, seriesData.map(function (s, i) {
|
|
1870
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("th", {
|
|
1871
|
+
key: i,
|
|
1872
|
+
scope: "col"
|
|
1873
|
+
}, s.name);
|
|
1874
|
+
}))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tbody", null, Array.from({
|
|
1875
|
+
length: Math.min(20, (_c = (_b = seriesData[0]) === null || _b === void 0 ? void 0 : _b.data.length) !== null && _c !== void 0 ? _c : 0)
|
|
1876
|
+
}).map(function (_, rowIdx) {
|
|
1877
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tr", {
|
|
1878
|
+
key: rowIdx
|
|
1879
|
+
}, seriesData.map(function (s, colIdx) {
|
|
1880
|
+
var _a;
|
|
1881
|
+
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("td", {
|
|
1882
|
+
key: colIdx
|
|
1883
|
+
}, String((_a = s.data[rowIdx]) !== null && _a !== void 0 ? _a : ''));
|
|
1884
|
+
}));
|
|
1885
|
+
}))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
|
1711
1886
|
className: "taroviz-".concat(chartType, " ").concat(className),
|
|
1712
1887
|
style: mergedStyle,
|
|
1713
|
-
ref: containerRef
|
|
1714
|
-
|
|
1888
|
+
ref: containerRef,
|
|
1889
|
+
role: "application",
|
|
1890
|
+
"aria-label": ariaLabel,
|
|
1891
|
+
"aria-describedby": tableId,
|
|
1892
|
+
tabIndex: 0,
|
|
1893
|
+
onKeyDown: handleKeyDown
|
|
1894
|
+
}));
|
|
1715
1895
|
};
|
|
1716
1896
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BaseChartWrapper);
|
|
1717
1897
|
|
|
@@ -2212,20 +2392,31 @@ var __assign = undefined && undefined.__assign || function () {
|
|
|
2212
2392
|
return __assign.apply(this, arguments);
|
|
2213
2393
|
};
|
|
2214
2394
|
/**
|
|
2215
|
-
*
|
|
2395
|
+
* Checks the OS/browser prefers-reduced-motion setting.
|
|
2396
|
+
* Returns true if the user has requested reduced motion.
|
|
2397
|
+
*/
|
|
2398
|
+
function prefersReducedMotion() {
|
|
2399
|
+
if (typeof window === 'undefined') return false;
|
|
2400
|
+
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
2401
|
+
}
|
|
2402
|
+
/**
|
|
2403
|
+
* Professional animation presets following frontend-design-pro skill guidelines:
|
|
2404
|
+
* - Easing: cubic-bezier(0.16, 1, 0.3, 1) ("cubicOut") for natural deceleration
|
|
2405
|
+
* - Durations: 100-200ms micro, 300-500ms transitions, never >600ms
|
|
2406
|
+
* - NO bounce/elastic — anti-patterns that feel廉价 (cheap)
|
|
2216
2407
|
*/
|
|
2217
2408
|
var DEFAULT_ANIMATION_PRESETS = [{
|
|
2218
2409
|
name: 'default',
|
|
2219
|
-
description: '默认动画配置',
|
|
2410
|
+
description: '默认动画配置 — 专业级 (300-500ms, cubicOut)',
|
|
2220
2411
|
config: {
|
|
2221
2412
|
enabled: true,
|
|
2222
|
-
duration:
|
|
2413
|
+
duration: 400,
|
|
2223
2414
|
easing: 'cubicOut',
|
|
2224
|
-
appearDuration:
|
|
2415
|
+
appearDuration: 450,
|
|
2225
2416
|
appearEasing: 'cubicOut',
|
|
2226
|
-
updateDuration:
|
|
2417
|
+
updateDuration: 300,
|
|
2227
2418
|
updateEasing: 'cubicOut',
|
|
2228
|
-
disappearDuration:
|
|
2419
|
+
disappearDuration: 250,
|
|
2229
2420
|
disappearEasing: 'cubicIn',
|
|
2230
2421
|
threshold: 1000,
|
|
2231
2422
|
progressive: true,
|
|
@@ -2233,70 +2424,76 @@ var DEFAULT_ANIMATION_PRESETS = [{
|
|
|
2233
2424
|
}
|
|
2234
2425
|
}, {
|
|
2235
2426
|
name: 'fast',
|
|
2236
|
-
description: '快速动画配置',
|
|
2427
|
+
description: '快速动画配置 — 微交互 (150-200ms)',
|
|
2237
2428
|
config: {
|
|
2238
2429
|
enabled: true,
|
|
2239
|
-
duration:
|
|
2240
|
-
easing: '
|
|
2241
|
-
appearDuration:
|
|
2242
|
-
appearEasing: '
|
|
2243
|
-
updateDuration:
|
|
2244
|
-
updateEasing: '
|
|
2245
|
-
disappearDuration:
|
|
2246
|
-
disappearEasing: '
|
|
2430
|
+
duration: 150,
|
|
2431
|
+
easing: 'cubicOut',
|
|
2432
|
+
appearDuration: 200,
|
|
2433
|
+
appearEasing: 'cubicOut',
|
|
2434
|
+
updateDuration: 150,
|
|
2435
|
+
updateEasing: 'cubicOut',
|
|
2436
|
+
disappearDuration: 100,
|
|
2437
|
+
disappearEasing: 'cubicIn',
|
|
2247
2438
|
threshold: 2000,
|
|
2248
2439
|
progressive: true,
|
|
2249
2440
|
progressiveStep: 1000
|
|
2250
2441
|
}
|
|
2251
2442
|
}, {
|
|
2252
2443
|
name: 'slow',
|
|
2253
|
-
description: '慢速动画配置',
|
|
2444
|
+
description: '慢速动画配置 — 页面过渡 (500-600ms, capped)',
|
|
2254
2445
|
config: {
|
|
2255
2446
|
enabled: true,
|
|
2256
|
-
duration:
|
|
2447
|
+
duration: 500,
|
|
2257
2448
|
easing: 'cubicInOut',
|
|
2258
|
-
appearDuration:
|
|
2449
|
+
appearDuration: 600,
|
|
2259
2450
|
appearEasing: 'cubicInOut',
|
|
2260
|
-
updateDuration:
|
|
2451
|
+
updateDuration: 400,
|
|
2261
2452
|
updateEasing: 'cubicInOut',
|
|
2262
|
-
disappearDuration:
|
|
2453
|
+
disappearDuration: 300,
|
|
2263
2454
|
disappearEasing: 'cubicInOut',
|
|
2264
2455
|
threshold: 500,
|
|
2265
2456
|
progressive: true,
|
|
2266
2457
|
progressiveStep: 250
|
|
2267
2458
|
}
|
|
2268
|
-
},
|
|
2459
|
+
},
|
|
2460
|
+
// DEPRECATED — bounce is an anti-pattern per frontend-design-pro skill
|
|
2461
|
+
{
|
|
2269
2462
|
name: 'bounce',
|
|
2270
|
-
description: '
|
|
2463
|
+
description: '[已废弃] 弹跳动画 — 请使用 default 或 fast',
|
|
2271
2464
|
config: {
|
|
2272
|
-
enabled:
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2465
|
+
enabled: false,
|
|
2466
|
+
// disabled by default — anti-pattern
|
|
2467
|
+
duration: 0,
|
|
2468
|
+
easing: 'cubicOut',
|
|
2469
|
+
appearDuration: 0,
|
|
2470
|
+
appearEasing: 'cubicOut',
|
|
2471
|
+
updateDuration: 0,
|
|
2472
|
+
updateEasing: 'cubicOut',
|
|
2473
|
+
disappearDuration: 0,
|
|
2474
|
+
disappearEasing: 'cubicIn',
|
|
2281
2475
|
threshold: 500,
|
|
2282
|
-
progressive:
|
|
2476
|
+
progressive: false,
|
|
2283
2477
|
progressiveStep: 250
|
|
2284
2478
|
}
|
|
2285
|
-
},
|
|
2479
|
+
},
|
|
2480
|
+
// DEPRECATED — elastic is an anti-pattern per frontend-design-pro skill
|
|
2481
|
+
{
|
|
2286
2482
|
name: 'elastic',
|
|
2287
|
-
description: '
|
|
2483
|
+
description: '[已废弃] 弹性动画 — 请使用 default 或 fast',
|
|
2288
2484
|
config: {
|
|
2289
|
-
enabled:
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2485
|
+
enabled: false,
|
|
2486
|
+
// disabled by default — anti-pattern
|
|
2487
|
+
duration: 0,
|
|
2488
|
+
easing: 'cubicOut',
|
|
2489
|
+
appearDuration: 0,
|
|
2490
|
+
appearEasing: 'cubicOut',
|
|
2491
|
+
updateDuration: 0,
|
|
2492
|
+
updateEasing: 'cubicOut',
|
|
2493
|
+
disappearDuration: 0,
|
|
2494
|
+
disappearEasing: 'cubicIn',
|
|
2298
2495
|
threshold: 500,
|
|
2299
|
-
progressive:
|
|
2496
|
+
progressive: false,
|
|
2300
2497
|
progressiveStep: 250
|
|
2301
2498
|
}
|
|
2302
2499
|
}];
|
|
@@ -2392,6 +2589,7 @@ var AnimationManager = /** @class */function () {
|
|
|
2392
2589
|
};
|
|
2393
2590
|
/**
|
|
2394
2591
|
* 根据数据量和动画类型获取优化后的动画配置
|
|
2592
|
+
* 尊重 prefers-reduced-motion 无障碍设置
|
|
2395
2593
|
*/
|
|
2396
2594
|
AnimationManager.prototype.getOptimizedConfig = function (config, dataLength) {
|
|
2397
2595
|
if (config === void 0) {
|
|
@@ -2402,6 +2600,16 @@ var AnimationManager = /** @class */function () {
|
|
|
2402
2600
|
}
|
|
2403
2601
|
// 合并配置:用户配置 > 默认配置
|
|
2404
2602
|
var mergedConfig = __assign(__assign({}, this.defaultConfig), config);
|
|
2603
|
+
// Respect OS/browser prefers-reduced-motion setting (WCAG)
|
|
2604
|
+
if (prefersReducedMotion()) {
|
|
2605
|
+
return __assign(__assign({}, mergedConfig), {
|
|
2606
|
+
enabled: false,
|
|
2607
|
+
duration: 0,
|
|
2608
|
+
appearDuration: 0,
|
|
2609
|
+
updateDuration: 0,
|
|
2610
|
+
disappearDuration: 0
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2405
2613
|
// 根据数据量优化动画
|
|
2406
2614
|
if (mergedConfig.threshold && dataLength > mergedConfig.threshold) {
|
|
2407
2615
|
mergedConfig.enabled = false;
|
|
@@ -48788,9 +48996,18 @@ var PerformanceAnalyzer = /** @class */function () {
|
|
|
48788
48996
|
}
|
|
48789
48997
|
}
|
|
48790
48998
|
/**
|
|
48791
|
-
*
|
|
48999
|
+
* 获取实例
|
|
49000
|
+
* - 传入 chartId 时:每个 chartId 获得独立实例(指标隔离)
|
|
49001
|
+
* - 不传 chartId 时:全局单例(向后兼容)
|
|
48792
49002
|
*/
|
|
48793
49003
|
PerformanceAnalyzer.getInstance = function (config) {
|
|
49004
|
+
if (config === null || config === void 0 ? void 0 : config.chartId) {
|
|
49005
|
+
if (!PerformanceAnalyzer.instances.has(config.chartId)) {
|
|
49006
|
+
PerformanceAnalyzer.instances.set(config.chartId, new PerformanceAnalyzer(config));
|
|
49007
|
+
}
|
|
49008
|
+
return PerformanceAnalyzer.instances.get(config.chartId);
|
|
49009
|
+
}
|
|
49010
|
+
// Legacy: global singleton
|
|
48794
49011
|
if (!PerformanceAnalyzer.instance) {
|
|
48795
49012
|
PerformanceAnalyzer.instance = new PerformanceAnalyzer(config);
|
|
48796
49013
|
}
|
|
@@ -48805,6 +49022,16 @@ var PerformanceAnalyzer = /** @class */function () {
|
|
|
48805
49022
|
PerformanceAnalyzer.instance = null;
|
|
48806
49023
|
}
|
|
48807
49024
|
};
|
|
49025
|
+
/**
|
|
49026
|
+
* 重置所有图表实例(用于测试/清理)
|
|
49027
|
+
*/
|
|
49028
|
+
PerformanceAnalyzer.resetAllInstances = function () {
|
|
49029
|
+
PerformanceAnalyzer.resetInstance();
|
|
49030
|
+
PerformanceAnalyzer.instances.forEach(function (analyzer) {
|
|
49031
|
+
return analyzer.stop();
|
|
49032
|
+
});
|
|
49033
|
+
PerformanceAnalyzer.instances.clear();
|
|
49034
|
+
};
|
|
48808
49035
|
/**
|
|
48809
49036
|
* 注册事件处理器
|
|
48810
49037
|
*/
|
|
@@ -49215,6 +49442,8 @@ var PerformanceAnalyzer = /** @class */function () {
|
|
|
49215
49442
|
return this.analyze().score;
|
|
49216
49443
|
};
|
|
49217
49444
|
PerformanceAnalyzer.instance = null;
|
|
49445
|
+
// Per-chart isolated instances
|
|
49446
|
+
PerformanceAnalyzer.instances = new Map();
|
|
49218
49447
|
return PerformanceAnalyzer;
|
|
49219
49448
|
}();
|
|
49220
49449
|
|
|
@@ -49287,6 +49516,15 @@ var BaseChart_assign = undefined && undefined.__assign || function () {
|
|
|
49287
49516
|
};
|
|
49288
49517
|
return BaseChart_assign.apply(this, arguments);
|
|
49289
49518
|
};
|
|
49519
|
+
var BaseChart_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
|
|
49520
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
49521
|
+
if (ar || !(i in from)) {
|
|
49522
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
49523
|
+
ar[i] = from[i];
|
|
49524
|
+
}
|
|
49525
|
+
}
|
|
49526
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
49527
|
+
};
|
|
49290
49528
|
/**
|
|
49291
49529
|
* TaroViz 基础图表组件
|
|
49292
49530
|
* 所有图表组件的基类
|
|
@@ -49420,11 +49658,30 @@ var BaseChart = function (props) {
|
|
|
49420
49658
|
});
|
|
49421
49659
|
}
|
|
49422
49660
|
}
|
|
49661
|
+
// Inject dataZoom when enableZoom is true (keyboard-accessible zoom)
|
|
49662
|
+
if (_enableZoom) {
|
|
49663
|
+
processed = JSON.parse(JSON.stringify(processed));
|
|
49664
|
+
// Avoid duplicate dataZoom entries
|
|
49665
|
+
var existingDzArr = Array.isArray(processed.dataZoom) ? processed.dataZoom : processed.dataZoom ? [processed.dataZoom] : [];
|
|
49666
|
+
if (!existingDzArr.some(function (dz) {
|
|
49667
|
+
return (dz === null || dz === void 0 ? void 0 : dz.type) === 'inside';
|
|
49668
|
+
})) {
|
|
49669
|
+
processed.dataZoom = BaseChart_spreadArray(BaseChart_spreadArray([], existingDzArr || [], true), [
|
|
49670
|
+
// Inside (mouse wheel + keyboard) — wired to keyboard nav in BaseChartWrapper
|
|
49671
|
+
{
|
|
49672
|
+
type: 'inside',
|
|
49673
|
+
start: 0,
|
|
49674
|
+
end: 100,
|
|
49675
|
+
zoomOnMouseWheel: true,
|
|
49676
|
+
moveOnMouseMove: false
|
|
49677
|
+
}], false);
|
|
49678
|
+
}
|
|
49679
|
+
}
|
|
49423
49680
|
// Apply animation config
|
|
49424
49681
|
var dataLength = calculateDataLength(processed);
|
|
49425
49682
|
var animConfig = (0,core_animation/* generateEChartsAnimationConfig */.ek)(animation, dataLength);
|
|
49426
49683
|
return BaseChart_assign(BaseChart_assign({}, processed), animConfig);
|
|
49427
|
-
}, [option, animation, enableDataFiltering, filters, virtualScroll, virtualScrollPageSize, virtualScrollPreloadSize, onDataFiltered]);
|
|
49684
|
+
}, [option, animation, _enableZoom, enableDataFiltering, filters, virtualScroll, virtualScrollPageSize, virtualScrollPreloadSize, onDataFiltered]);
|
|
49428
49685
|
// Internal chartInit that wraps the user's callback
|
|
49429
49686
|
var handleChartInit = (0,external_react_.useCallback)(function (instance) {
|
|
49430
49687
|
var _a;
|
|
@@ -49433,6 +49690,7 @@ var BaseChart = function (props) {
|
|
|
49433
49690
|
// Performance monitoring init
|
|
49434
49691
|
if (enablePerformanceMonitoring) {
|
|
49435
49692
|
performanceAnalyzerRef.current = PerformanceAnalyzer.getInstance({
|
|
49693
|
+
chartId: chartId,
|
|
49436
49694
|
enabled: true,
|
|
49437
49695
|
metrics: ['initTime', 'renderTime', 'updateTime', 'dataSize', 'frameRate'],
|
|
49438
49696
|
sampleInterval: 1000,
|
|
@@ -49588,15 +49846,36 @@ var BaseChart = function (props) {
|
|
|
49588
49846
|
});
|
|
49589
49847
|
}
|
|
49590
49848
|
}, [option, onPerformance]);
|
|
49591
|
-
// Data update callback
|
|
49849
|
+
// Data update callback — supports debounce
|
|
49850
|
+
var debounceTimerRef = (0,external_react_.useRef)(null);
|
|
49592
49851
|
(0,external_react_.useEffect)(function () {
|
|
49593
|
-
|
|
49852
|
+
var _a;
|
|
49853
|
+
if (!onDataUpdate || (dataUpdateOptions === null || dataUpdateOptions === void 0 ? void 0 : dataUpdateOptions.enabled) === false) return;
|
|
49854
|
+
var delay = (_a = dataUpdateOptions === null || dataUpdateOptions === void 0 ? void 0 : dataUpdateOptions.debounceDelay) !== null && _a !== void 0 ? _a : 0;
|
|
49855
|
+
if (debounceTimerRef.current) {
|
|
49856
|
+
clearTimeout(debounceTimerRef.current);
|
|
49857
|
+
}
|
|
49858
|
+
if (delay > 0) {
|
|
49859
|
+
debounceTimerRef.current = setTimeout(function () {
|
|
49860
|
+
var oldOpt = oldOptionRef.current;
|
|
49861
|
+
if (oldOpt !== option) {
|
|
49862
|
+
onDataUpdate(oldOpt, option);
|
|
49863
|
+
oldOptionRef.current = option;
|
|
49864
|
+
}
|
|
49865
|
+
}, delay);
|
|
49866
|
+
} else {
|
|
49594
49867
|
var oldOpt = oldOptionRef.current;
|
|
49595
49868
|
if (oldOpt !== option) {
|
|
49596
49869
|
onDataUpdate(oldOpt, option);
|
|
49597
49870
|
oldOptionRef.current = option;
|
|
49598
49871
|
}
|
|
49599
49872
|
}
|
|
49873
|
+
return function () {
|
|
49874
|
+
if (debounceTimerRef.current) {
|
|
49875
|
+
clearTimeout(debounceTimerRef.current);
|
|
49876
|
+
debounceTimerRef.current = null;
|
|
49877
|
+
}
|
|
49878
|
+
};
|
|
49600
49879
|
}, [option, onDataUpdate, dataUpdateOptions]);
|
|
49601
49880
|
// Cleanup on unmount
|
|
49602
49881
|
(0,external_react_.useEffect)(function () {
|
|
@@ -50957,8 +51236,10 @@ var LiquidChart = /*#__PURE__*/(0,external_react_.memo)(function (props) {
|
|
|
50957
51236
|
chartInstance.current = instance;
|
|
50958
51237
|
// 绑定事件
|
|
50959
51238
|
if (onEvents) {
|
|
50960
|
-
Object.
|
|
50961
|
-
|
|
51239
|
+
Object.entries(onEvents).forEach(function (_a) {
|
|
51240
|
+
var eventName = _a[0],
|
|
51241
|
+
handler = _a[1];
|
|
51242
|
+
instance.on(eventName, handler);
|
|
50962
51243
|
});
|
|
50963
51244
|
}
|
|
50964
51245
|
if (onChartInit) {
|
|
@@ -56695,7 +56976,7 @@ function useChartTheme(theme, darkMode) {
|
|
|
56695
56976
|
*/
|
|
56696
56977
|
function useChartData(data, transformer) {
|
|
56697
56978
|
return (0,external_react_.useMemo)(function () {
|
|
56698
|
-
if (!data) {
|
|
56979
|
+
if (!data || Array.isArray(data) && data.length === 0) {
|
|
56699
56980
|
return {};
|
|
56700
56981
|
}
|
|
56701
56982
|
return transformer(data);
|