@agions/taroviz 1.7.0 → 1.10.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 +960 -136
- 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/boxplot/types.ts +5 -3
- 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/parallel/types.ts +6 -3
- package/src/charts/tree/types.ts +4 -4
- package/src/charts/types.ts +1 -1
- package/src/core/animation/AnimationManager.ts +69 -42
- package/src/core/components/Annotation.tsx +12 -10
- package/src/core/components/BaseChart.tsx +75 -12
- package/src/core/components/ErrorBoundary.tsx +30 -17
- package/src/core/components/LazyChart.tsx +14 -9
- package/src/core/themes/ThemeManager.ts +33 -0
- 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/chartUtils.ts +8 -3
- 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 +23 -1
- package/src/hooks/useAnimation.ts +427 -0
- package/src/hooks/useChartHistory.ts +273 -0
- package/src/hooks/useChartSelection.ts +350 -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
|
|
|
@@ -49264,12 +49493,12 @@ function calculateDataLength(option) {
|
|
|
49264
49493
|
function filterDataByKeys(data, filters) {
|
|
49265
49494
|
if (!filters || Object.keys(filters).length === 0) return data;
|
|
49266
49495
|
return data.filter(function (item) {
|
|
49267
|
-
var
|
|
49268
|
-
|
|
49269
|
-
|
|
49270
|
-
|
|
49271
|
-
|
|
49272
|
-
if (
|
|
49496
|
+
for (var _i = 0, _a = Object.entries(filters); _i < _a.length; _i++) {
|
|
49497
|
+
var _b = _a[_i],
|
|
49498
|
+
key = _b[0],
|
|
49499
|
+
value = _b[1];
|
|
49500
|
+
var itemVal = item[key];
|
|
49501
|
+
if (itemVal !== value && !(Array.isArray(itemVal) && itemVal.includes(value))) return false;
|
|
49273
49502
|
}
|
|
49274
49503
|
return true;
|
|
49275
49504
|
});
|
|
@@ -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) {
|
|
@@ -52205,6 +52486,38 @@ var ThemeManager = /** @class */function () {
|
|
|
52205
52486
|
ThemeManager.prototype.isDarkMode = function () {
|
|
52206
52487
|
return this.currentTheme.isDark || this.currentTheme.type === 'dark';
|
|
52207
52488
|
};
|
|
52489
|
+
/**
|
|
52490
|
+
* 检测系统 prefers-color-scheme 是否为暗色
|
|
52491
|
+
*/
|
|
52492
|
+
ThemeManager.prototype.getSystemPrefersDark = function () {
|
|
52493
|
+
if (typeof window === 'undefined') return false;
|
|
52494
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
52495
|
+
};
|
|
52496
|
+
/**
|
|
52497
|
+
* 订阅系统主题变化,自动切换匹配的主题
|
|
52498
|
+
* @returns 取消订阅的函数
|
|
52499
|
+
*/
|
|
52500
|
+
ThemeManager.prototype.watchSystemTheme = function () {
|
|
52501
|
+
var _this = this;
|
|
52502
|
+
if (typeof window === 'undefined') return function () {};
|
|
52503
|
+
var mq = window.matchMedia('(prefers-color-scheme: dark)');
|
|
52504
|
+
var handler = function (e) {
|
|
52505
|
+
// 当系统主题切换时,自动应用对应主题
|
|
52506
|
+
_this.setTheme(e.matches ? 'dark' : 'default');
|
|
52507
|
+
};
|
|
52508
|
+
mq.addEventListener('change', handler);
|
|
52509
|
+
return function () {
|
|
52510
|
+
return mq.removeEventListener('change', handler);
|
|
52511
|
+
};
|
|
52512
|
+
};
|
|
52513
|
+
/**
|
|
52514
|
+
* 应用初始主题(根据系统偏好自动选择 dark/default)
|
|
52515
|
+
* 必须在 DOM 加载后调用
|
|
52516
|
+
*/
|
|
52517
|
+
ThemeManager.prototype.applyInitialTheme = function () {
|
|
52518
|
+
var prefersDark = this.getSystemPrefersDark();
|
|
52519
|
+
this.setTheme(prefersDark ? 'dark' : 'default');
|
|
52520
|
+
};
|
|
52208
52521
|
/**
|
|
52209
52522
|
* 注册主题变更监听器
|
|
52210
52523
|
*/
|
|
@@ -53561,51 +53874,58 @@ var ErrorBoundary = /** @class */function (_super) {
|
|
|
53561
53874
|
if (fallback) {
|
|
53562
53875
|
return fallback(error, this.handleReset);
|
|
53563
53876
|
}
|
|
53564
|
-
//
|
|
53877
|
+
// 默认错误展示(使用 CSS 变量,与 ThemeManager 对齐)
|
|
53565
53878
|
return /*#__PURE__*/external_react_default().createElement("div", {
|
|
53879
|
+
role: "alert",
|
|
53880
|
+
"aria-live": "assertive",
|
|
53566
53881
|
style: {
|
|
53567
53882
|
display: 'flex',
|
|
53568
53883
|
flexDirection: 'column',
|
|
53569
53884
|
alignItems: 'center',
|
|
53570
53885
|
justifyContent: 'center',
|
|
53571
|
-
padding: '
|
|
53572
|
-
backgroundColor: '#fff',
|
|
53573
|
-
border: '1px solid #ff4d4f',
|
|
53574
|
-
borderRadius: '8px',
|
|
53575
|
-
color: '#333',
|
|
53576
|
-
minHeight: '200px'
|
|
53886
|
+
padding: 'var(--tv-border-radius, 16px)',
|
|
53887
|
+
backgroundColor: 'var(--tv-bg-color, #fff)',
|
|
53888
|
+
border: '1px solid var(--tv-error-color, #ff4d4f)',
|
|
53889
|
+
borderRadius: 'var(--tv-border-radius, 8px)',
|
|
53890
|
+
color: 'var(--tv-text-color, #333)',
|
|
53891
|
+
minHeight: '200px',
|
|
53892
|
+
fontFamily: 'var(--tv-font-family, sans-serif)'
|
|
53577
53893
|
}
|
|
53578
53894
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
53579
53895
|
style: {
|
|
53580
53896
|
fontSize: '48px',
|
|
53581
53897
|
marginBottom: '16px'
|
|
53582
|
-
}
|
|
53898
|
+
},
|
|
53899
|
+
"aria-hidden": "true"
|
|
53583
53900
|
}, "\u26A0\uFE0F"), /*#__PURE__*/external_react_default().createElement("h3", {
|
|
53584
53901
|
style: {
|
|
53585
53902
|
margin: '0 0 12px',
|
|
53586
|
-
color: '#ff4d4f'
|
|
53903
|
+
color: 'var(--tv-error-color, #ff4d4f)',
|
|
53904
|
+
fontWeight: 700
|
|
53587
53905
|
}
|
|
53588
53906
|
}, "\u56FE\u8868\u6E32\u67D3\u5931\u8D25"), /*#__PURE__*/external_react_default().createElement("p", {
|
|
53589
53907
|
style: {
|
|
53590
53908
|
margin: '0 0 16px',
|
|
53591
|
-
color: '#666',
|
|
53592
|
-
textAlign: 'center'
|
|
53909
|
+
color: 'var(--tv-text-color-secondary, #666)',
|
|
53910
|
+
textAlign: 'center',
|
|
53911
|
+
maxWidth: '320px'
|
|
53593
53912
|
}
|
|
53594
53913
|
}, "\u56FE\u8868\u5728\u6E32\u67D3\u8FC7\u7A0B\u4E2D\u9047\u5230\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u6570\u636E\u914D\u7F6E\u662F\u5426\u6B63\u786E"), showDetails && (/*#__PURE__*/external_react_default().createElement("details", {
|
|
53595
53914
|
style: {
|
|
53596
53915
|
width: '100%',
|
|
53597
53916
|
padding: '12px',
|
|
53598
|
-
backgroundColor: '#f5f5f5',
|
|
53599
|
-
borderRadius: '4px',
|
|
53600
|
-
fontSize: '12px',
|
|
53601
|
-
fontFamily: 'monospace',
|
|
53917
|
+
backgroundColor: 'var(--tv-bg-color-secondary, #f5f5f5)',
|
|
53918
|
+
borderRadius: 'var(--tv-border-radius-small, 4px)',
|
|
53919
|
+
fontSize: 'var(--tv-font-size-small, 12px)',
|
|
53920
|
+
fontFamily: 'var(--tv-font-family, monospace)',
|
|
53602
53921
|
overflow: 'auto',
|
|
53603
53922
|
maxHeight: '150px'
|
|
53604
53923
|
}
|
|
53605
53924
|
}, /*#__PURE__*/external_react_default().createElement("summary", {
|
|
53606
53925
|
style: {
|
|
53607
53926
|
cursor: 'pointer',
|
|
53608
|
-
marginBottom: '8px'
|
|
53927
|
+
marginBottom: '8px',
|
|
53928
|
+
fontWeight: 600
|
|
53609
53929
|
}
|
|
53610
53930
|
}, "\u9519\u8BEF\u8BE6\u60C5"), /*#__PURE__*/external_react_default().createElement("pre", {
|
|
53611
53931
|
style: {
|
|
@@ -53618,12 +53938,20 @@ var ErrorBoundary = /** @class */function (_super) {
|
|
|
53618
53938
|
style: {
|
|
53619
53939
|
marginTop: '16px',
|
|
53620
53940
|
padding: '8px 24px',
|
|
53621
|
-
backgroundColor: '#1890ff',
|
|
53941
|
+
backgroundColor: 'var(--tv-primary-color, #1890ff)',
|
|
53622
53942
|
color: '#fff',
|
|
53623
53943
|
border: 'none',
|
|
53624
|
-
borderRadius: '4px',
|
|
53944
|
+
borderRadius: 'var(--tv-border-radius-small, 4px)',
|
|
53625
53945
|
cursor: 'pointer',
|
|
53626
|
-
fontSize: '14px'
|
|
53946
|
+
fontSize: 'var(--tv-font-size, 14px)',
|
|
53947
|
+
fontWeight: 600,
|
|
53948
|
+
transition: 'background-color var(--tv-transition-duration, 0.3s)'
|
|
53949
|
+
},
|
|
53950
|
+
onMouseEnter: function (e) {
|
|
53951
|
+
e.currentTarget.style.backgroundColor = 'var(--tv-primary-color-hover, #40a9ff)';
|
|
53952
|
+
},
|
|
53953
|
+
onMouseLeave: function (e) {
|
|
53954
|
+
e.currentTarget.style.backgroundColor = 'var(--tv-primary-color, #1890ff)';
|
|
53627
53955
|
}
|
|
53628
53956
|
}, "\u91CD\u8BD5"));
|
|
53629
53957
|
}
|
|
@@ -53742,12 +54070,14 @@ var LAZY_CHART_MODULES = {
|
|
|
53742
54070
|
};
|
|
53743
54071
|
var LAZY_CHART_TYPES = Object.keys(LAZY_CHART_MODULES);
|
|
53744
54072
|
/**
|
|
53745
|
-
*
|
|
54073
|
+
* 默认加载状态组件(使用 CSS 变量,与 ThemeManager 对齐)
|
|
53746
54074
|
*/
|
|
53747
54075
|
var DefaultLoadingFallback = function (_a) {
|
|
53748
54076
|
var _b = _a.text,
|
|
53749
54077
|
text = _b === void 0 ? '加载中...' : _b;
|
|
53750
54078
|
return /*#__PURE__*/external_react_default().createElement("div", {
|
|
54079
|
+
role: "status",
|
|
54080
|
+
"aria-label": text,
|
|
53751
54081
|
style: {
|
|
53752
54082
|
display: 'flex',
|
|
53753
54083
|
alignItems: 'center',
|
|
@@ -53755,8 +54085,8 @@ var DefaultLoadingFallback = function (_a) {
|
|
|
53755
54085
|
width: '100%',
|
|
53756
54086
|
height: '100%',
|
|
53757
54087
|
minHeight: '200px',
|
|
53758
|
-
backgroundColor: '#f5f5f5',
|
|
53759
|
-
borderRadius: '8px'
|
|
54088
|
+
backgroundColor: 'var(--tv-bg-color-secondary, #f5f5f5)',
|
|
54089
|
+
borderRadius: 'var(--tv-border-radius, 8px)'
|
|
53760
54090
|
}
|
|
53761
54091
|
}, /*#__PURE__*/external_react_default().createElement("div", {
|
|
53762
54092
|
style: {
|
|
@@ -53766,16 +54096,17 @@ var DefaultLoadingFallback = function (_a) {
|
|
|
53766
54096
|
style: {
|
|
53767
54097
|
width: '40px',
|
|
53768
54098
|
height: '40px',
|
|
53769
|
-
border: '3px solid #1890ff',
|
|
54099
|
+
border: '3px solid var(--tv-primary-color, #1890ff)',
|
|
53770
54100
|
borderTopColor: 'transparent',
|
|
53771
54101
|
borderRadius: '50%',
|
|
53772
54102
|
animation: 'taroviz-spin 1s linear infinite',
|
|
53773
54103
|
margin: '0 auto 12px'
|
|
53774
|
-
}
|
|
54104
|
+
},
|
|
54105
|
+
"aria-hidden": "true"
|
|
53775
54106
|
}), /*#__PURE__*/external_react_default().createElement("style", null, "\n @keyframes taroviz-spin {\n to { transform: rotate(360deg); }\n }\n "), /*#__PURE__*/external_react_default().createElement("span", {
|
|
53776
54107
|
style: {
|
|
53777
|
-
color: '#666',
|
|
53778
|
-
fontSize: '14px'
|
|
54108
|
+
color: 'var(--tv-text-color-secondary, #666)',
|
|
54109
|
+
fontSize: 'var(--tv-font-size, 14px)'
|
|
53779
54110
|
}
|
|
53780
54111
|
}, text)));
|
|
53781
54112
|
};
|
|
@@ -55868,6 +56199,491 @@ function useChartDownload(instance, options) {
|
|
|
55868
56199
|
// 导出
|
|
55869
56200
|
// ============================================================================
|
|
55870
56201
|
/* harmony default export */ const hooks_useChartDownload = ((/* unused pure expression or super */ null && (useChartDownload)));
|
|
56202
|
+
;// ./src/hooks/useChartHistory.ts
|
|
56203
|
+
var useChartHistory_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
|
|
56204
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
56205
|
+
if (ar || !(i in from)) {
|
|
56206
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
56207
|
+
ar[i] = from[i];
|
|
56208
|
+
}
|
|
56209
|
+
}
|
|
56210
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56211
|
+
};
|
|
56212
|
+
/**
|
|
56213
|
+
* useChartHistory - 图表 Undo/Redo Hook
|
|
56214
|
+
* 追踪图表配置历史,支持撤销/重做操作和键盘快捷键
|
|
56215
|
+
*
|
|
56216
|
+
* 特性:
|
|
56217
|
+
* - 最多保存 50 条历史记录(可配置)
|
|
56218
|
+
* - 自动绑定 Ctrl+Z / Ctrl+Y 键盘快捷键
|
|
56219
|
+
* - 支持 ignoreKeys 忽略特定配置字段(如动画、时间戳)
|
|
56220
|
+
* - 暴露 canUndo / canRedo 状态
|
|
56221
|
+
*/
|
|
56222
|
+
|
|
56223
|
+
// ============================================================================
|
|
56224
|
+
// 工具函数
|
|
56225
|
+
// ============================================================================
|
|
56226
|
+
/** 深度省略指定键后比较两个配置是否相等 */
|
|
56227
|
+
function omitAndCompare(a, b, ignoreKeys) {
|
|
56228
|
+
if (a === b) return true;
|
|
56229
|
+
if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
|
|
56230
|
+
return a === b;
|
|
56231
|
+
}
|
|
56232
|
+
var aObj = a;
|
|
56233
|
+
var bObj = b;
|
|
56234
|
+
var aKeys = Object.keys(aObj).filter(function (k) {
|
|
56235
|
+
return !ignoreKeys.has(k);
|
|
56236
|
+
});
|
|
56237
|
+
var bKeys = Object.keys(bObj).filter(function (k) {
|
|
56238
|
+
return !ignoreKeys.has(k);
|
|
56239
|
+
});
|
|
56240
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
56241
|
+
for (var _i = 0, aKeys_1 = aKeys; _i < aKeys_1.length; _i++) {
|
|
56242
|
+
var key = aKeys_1[_i];
|
|
56243
|
+
if (!bObj.hasOwnProperty(key)) return false;
|
|
56244
|
+
if (!omitAndCompare(aObj[key], bObj[key], ignoreKeys)) return false;
|
|
56245
|
+
}
|
|
56246
|
+
return true;
|
|
56247
|
+
}
|
|
56248
|
+
// ============================================================================
|
|
56249
|
+
// Hook 实现
|
|
56250
|
+
// ============================================================================
|
|
56251
|
+
/**
|
|
56252
|
+
* 使用图表历史记录(Undo/Redo)
|
|
56253
|
+
* @param chartInstance 图表实例
|
|
56254
|
+
* @param options 配置选项
|
|
56255
|
+
* @returns 历史记录控制接口
|
|
56256
|
+
*/
|
|
56257
|
+
function useChartHistory(chartInstance, options) {
|
|
56258
|
+
if (options === void 0) {
|
|
56259
|
+
options = {};
|
|
56260
|
+
}
|
|
56261
|
+
var _a = options.maxHistorySize,
|
|
56262
|
+
maxHistorySize = _a === void 0 ? 50 : _a,
|
|
56263
|
+
_b = options.ignoreKeys,
|
|
56264
|
+
ignoreKeys = _b === void 0 ? ['animation', 'animationDuration', 'animationEasing', 'animationFrame'] : _b,
|
|
56265
|
+
_c = options.enableKeyboard,
|
|
56266
|
+
enableKeyboard = _c === void 0 ? true : _c,
|
|
56267
|
+
_d = options.clearOnUnmount,
|
|
56268
|
+
clearOnUnmount = _d === void 0 ? false : _d;
|
|
56269
|
+
// 忽略键集合
|
|
56270
|
+
var ignoreKeySet = (0,external_react_.useRef)(new Set(ignoreKeys));
|
|
56271
|
+
// 历史栈(每次 setOption 快照)
|
|
56272
|
+
var historyStack = (0,external_react_.useRef)([]);
|
|
56273
|
+
// 当前索引
|
|
56274
|
+
var _e = (0,external_react_.useState)(-1),
|
|
56275
|
+
currentIndex = _e[0],
|
|
56276
|
+
setCurrentIndex = _e[1];
|
|
56277
|
+
// Chart instance ref
|
|
56278
|
+
var chartRef = (0,external_react_.useRef)(null);
|
|
56279
|
+
chartRef.current = chartInstance;
|
|
56280
|
+
// 是否正在执行 undo/redo(避免 push 时重复记录)
|
|
56281
|
+
var isApplyingRef = (0,external_react_.useRef)(false);
|
|
56282
|
+
// 拦截 chart.setOption,记录历史
|
|
56283
|
+
(0,external_react_.useEffect)(function () {
|
|
56284
|
+
var chart = chartRef.current;
|
|
56285
|
+
if (!chart) return;
|
|
56286
|
+
var originalSetOption = chart.setOption.bind(chart);
|
|
56287
|
+
chart.setOption = function (option, notMerge, lazyUpdate) {
|
|
56288
|
+
// 如果正在执行 undo/redo,跳过历史记录
|
|
56289
|
+
if (isApplyingRef.current) {
|
|
56290
|
+
return originalSetOption(option, notMerge, lazyUpdate);
|
|
56291
|
+
}
|
|
56292
|
+
var stack = historyStack.current;
|
|
56293
|
+
var idx = currentIndex;
|
|
56294
|
+
// 如果当前索引不在栈顶,丢弃redo历史(类似 Git 行为)
|
|
56295
|
+
var newStack = idx < stack.length - 1 ? stack.slice(0, idx + 1) : useChartHistory_spreadArray([], stack, true);
|
|
56296
|
+
// 检查是否与上一次配置相同(忽略动画字段)
|
|
56297
|
+
var lastOption = newStack[newStack.length - 1];
|
|
56298
|
+
if (lastOption && omitAndCompare(lastOption, option, ignoreKeySet.current)) {
|
|
56299
|
+
// 配置没变,直接应用
|
|
56300
|
+
return originalSetOption(option, notMerge, lazyUpdate);
|
|
56301
|
+
}
|
|
56302
|
+
// 入栈
|
|
56303
|
+
newStack.push(option);
|
|
56304
|
+
// 裁剪超出 maxHistorySize
|
|
56305
|
+
if (newStack.length > maxHistorySize) {
|
|
56306
|
+
newStack.shift();
|
|
56307
|
+
} else {
|
|
56308
|
+
// 更新索引
|
|
56309
|
+
setCurrentIndex(newStack.length - 1);
|
|
56310
|
+
}
|
|
56311
|
+
historyStack.current = newStack;
|
|
56312
|
+
return originalSetOption(option, notMerge, lazyUpdate);
|
|
56313
|
+
};
|
|
56314
|
+
return function () {
|
|
56315
|
+
// 恢复原始 setOption
|
|
56316
|
+
chart.setOption = originalSetOption;
|
|
56317
|
+
};
|
|
56318
|
+
}, [chartInstance, currentIndex, maxHistorySize]);
|
|
56319
|
+
// 键盘快捷键:Ctrl+Z 撤销,Ctrl+Y / Ctrl+Shift+Z 重做
|
|
56320
|
+
(0,external_react_.useEffect)(function () {
|
|
56321
|
+
if (!enableKeyboard) return;
|
|
56322
|
+
var handleKeyDown = function (e) {
|
|
56323
|
+
var isMod = e.ctrlKey || e.metaKey;
|
|
56324
|
+
if (!isMod) return;
|
|
56325
|
+
if (e.key === 'z' && !e.shiftKey) {
|
|
56326
|
+
e.preventDefault();
|
|
56327
|
+
undo();
|
|
56328
|
+
} else if (e.key === 'y' || e.key === 'z' && e.shiftKey) {
|
|
56329
|
+
e.preventDefault();
|
|
56330
|
+
redo();
|
|
56331
|
+
}
|
|
56332
|
+
};
|
|
56333
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
56334
|
+
return function () {
|
|
56335
|
+
return window.removeEventListener('keydown', handleKeyDown);
|
|
56336
|
+
};
|
|
56337
|
+
}, [enableKeyboard]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
56338
|
+
// 组件卸载时清空
|
|
56339
|
+
(0,external_react_.useEffect)(function () {
|
|
56340
|
+
return function () {
|
|
56341
|
+
if (clearOnUnmount) {
|
|
56342
|
+
historyStack.current = [];
|
|
56343
|
+
setCurrentIndex(-1);
|
|
56344
|
+
}
|
|
56345
|
+
};
|
|
56346
|
+
}, [clearOnUnmount]);
|
|
56347
|
+
// ─── Public API ───────────────────────────────────────────────────────────
|
|
56348
|
+
var undo = (0,external_react_.useCallback)(function () {
|
|
56349
|
+
var chart = chartRef.current;
|
|
56350
|
+
if (!chart || currentIndex <= 0) return;
|
|
56351
|
+
var idx = currentIndex - 1;
|
|
56352
|
+
isApplyingRef.current = true;
|
|
56353
|
+
chart.setOption(historyStack.current[idx], true, true);
|
|
56354
|
+
isApplyingRef.current = false;
|
|
56355
|
+
setCurrentIndex(idx);
|
|
56356
|
+
}, [currentIndex]);
|
|
56357
|
+
var redo = (0,external_react_.useCallback)(function () {
|
|
56358
|
+
var chart = chartRef.current;
|
|
56359
|
+
if (!chart || currentIndex >= historyStack.current.length - 1) return;
|
|
56360
|
+
var idx = currentIndex + 1;
|
|
56361
|
+
isApplyingRef.current = true;
|
|
56362
|
+
chart.setOption(historyStack.current[idx], true, true);
|
|
56363
|
+
isApplyingRef.current = false;
|
|
56364
|
+
setCurrentIndex(idx);
|
|
56365
|
+
}, [currentIndex]);
|
|
56366
|
+
var goTo = (0,external_react_.useCallback)(function (index) {
|
|
56367
|
+
var chart = chartRef.current;
|
|
56368
|
+
if (!chart) return;
|
|
56369
|
+
if (index < 0 || index >= historyStack.current.length) return;
|
|
56370
|
+
if (index === currentIndex) return;
|
|
56371
|
+
isApplyingRef.current = true;
|
|
56372
|
+
chart.setOption(historyStack.current[index], true, true);
|
|
56373
|
+
isApplyingRef.current = false;
|
|
56374
|
+
setCurrentIndex(index);
|
|
56375
|
+
}, [currentIndex]);
|
|
56376
|
+
var push = (0,external_react_.useCallback)(function (option) {
|
|
56377
|
+
var stack = historyStack.current;
|
|
56378
|
+
var idx = currentIndex;
|
|
56379
|
+
var newStack = idx < stack.length - 1 ? stack.slice(0, idx + 1) : useChartHistory_spreadArray([], stack, true);
|
|
56380
|
+
newStack.push(option);
|
|
56381
|
+
if (newStack.length > maxHistorySize) newStack.shift();
|
|
56382
|
+
historyStack.current = newStack;
|
|
56383
|
+
setCurrentIndex(newStack.length - 1);
|
|
56384
|
+
}, [currentIndex, maxHistorySize]);
|
|
56385
|
+
var clear = (0,external_react_.useCallback)(function () {
|
|
56386
|
+
historyStack.current = [];
|
|
56387
|
+
setCurrentIndex(-1);
|
|
56388
|
+
}, []);
|
|
56389
|
+
return {
|
|
56390
|
+
canUndo: currentIndex > 0,
|
|
56391
|
+
canRedo: currentIndex < historyStack.current.length - 1,
|
|
56392
|
+
currentIndex: currentIndex,
|
|
56393
|
+
historyCount: historyStack.current.length,
|
|
56394
|
+
undo: undo,
|
|
56395
|
+
redo: redo,
|
|
56396
|
+
goTo: goTo,
|
|
56397
|
+
push: push,
|
|
56398
|
+
clear: clear
|
|
56399
|
+
};
|
|
56400
|
+
}
|
|
56401
|
+
/* harmony default export */ const hooks_useChartHistory = ((/* unused pure expression or super */ null && (useChartHistory)));
|
|
56402
|
+
;// ./src/hooks/useChartSelection.ts
|
|
56403
|
+
var useChartSelection_spreadArray = undefined && undefined.__spreadArray || function (to, from, pack) {
|
|
56404
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
56405
|
+
if (ar || !(i in from)) {
|
|
56406
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
56407
|
+
ar[i] = from[i];
|
|
56408
|
+
}
|
|
56409
|
+
}
|
|
56410
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56411
|
+
};
|
|
56412
|
+
/**
|
|
56413
|
+
* useChartSelection - 图表数据点选择/高亮 Hook
|
|
56414
|
+
* 支持单个/批量选择、反选、清除选择,配合 ECharts select 事件
|
|
56415
|
+
*
|
|
56416
|
+
* 特性:
|
|
56417
|
+
* - 支持按 seriesIndex + dataIndex 选择
|
|
56418
|
+
* - 支持按 dataIndex 跨系列批量选择
|
|
56419
|
+
* - 支持反选(invertSelection)
|
|
56420
|
+
* - 支持多选模式(multi)
|
|
56421
|
+
* - 自动绑定图表 select/unselect 事件
|
|
56422
|
+
*/
|
|
56423
|
+
|
|
56424
|
+
// ============================================================================
|
|
56425
|
+
// 工具函数
|
|
56426
|
+
// ============================================================================
|
|
56427
|
+
/** 生成唯一键字符串 */
|
|
56428
|
+
function keyToString(key) {
|
|
56429
|
+
return "".concat(key.seriesIndex, ":").concat(key.dataIndex);
|
|
56430
|
+
}
|
|
56431
|
+
function stringToKey(str) {
|
|
56432
|
+
var _a = str.split(':').map(Number),
|
|
56433
|
+
seriesIndex = _a[0],
|
|
56434
|
+
dataIndex = _a[1];
|
|
56435
|
+
return {
|
|
56436
|
+
seriesIndex: seriesIndex,
|
|
56437
|
+
dataIndex: dataIndex
|
|
56438
|
+
};
|
|
56439
|
+
}
|
|
56440
|
+
// ============================================================================
|
|
56441
|
+
// Hook 实现
|
|
56442
|
+
// ============================================================================
|
|
56443
|
+
/**
|
|
56444
|
+
* 使用图表数据点选择功能
|
|
56445
|
+
* @param chartInstance 图表实例
|
|
56446
|
+
* @param options 配置选项
|
|
56447
|
+
* @returns 选择控制接口
|
|
56448
|
+
*/
|
|
56449
|
+
function useChartSelection(chartInstance, options) {
|
|
56450
|
+
if (options === void 0) {
|
|
56451
|
+
options = {};
|
|
56452
|
+
}
|
|
56453
|
+
var _a = options.mode,
|
|
56454
|
+
mode = _a === void 0 ? 'multiple' : _a,
|
|
56455
|
+
_b = options.clearOnUnmount,
|
|
56456
|
+
clearOnUnmount = _b === void 0 ? true : _b,
|
|
56457
|
+
_c = options.enableCtrlMultiSelect,
|
|
56458
|
+
enableCtrlMultiSelect = _c === void 0 ? true : _c,
|
|
56459
|
+
_d = options.enableShiftRangeSelect,
|
|
56460
|
+
enableShiftRangeSelect = _d === void 0 ? true : _d,
|
|
56461
|
+
onSelectionChange = options.onSelectionChange;
|
|
56462
|
+
// 选中点集合(字符串键)
|
|
56463
|
+
var _e = (0,external_react_.useState)([]),
|
|
56464
|
+
selectedPoints = _e[0],
|
|
56465
|
+
setSelectedPoints = _e[1];
|
|
56466
|
+
// Chart instance ref
|
|
56467
|
+
var chartRef = (0,external_react_.useRef)(null);
|
|
56468
|
+
chartRef.current = chartInstance;
|
|
56469
|
+
// 上一次 shift+click 的数据索引(用于范围选择)
|
|
56470
|
+
var lastShiftIndexRef = (0,external_react_.useRef)(null);
|
|
56471
|
+
// 当前模式 ref(用于事件处理)
|
|
56472
|
+
var modeRef = (0,external_react_.useRef)(mode);
|
|
56473
|
+
modeRef.current = mode;
|
|
56474
|
+
// 绑定图表 select/unselect 事件
|
|
56475
|
+
(0,external_react_.useEffect)(function () {
|
|
56476
|
+
var chart = chartRef.current;
|
|
56477
|
+
if (!chart || !chart.on) return;
|
|
56478
|
+
var handleSelect = function (params) {
|
|
56479
|
+
// ECharts 内置 select 会同步更新 legend
|
|
56480
|
+
// 这里我们用 dispatchAction 来实现纯数据点选择
|
|
56481
|
+
};
|
|
56482
|
+
// 单击 legend 时清除数据点选择(保持一致性)
|
|
56483
|
+
var handleLegendSelectChanged = function (params) {
|
|
56484
|
+
// 清除选择时的视觉反馈
|
|
56485
|
+
};
|
|
56486
|
+
chart.on('selectchanged', function (params) {
|
|
56487
|
+
// 当图表内部选择变化时同步状态
|
|
56488
|
+
var p = params;
|
|
56489
|
+
if (p.isFromClick) {
|
|
56490
|
+
// 用户点击了图例,清除所有数据点选择
|
|
56491
|
+
setSelectedPoints([]);
|
|
56492
|
+
onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
|
|
56493
|
+
selected: [],
|
|
56494
|
+
unselected: []
|
|
56495
|
+
});
|
|
56496
|
+
}
|
|
56497
|
+
});
|
|
56498
|
+
return function () {
|
|
56499
|
+
if (chart.off) {
|
|
56500
|
+
chart.off('selectchanged');
|
|
56501
|
+
}
|
|
56502
|
+
};
|
|
56503
|
+
}, [onSelectionChange]);
|
|
56504
|
+
// 组件卸载时清除选择
|
|
56505
|
+
(0,external_react_.useEffect)(function () {
|
|
56506
|
+
return function () {
|
|
56507
|
+
if (clearOnUnmount) {
|
|
56508
|
+
var chart = chartRef.current;
|
|
56509
|
+
if (chart === null || chart === void 0 ? void 0 : chart.dispatchAction) {
|
|
56510
|
+
// 清除所有系列的选择状态
|
|
56511
|
+
chart.dispatchAction({
|
|
56512
|
+
type: 'unselect'
|
|
56513
|
+
});
|
|
56514
|
+
}
|
|
56515
|
+
}
|
|
56516
|
+
};
|
|
56517
|
+
}, [clearOnUnmount]);
|
|
56518
|
+
// ─── 私有方法 ───────────────────────────────────────────────────────────────
|
|
56519
|
+
/** 触发选择变化回调 */
|
|
56520
|
+
var notifyChange = (0,external_react_.useCallback)(function (selected, unselected) {
|
|
56521
|
+
onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({
|
|
56522
|
+
selected: selected,
|
|
56523
|
+
unselected: unselected
|
|
56524
|
+
});
|
|
56525
|
+
}, [onSelectionChange]);
|
|
56526
|
+
/** 执行 ECharts dispatchAction */
|
|
56527
|
+
var dispatchSelect = (0,external_react_.useCallback)(function (key, select) {
|
|
56528
|
+
var chart = chartRef.current;
|
|
56529
|
+
if (!(chart === null || chart === void 0 ? void 0 : chart.dispatchAction)) return;
|
|
56530
|
+
chart.dispatchAction({
|
|
56531
|
+
type: select ? 'select' : 'unselect',
|
|
56532
|
+
seriesIndex: key.seriesIndex,
|
|
56533
|
+
dataIndex: key.dataIndex
|
|
56534
|
+
});
|
|
56535
|
+
}, []);
|
|
56536
|
+
// ─── Public API ───────────────────────────────────────────────────────────
|
|
56537
|
+
var select = (0,external_react_.useCallback)(function (key) {
|
|
56538
|
+
setSelectedPoints(function (prev) {
|
|
56539
|
+
var str = keyToString(key);
|
|
56540
|
+
if (prev.some(function (p) {
|
|
56541
|
+
return keyToString(p) === str;
|
|
56542
|
+
})) return prev;
|
|
56543
|
+
var next = mode === 'single' ? [key] : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), [key], false);
|
|
56544
|
+
notifyChange(next, []);
|
|
56545
|
+
return next;
|
|
56546
|
+
});
|
|
56547
|
+
dispatchSelect(key, true);
|
|
56548
|
+
}, [mode, notifyChange, dispatchSelect]);
|
|
56549
|
+
var deselect = (0,external_react_.useCallback)(function (key) {
|
|
56550
|
+
setSelectedPoints(function (prev) {
|
|
56551
|
+
var str = keyToString(key);
|
|
56552
|
+
var removed = prev.filter(function (p) {
|
|
56553
|
+
return keyToString(p) !== str;
|
|
56554
|
+
});
|
|
56555
|
+
notifyChange([], removed);
|
|
56556
|
+
return removed;
|
|
56557
|
+
});
|
|
56558
|
+
dispatchSelect(key, false);
|
|
56559
|
+
}, [notifyChange, dispatchSelect]);
|
|
56560
|
+
var toggle = (0,external_react_.useCallback)(function (key) {
|
|
56561
|
+
var str = keyToString(key);
|
|
56562
|
+
if (selectedPoints.some(function (p) {
|
|
56563
|
+
return keyToString(p) === str;
|
|
56564
|
+
})) {
|
|
56565
|
+
deselect(key);
|
|
56566
|
+
} else {
|
|
56567
|
+
select(key);
|
|
56568
|
+
}
|
|
56569
|
+
}, [selectedPoints, select, deselect]);
|
|
56570
|
+
var selectMultiple = (0,external_react_.useCallback)(function (keys) {
|
|
56571
|
+
setSelectedPoints(function (prev) {
|
|
56572
|
+
var newPoints = mode === 'single' ? keys : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), keys.filter(function (k) {
|
|
56573
|
+
return !prev.some(function (p) {
|
|
56574
|
+
return keyToString(p) === keyToString(k);
|
|
56575
|
+
});
|
|
56576
|
+
}), true);
|
|
56577
|
+
notifyChange(newPoints, []);
|
|
56578
|
+
return newPoints;
|
|
56579
|
+
});
|
|
56580
|
+
keys.forEach(function (key) {
|
|
56581
|
+
return dispatchSelect(key, true);
|
|
56582
|
+
});
|
|
56583
|
+
}, [mode, notifyChange, dispatchSelect]);
|
|
56584
|
+
var deselectMultiple = (0,external_react_.useCallback)(function (keys) {
|
|
56585
|
+
setSelectedPoints(function (prev) {
|
|
56586
|
+
var keySet = new Set(keys.map(keyToString));
|
|
56587
|
+
var removed = prev.filter(function (p) {
|
|
56588
|
+
return keySet.has(keyToString(p));
|
|
56589
|
+
});
|
|
56590
|
+
var remaining = prev.filter(function (p) {
|
|
56591
|
+
return !keySet.has(keyToString(p));
|
|
56592
|
+
});
|
|
56593
|
+
notifyChange([], removed);
|
|
56594
|
+
return remaining;
|
|
56595
|
+
});
|
|
56596
|
+
keys.forEach(function (key) {
|
|
56597
|
+
return dispatchSelect(key, false);
|
|
56598
|
+
});
|
|
56599
|
+
}, [notifyChange, dispatchSelect]);
|
|
56600
|
+
var invertSelection = (0,external_react_.useCallback)(function (seriesIndex, dataIndices) {
|
|
56601
|
+
setSelectedPoints(function (prev) {
|
|
56602
|
+
var selectedSet = new Set(prev.filter(function (p) {
|
|
56603
|
+
return p.seriesIndex === seriesIndex;
|
|
56604
|
+
}).map(function (p) {
|
|
56605
|
+
return p.dataIndex;
|
|
56606
|
+
}));
|
|
56607
|
+
var toSelect = [];
|
|
56608
|
+
var toDeselect = [];
|
|
56609
|
+
dataIndices.forEach(function (dataIndex) {
|
|
56610
|
+
var key = {
|
|
56611
|
+
seriesIndex: seriesIndex,
|
|
56612
|
+
dataIndex: dataIndex
|
|
56613
|
+
};
|
|
56614
|
+
var str = keyToString(key);
|
|
56615
|
+
if (selectedSet.has(dataIndex)) {
|
|
56616
|
+
toDeselect.push(key);
|
|
56617
|
+
} else {
|
|
56618
|
+
toSelect.push(key);
|
|
56619
|
+
}
|
|
56620
|
+
});
|
|
56621
|
+
toDeselect.forEach(function (k) {
|
|
56622
|
+
return dispatchSelect(k, false);
|
|
56623
|
+
});
|
|
56624
|
+
toSelect.forEach(function (k) {
|
|
56625
|
+
return dispatchSelect(k, true);
|
|
56626
|
+
});
|
|
56627
|
+
var newSelected = prev.filter(function (p) {
|
|
56628
|
+
return !(p.seriesIndex === seriesIndex && selectedSet.has(p.dataIndex));
|
|
56629
|
+
}).concat(toSelect);
|
|
56630
|
+
notifyChange(toSelect, toDeselect);
|
|
56631
|
+
return newSelected;
|
|
56632
|
+
});
|
|
56633
|
+
}, [notifyChange, dispatchSelect]);
|
|
56634
|
+
var selectAll = (0,external_react_.useCallback)(function (seriesIndex, dataIndices) {
|
|
56635
|
+
var keys = dataIndices.map(function (dataIndex) {
|
|
56636
|
+
return {
|
|
56637
|
+
seriesIndex: seriesIndex,
|
|
56638
|
+
dataIndex: dataIndex
|
|
56639
|
+
};
|
|
56640
|
+
});
|
|
56641
|
+
setSelectedPoints(function (prev) {
|
|
56642
|
+
var newPoints = mode === 'single' ? keys : useChartSelection_spreadArray(useChartSelection_spreadArray([], prev, true), keys.filter(function (k) {
|
|
56643
|
+
return !prev.some(function (p) {
|
|
56644
|
+
return keyToString(p) === keyToString(k);
|
|
56645
|
+
});
|
|
56646
|
+
}), true);
|
|
56647
|
+
notifyChange(newPoints, []);
|
|
56648
|
+
return newPoints;
|
|
56649
|
+
});
|
|
56650
|
+
keys.forEach(function (key) {
|
|
56651
|
+
return dispatchSelect(key, true);
|
|
56652
|
+
});
|
|
56653
|
+
}, [mode, notifyChange, dispatchSelect]);
|
|
56654
|
+
var clearSelection = (0,external_react_.useCallback)(function () {
|
|
56655
|
+
var chart = chartRef.current;
|
|
56656
|
+
if (chart === null || chart === void 0 ? void 0 : chart.dispatchAction) {
|
|
56657
|
+
chart.dispatchAction({
|
|
56658
|
+
type: 'unselect'
|
|
56659
|
+
});
|
|
56660
|
+
}
|
|
56661
|
+
var prev = selectedPoints;
|
|
56662
|
+
setSelectedPoints([]);
|
|
56663
|
+
notifyChange([], prev);
|
|
56664
|
+
}, [selectedPoints, notifyChange]);
|
|
56665
|
+
var isSelected = (0,external_react_.useCallback)(function (key) {
|
|
56666
|
+
var str = keyToString(key);
|
|
56667
|
+
return selectedPoints.some(function (p) {
|
|
56668
|
+
return keyToString(p) === str;
|
|
56669
|
+
});
|
|
56670
|
+
}, [selectedPoints]);
|
|
56671
|
+
return {
|
|
56672
|
+
selectedPoints: selectedPoints,
|
|
56673
|
+
hasSelection: selectedPoints.length > 0,
|
|
56674
|
+
selectionCount: selectedPoints.length,
|
|
56675
|
+
select: select,
|
|
56676
|
+
deselect: deselect,
|
|
56677
|
+
selectMultiple: selectMultiple,
|
|
56678
|
+
deselectMultiple: deselectMultiple,
|
|
56679
|
+
toggle: toggle,
|
|
56680
|
+
invertSelection: invertSelection,
|
|
56681
|
+
selectAll: selectAll,
|
|
56682
|
+
clearSelection: clearSelection,
|
|
56683
|
+
isSelected: isSelected
|
|
56684
|
+
};
|
|
56685
|
+
}
|
|
56686
|
+
/* harmony default export */ const hooks_useChartSelection = ((/* unused pure expression or super */ null && (useChartSelection)));
|
|
55871
56687
|
;// ./src/hooks/useDataTransform.ts
|
|
55872
56688
|
var useDataTransform_assign = undefined && undefined.__assign || function () {
|
|
55873
56689
|
useDataTransform_assign = Object.assign || function (t) {
|
|
@@ -56459,6 +57275,8 @@ var hooks_spreadArray = undefined && undefined.__spreadArray || function (to, fr
|
|
|
56459
57275
|
|
|
56460
57276
|
|
|
56461
57277
|
|
|
57278
|
+
|
|
57279
|
+
|
|
56462
57280
|
// ============================================================================
|
|
56463
57281
|
// Hooks
|
|
56464
57282
|
// ============================================================================
|
|
@@ -56695,7 +57513,7 @@ function useChartTheme(theme, darkMode) {
|
|
|
56695
57513
|
*/
|
|
56696
57514
|
function useChartData(data, transformer) {
|
|
56697
57515
|
return (0,external_react_.useMemo)(function () {
|
|
56698
|
-
if (!data) {
|
|
57516
|
+
if (!data || Array.isArray(data) && data.length === 0) {
|
|
56699
57517
|
return {};
|
|
56700
57518
|
}
|
|
56701
57519
|
return transformer(data);
|
|
@@ -57061,6 +57879,10 @@ function useChartTools(instance) {
|
|
|
57061
57879
|
|
|
57062
57880
|
// 图表下载 Hook
|
|
57063
57881
|
|
|
57882
|
+
// 图表历史记录 Hook (Undo/Redo)
|
|
57883
|
+
|
|
57884
|
+
// 图表选择 Hook
|
|
57885
|
+
|
|
57064
57886
|
// ============================================================================
|
|
57065
57887
|
// 导出
|
|
57066
57888
|
// ============================================================================
|
|
@@ -57084,7 +57906,9 @@ var hooks_version = '1.7.0';
|
|
|
57084
57906
|
// v1.7.0 新增
|
|
57085
57907
|
useDataZoom: useDataZoom,
|
|
57086
57908
|
useChartConnect: useChartConnect,
|
|
57087
|
-
useChartDownload: useChartDownload
|
|
57909
|
+
useChartDownload: useChartDownload,
|
|
57910
|
+
useChartHistory: useChartHistory,
|
|
57911
|
+
useChartSelection: useChartSelection
|
|
57088
57912
|
});
|
|
57089
57913
|
;// ./src/index.ts
|
|
57090
57914
|
/**
|