@neo4j-ndl/react-charts 1.1.1 → 1.1.3
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/lib/cjs/charts/Chart.js +56 -462
- package/lib/cjs/charts/Chart.js.map +1 -1
- package/lib/cjs/charts/ChartContainer.js +71 -0
- package/lib/cjs/charts/ChartContainer.js.map +1 -0
- package/lib/cjs/charts/ChartEmpty.js.map +1 -1
- package/lib/cjs/charts/ChartRender.js +97 -0
- package/lib/cjs/charts/ChartRender.js.map +1 -0
- package/lib/cjs/charts/ChartTooltip.js.map +1 -1
- package/lib/cjs/charts/Legend.js +32 -246
- package/lib/cjs/charts/Legend.js.map +1 -1
- package/lib/cjs/charts/LegendItem.js +68 -0
- package/lib/cjs/charts/LegendItem.js.map +1 -0
- package/lib/cjs/charts/LegendLayout.js +363 -0
- package/lib/cjs/charts/LegendLayout.js.map +1 -0
- package/lib/cjs/charts/hooks/use-chart-instance.js +133 -0
- package/lib/cjs/charts/hooks/use-chart-instance.js.map +1 -0
- package/lib/cjs/charts/hooks/use-chart-option.js +79 -0
- package/lib/cjs/charts/hooks/use-chart-option.js.map +1 -0
- package/lib/cjs/charts/hooks/use-chart-refs.js +52 -0
- package/lib/cjs/charts/hooks/use-chart-refs.js.map +1 -0
- package/lib/cjs/charts/hooks/use-chart-zoom.js +117 -0
- package/lib/cjs/charts/hooks/use-chart-zoom.js.map +1 -0
- package/lib/cjs/charts/hooks/use-legend-interactions.js +149 -0
- package/lib/cjs/charts/hooks/use-legend-interactions.js.map +1 -0
- package/lib/cjs/charts/hooks/use-legend-series.js +181 -0
- package/lib/cjs/charts/hooks/use-legend-series.js.map +1 -0
- package/lib/cjs/charts/hooks/use-legend-visibility.js +91 -0
- package/lib/cjs/charts/hooks/use-legend-visibility.js.map +1 -0
- package/lib/cjs/charts/index.js +1 -1
- package/lib/cjs/charts/index.js.map +1 -1
- package/lib/cjs/charts/tests/chart-test-utils.js +56 -9
- package/lib/cjs/charts/tests/chart-test-utils.js.map +1 -1
- package/lib/cjs/charts/themes/ndl-echarts-theme.js.map +1 -1
- package/lib/cjs/charts/{aria-description.js → utils/aria-description.js} +4 -45
- package/lib/cjs/charts/utils/aria-description.js.map +1 -0
- package/lib/cjs/charts/utils/build-chart-option.js +74 -0
- package/lib/cjs/charts/utils/build-chart-option.js.map +1 -0
- package/lib/cjs/charts/utils/chart-tooltip-formatter.js +86 -0
- package/lib/cjs/charts/utils/chart-tooltip-formatter.js.map +1 -0
- package/lib/cjs/charts/utils/chart-types.js.map +1 -0
- package/lib/cjs/charts/utils/defaults.js.map +1 -0
- package/lib/cjs/charts/{utils.js → utils/format-utils.js} +3 -19
- package/lib/cjs/charts/utils/format-utils.js.map +1 -0
- package/lib/cjs/charts/utils/legend-layout.js +65 -0
- package/lib/cjs/charts/utils/legend-layout.js.map +1 -0
- package/lib/cjs/charts/{legend-utils.js → utils/legend-utils.js} +1 -78
- package/lib/cjs/charts/utils/legend-utils.js.map +1 -0
- package/lib/cjs/charts/utils/threshold.js +114 -0
- package/lib/cjs/charts/utils/threshold.js.map +1 -0
- package/lib/cjs/charts/{user-option-utils.js → utils/user-option-utils.js} +7 -16
- package/lib/cjs/charts/utils/user-option-utils.js.map +1 -0
- package/lib/esm/charts/Chart.js +50 -457
- package/lib/esm/charts/Chart.js.map +1 -1
- package/lib/esm/charts/ChartContainer.js +67 -0
- package/lib/esm/charts/ChartContainer.js.map +1 -0
- package/lib/esm/charts/ChartEmpty.js.map +1 -1
- package/lib/esm/charts/ChartRender.js +93 -0
- package/lib/esm/charts/ChartRender.js.map +1 -0
- package/lib/esm/charts/ChartTooltip.js.map +1 -1
- package/lib/esm/charts/Legend.js +32 -243
- package/lib/esm/charts/Legend.js.map +1 -1
- package/lib/esm/charts/LegendItem.js +61 -0
- package/lib/esm/charts/LegendItem.js.map +1 -0
- package/lib/esm/charts/LegendLayout.js +323 -0
- package/lib/esm/charts/LegendLayout.js.map +1 -0
- package/lib/esm/charts/hooks/use-chart-instance.js +128 -0
- package/lib/esm/charts/hooks/use-chart-instance.js.map +1 -0
- package/lib/esm/charts/hooks/use-chart-option.js +76 -0
- package/lib/esm/charts/hooks/use-chart-option.js.map +1 -0
- package/lib/esm/charts/hooks/use-chart-refs.js +48 -0
- package/lib/esm/charts/hooks/use-chart-refs.js.map +1 -0
- package/lib/esm/charts/hooks/use-chart-zoom.js +114 -0
- package/lib/esm/charts/hooks/use-chart-zoom.js.map +1 -0
- package/lib/esm/charts/hooks/use-legend-interactions.js +145 -0
- package/lib/esm/charts/hooks/use-legend-interactions.js.map +1 -0
- package/lib/esm/charts/hooks/use-legend-series.js +178 -0
- package/lib/esm/charts/hooks/use-legend-series.js.map +1 -0
- package/lib/esm/charts/hooks/use-legend-visibility.js +87 -0
- package/lib/esm/charts/hooks/use-legend-visibility.js.map +1 -0
- package/lib/esm/charts/index.js +1 -1
- package/lib/esm/charts/index.js.map +1 -1
- package/lib/esm/charts/tests/chart-test-utils.js +53 -8
- package/lib/esm/charts/tests/chart-test-utils.js.map +1 -1
- package/lib/esm/charts/themes/ndl-echarts-theme.js.map +1 -1
- package/lib/esm/charts/{aria-description.js → utils/aria-description.js} +4 -45
- package/lib/esm/charts/utils/aria-description.js.map +1 -0
- package/lib/esm/charts/utils/build-chart-option.js +69 -0
- package/lib/esm/charts/utils/build-chart-option.js.map +1 -0
- package/lib/esm/charts/utils/chart-tooltip-formatter.js +82 -0
- package/lib/esm/charts/utils/chart-tooltip-formatter.js.map +1 -0
- package/lib/esm/charts/utils/chart-types.js.map +1 -0
- package/lib/esm/charts/utils/defaults.js.map +1 -0
- package/lib/esm/charts/{utils.js → utils/format-utils.js} +2 -17
- package/lib/esm/charts/utils/format-utils.js.map +1 -0
- package/lib/esm/charts/utils/legend-layout.js +59 -0
- package/lib/esm/charts/utils/legend-layout.js.map +1 -0
- package/lib/esm/charts/{legend-utils.js → utils/legend-utils.js} +1 -75
- package/lib/esm/charts/utils/legend-utils.js.map +1 -0
- package/lib/esm/charts/utils/threshold.js +106 -0
- package/lib/esm/charts/utils/threshold.js.map +1 -0
- package/lib/esm/charts/{user-option-utils.js → utils/user-option-utils.js} +5 -14
- package/lib/esm/charts/utils/user-option-utils.js.map +1 -0
- package/lib/types/charts/Chart.d.ts +2 -2
- package/lib/types/charts/Chart.d.ts.map +1 -1
- package/lib/{esm/charts/types.js → types/charts/ChartContainer.d.ts} +14 -1
- package/lib/types/charts/ChartContainer.d.ts.map +1 -0
- package/lib/types/charts/ChartEmpty.d.ts +1 -1
- package/lib/types/charts/ChartEmpty.d.ts.map +1 -1
- package/lib/types/charts/ChartRender.d.ts +36 -0
- package/lib/types/charts/ChartRender.d.ts.map +1 -0
- package/lib/types/charts/ChartTooltip.d.ts +1 -1
- package/lib/types/charts/ChartTooltip.d.ts.map +1 -1
- package/lib/types/charts/Legend.d.ts +15 -3
- package/lib/types/charts/Legend.d.ts.map +1 -1
- package/lib/{cjs/charts/types.js → types/charts/LegendItem.d.ts} +10 -3
- package/lib/types/charts/LegendItem.d.ts.map +1 -0
- package/lib/types/charts/LegendLayout.d.ts +38 -0
- package/lib/types/charts/LegendLayout.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-chart-instance.d.ts +62 -0
- package/lib/types/charts/hooks/use-chart-instance.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-chart-option.d.ts +48 -0
- package/lib/types/charts/hooks/use-chart-option.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-chart-refs.d.ts +38 -0
- package/lib/types/charts/hooks/use-chart-refs.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-chart-zoom.d.ts +36 -0
- package/lib/types/charts/hooks/use-chart-zoom.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-legend-interactions.d.ts +56 -0
- package/lib/types/charts/hooks/use-legend-interactions.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-legend-series.d.ts +42 -0
- package/lib/types/charts/hooks/use-legend-series.d.ts.map +1 -0
- package/lib/types/charts/hooks/use-legend-visibility.d.ts +24 -0
- package/lib/types/charts/hooks/use-legend-visibility.d.ts.map +1 -0
- package/lib/types/charts/index.d.ts +2 -2
- package/lib/types/charts/index.d.ts.map +1 -1
- package/lib/types/charts/tests/chart-test-utils.d.ts +7 -1
- package/lib/types/charts/tests/chart-test-utils.d.ts.map +1 -1
- package/lib/types/charts/themes/ndl-echarts-theme.d.ts +1 -1
- package/lib/types/charts/themes/ndl-echarts-theme.d.ts.map +1 -1
- package/lib/types/charts/utils/aria-description.d.ts.map +1 -0
- package/lib/types/charts/utils/build-chart-option.d.ts +52 -0
- package/lib/types/charts/utils/build-chart-option.d.ts.map +1 -0
- package/lib/types/charts/utils/chart-tooltip-formatter.d.ts +37 -0
- package/lib/types/charts/utils/chart-tooltip-formatter.d.ts.map +1 -0
- package/lib/types/charts/{chart-types.d.ts → utils/chart-types.d.ts} +23 -22
- package/lib/types/charts/utils/chart-types.d.ts.map +1 -0
- package/lib/types/charts/utils/defaults.d.ts.map +1 -0
- package/lib/types/charts/{utils.d.ts → utils/format-utils.d.ts} +2 -4
- package/lib/types/charts/utils/format-utils.d.ts.map +1 -0
- package/lib/types/charts/utils/legend-layout.d.ts +37 -0
- package/lib/types/charts/utils/legend-layout.d.ts.map +1 -0
- package/lib/types/charts/{legend-utils.d.ts → utils/legend-utils.d.ts} +1 -11
- package/lib/types/charts/utils/legend-utils.d.ts.map +1 -0
- package/lib/types/charts/utils/threshold.d.ts +45 -0
- package/lib/types/charts/utils/threshold.d.ts.map +1 -0
- package/lib/types/charts/utils/user-option-utils.d.ts.map +1 -0
- package/package.json +3 -3
- package/lib/cjs/charts/aria-description.js.map +0 -1
- package/lib/cjs/charts/chart-types.js.map +0 -1
- package/lib/cjs/charts/defaults.js.map +0 -1
- package/lib/cjs/charts/legend-utils.js.map +0 -1
- package/lib/cjs/charts/types.js.map +0 -1
- package/lib/cjs/charts/user-option-utils.js.map +0 -1
- package/lib/cjs/charts/utils.js.map +0 -1
- package/lib/esm/charts/aria-description.js.map +0 -1
- package/lib/esm/charts/chart-types.js.map +0 -1
- package/lib/esm/charts/defaults.js.map +0 -1
- package/lib/esm/charts/legend-utils.js.map +0 -1
- package/lib/esm/charts/types.js.map +0 -1
- package/lib/esm/charts/user-option-utils.js.map +0 -1
- package/lib/esm/charts/utils.js.map +0 -1
- package/lib/types/charts/aria-description.d.ts.map +0 -1
- package/lib/types/charts/chart-types.d.ts.map +0 -1
- package/lib/types/charts/defaults.d.ts.map +0 -1
- package/lib/types/charts/legend-utils.d.ts.map +0 -1
- package/lib/types/charts/types.d.ts +0 -44
- package/lib/types/charts/types.d.ts.map +0 -1
- package/lib/types/charts/user-option-utils.d.ts.map +0 -1
- package/lib/types/charts/utils.d.ts.map +0 -1
- /package/lib/cjs/charts/{chart-types.js → utils/chart-types.js} +0 -0
- /package/lib/cjs/charts/{defaults.js → utils/defaults.js} +0 -0
- /package/lib/esm/charts/{chart-types.js → utils/chart-types.js} +0 -0
- /package/lib/esm/charts/{defaults.js → utils/defaults.js} +0 -0
- /package/lib/types/charts/{aria-description.d.ts → utils/aria-description.d.ts} +0 -0
- /package/lib/types/charts/{defaults.d.ts → utils/defaults.d.ts} +0 -0
- /package/lib/types/charts/{user-option-utils.d.ts → utils/user-option-utils.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chart-option.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-chart-option.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;AAmCH,wCA4DC;AA5FD,qCAA2C;AAC3C,iCAA4C;AAE5C,oEAA+D;AAG/D,qDAAuD;AAiBvD;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,OAAO,EACP,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,MAAM,EACN,QAAQ,EACR,cAAc,EACd,cAAc,EACd,UAAU,EACV,KAAK,EACL,KAAK,GACgB;IACrB,MAAM,EAAE,cAAc,EAAE,iBAAiB,EAAE,GAAG,IAAA,oCAAmB,GAAE,CAAC;IACpE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,GAAiB,CAAC;IAEhE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAA,0BAAgB,EAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,IAAA,qCAAgB,EAAC;YAC9B,QAAQ;YACR,OAAO;YACP,gBAAgB;YAChB,aAAa;YACb,cAAc,EAAE,iBAAiB,CAAC,OAAO,IAAI,EAAE;YAC/C,WAAW;YACX,MAAM;YACN,cAAc;YACd,cAAc;YACd,UAAU;YACV,KAAK;YACL,KAAK;SACN,CAAC,CAAC;QAEH,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEnC,cAAc,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,SAAS,EAA+B,CAAC,CAAC;IAClE,CAAC,EAAE;QACD,cAAc;QACd,QAAQ;QACR,OAAO;QACP,gBAAgB;QAChB,aAAa;QACb,iBAAiB;QACjB,WAAW;QACX,MAAM;QACN,QAAQ;QACR,cAAc;QACd,cAAc;QACd,UAAU;QACV,KAAK;QACL,KAAK;KACN,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type { EChartsOption } from 'echarts';\nimport { getInstanceByDom } from 'echarts';\nimport { useEffect, useState } from 'react';\n\nimport { buildChartOption } from '../utils/build-chart-option';\nimport type { ChartProps, EchartsSeries } from '../utils/chart-types';\nimport type { NormalizedThresholdLine } from '../utils/threshold';\nimport { useChartRefsContext } from './use-chart-refs';\n\nexport type UseChartOptionParams = {\n dataZoom: EChartsOption['dataZoom'];\n dataset: ChartProps['dataset'];\n hasCategoryXAxis: boolean;\n hasSliderZoom: boolean;\n propsSeries: ChartProps['series'];\n series: EchartsSeries;\n settings: ChartProps['settings'];\n thresholdLines: NormalizedThresholdLine[];\n toolboxOptions: EChartsOption['toolbox'];\n userOption: ChartProps['option'];\n xAxis: EChartsOption['xAxis'];\n yAxis: EChartsOption['yAxis'];\n};\n\n/**\n * Builds, applies, and exposes the ECharts option for the current React props.\n *\n * `buildChartOption` merges Needle defaults, normalized axes/series, threshold\n * lines, zoom settings, toolbox options, user overrides, and the current legend\n * selection. After `setOption`, the hook returns ECharts' normalized option so\n * downstream code, especially the custom legend, can read the final series and\n * dataset shape ECharts is actually using.\n */\nexport function useChartOption({\n dataZoom,\n dataset,\n hasCategoryXAxis,\n hasSliderZoom,\n propsSeries,\n series,\n settings,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n}: UseChartOptionParams) {\n const { chartEchartRef, legendSelectedRef } = useChartRefsContext();\n const [chartOption, setChartOption] = useState<EChartsOption>();\n\n useEffect(() => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n\n const option = buildChartOption({\n dataZoom,\n dataset,\n hasCategoryXAxis,\n hasSliderZoom,\n legendSelected: legendSelectedRef.current || {},\n propsSeries,\n series,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n });\n\n chart?.setOption(option, settings);\n\n setChartOption(chart?.getOption() as EChartsOption | undefined);\n }, [\n chartEchartRef,\n dataZoom,\n dataset,\n hasCategoryXAxis,\n hasSliderZoom,\n legendSelectedRef,\n propsSeries,\n series,\n settings,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n ]);\n\n return chartOption;\n}\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.ChartRefsProvider = ChartRefsProvider;
|
|
24
|
+
exports.useChartRefsContext = useChartRefsContext;
|
|
25
|
+
const react_1 = require("react");
|
|
26
|
+
const ChartRefsContext = (0, react_1.createContext)(undefined);
|
|
27
|
+
/**
|
|
28
|
+
* Creates the mutable refs shared between `ChartRender` and legend components.
|
|
29
|
+
*
|
|
30
|
+
* `chartEchartRef` points at the ECharts host element, while the legend refs act
|
|
31
|
+
* as a bridge for state that ECharts needs synchronously during option rebuilds
|
|
32
|
+
* without forcing extra React renders.
|
|
33
|
+
*/
|
|
34
|
+
function ChartRefsProvider({ children }) {
|
|
35
|
+
const chartEchartRef = (0, react_1.useRef)(null);
|
|
36
|
+
const legendSelectedRef = (0, react_1.useRef)({});
|
|
37
|
+
const legendColorCacheRef = (0, react_1.useRef)(new Map());
|
|
38
|
+
const refs = (0, react_1.useMemo)(() => ({
|
|
39
|
+
chartEchartRef,
|
|
40
|
+
legendColorCacheRef,
|
|
41
|
+
legendSelectedRef,
|
|
42
|
+
}), []);
|
|
43
|
+
return (0, react_1.createElement)(ChartRefsContext.Provider, { value: refs }, children);
|
|
44
|
+
}
|
|
45
|
+
function useChartRefsContext() {
|
|
46
|
+
const refs = (0, react_1.useContext)(ChartRefsContext);
|
|
47
|
+
if (refs === undefined) {
|
|
48
|
+
throw new Error('useChartRefsContext must be used within ChartRefsProvider');
|
|
49
|
+
}
|
|
50
|
+
return refs;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=use-chart-refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chart-refs.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-chart-refs.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;AA0BH,8CAcC;AAED,kDASC;AAjDD,iCAOe;AAQf,MAAM,gBAAgB,GAAG,IAAA,qBAAa,EAAwB,SAAS,CAAC,CAAC;AAEzE;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,EAAE,QAAQ,EAA2B;IACrE,MAAM,cAAc,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAC;IACpD,MAAM,iBAAiB,GAAG,IAAA,cAAM,EAA0B,EAAE,CAAC,CAAC;IAC9D,MAAM,mBAAmB,GAAG,IAAA,cAAM,EAAsB,IAAI,GAAG,EAAE,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,IAAA,eAAO,EAClB,GAAG,EAAE,CAAC,CAAC;QACL,cAAc;QACd,mBAAmB;QACnB,iBAAiB;KAClB,CAAC,EACF,EAAE,CACH,CAAC;IAEF,OAAO,IAAA,qBAAa,EAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC;AAED,SAAgB,mBAAmB;IACjC,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,gBAAgB,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport {\n createContext,\n createElement,\n type ReactNode,\n useContext,\n useMemo,\n useRef,\n} from 'react';\n\nexport type ChartRefs = {\n chartEchartRef: React.RefObject<HTMLDivElement | null>;\n legendColorCacheRef: React.RefObject<Map<string, string>>;\n legendSelectedRef: React.RefObject<Record<string, boolean>>;\n};\n\nconst ChartRefsContext = createContext<ChartRefs | undefined>(undefined);\n\n/**\n * Creates the mutable refs shared between `ChartRender` and legend components.\n *\n * `chartEchartRef` points at the ECharts host element, while the legend refs act\n * as a bridge for state that ECharts needs synchronously during option rebuilds\n * without forcing extra React renders.\n */\nexport function ChartRefsProvider({ children }: { children: ReactNode }) {\n const chartEchartRef = useRef<HTMLDivElement>(null);\n const legendSelectedRef = useRef<Record<string, boolean>>({});\n const legendColorCacheRef = useRef<Map<string, string>>(new Map());\n const refs = useMemo(\n () => ({\n chartEchartRef,\n legendColorCacheRef,\n legendSelectedRef,\n }),\n [],\n );\n\n return createElement(ChartRefsContext.Provider, { value: refs }, children);\n}\n\nexport function useChartRefsContext() {\n const refs = useContext(ChartRefsContext);\n if (refs === undefined) {\n throw new Error(\n 'useChartRefsContext must be used within ChartRefsProvider',\n );\n }\n\n return refs;\n}\n"]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.useChartZoom = useChartZoom;
|
|
24
|
+
const echarts_1 = require("echarts");
|
|
25
|
+
const react_1 = require("react");
|
|
26
|
+
const use_chart_refs_1 = require("./use-chart-refs");
|
|
27
|
+
/**
|
|
28
|
+
* Owns ECharts zoom interactions and forwards zoom changes to consumers.
|
|
29
|
+
*
|
|
30
|
+
* The hook subscribes to ECharts `datazoom` events, enables drag-to-zoom through
|
|
31
|
+
* ECharts' global cursor API, resets zoom on double click, and clears ECharts'
|
|
32
|
+
* SVG cursor override after mouse movement so Needle's default cursor styling is
|
|
33
|
+
* preserved.
|
|
34
|
+
*/
|
|
35
|
+
function useChartZoom({ callbacks, isChartZoomDisabled, }) {
|
|
36
|
+
const { chartEchartRef } = (0, use_chart_refs_1.useChartRefsContext)();
|
|
37
|
+
(0, react_1.useEffect)(() => {
|
|
38
|
+
var _a;
|
|
39
|
+
const chart = chartEchartRef.current === null
|
|
40
|
+
? undefined
|
|
41
|
+
: (0, echarts_1.getInstanceByDom)(chartEchartRef.current);
|
|
42
|
+
if (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onZoom) {
|
|
43
|
+
chart === null || chart === void 0 ? void 0 : chart.on('datazoom', () => {
|
|
44
|
+
var _a;
|
|
45
|
+
if (chartEchartRef.current === null) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const currentChart = (0, echarts_1.getInstanceByDom)(chartEchartRef.current);
|
|
49
|
+
if (!currentChart) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const option = currentChart.getOption();
|
|
53
|
+
if (!option || !option.dataZoom) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const dataZoom = Array.isArray(option.dataZoom)
|
|
57
|
+
? option.dataZoom[0]
|
|
58
|
+
: option.dataZoom;
|
|
59
|
+
const { startValue, endValue } = dataZoom;
|
|
60
|
+
(_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onZoom) === null || _a === void 0 ? void 0 : _a.call(callbacks, { endValue, startValue });
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const handleMouseMove = () => {
|
|
64
|
+
// ECharts updates SVG cursor styles on mouse move, so Needle has to
|
|
65
|
+
// reset it after ECharts' internal handler runs.
|
|
66
|
+
chart === null || chart === void 0 ? void 0 : chart.getZr().setCursorStyle('default');
|
|
67
|
+
};
|
|
68
|
+
const chartChild = (_a = chartEchartRef.current) === null || _a === void 0 ? void 0 : _a.children[0];
|
|
69
|
+
if (!isChartZoomDisabled) {
|
|
70
|
+
chartChild === null || chartChild === void 0 ? void 0 : chartChild.addEventListener('mousemove', handleMouseMove);
|
|
71
|
+
}
|
|
72
|
+
const handleMouseDown = (params) => {
|
|
73
|
+
var _a;
|
|
74
|
+
const event = params.event;
|
|
75
|
+
const amountOfMouseClicks = event.detail;
|
|
76
|
+
const isDoubleClick = amountOfMouseClicks === 2;
|
|
77
|
+
if (isDoubleClick) {
|
|
78
|
+
if (chart === undefined) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
chart === null || chart === void 0 ? void 0 : chart.dispatchAction({
|
|
82
|
+
end: 100,
|
|
83
|
+
start: 0,
|
|
84
|
+
type: 'dataZoom',
|
|
85
|
+
});
|
|
86
|
+
if (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onZoom) {
|
|
87
|
+
(_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onZoom) === null || _a === void 0 ? void 0 : _a.call(callbacks, { endValue: 100, startValue: 0 });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
if (!isChartZoomDisabled) {
|
|
92
|
+
chart === null || chart === void 0 ? void 0 : chart.getZr().on('mousedown', handleMouseDown);
|
|
93
|
+
}
|
|
94
|
+
const chartRefCurrentElement = chartEchartRef.current;
|
|
95
|
+
const element = chartRefCurrentElement === null || chartRefCurrentElement === void 0 ? void 0 : chartRefCurrentElement.children[0];
|
|
96
|
+
return () => {
|
|
97
|
+
element === null || element === void 0 ? void 0 : element.removeEventListener('mousemove', handleMouseMove);
|
|
98
|
+
if (chartRefCurrentElement) {
|
|
99
|
+
const chart = (0, echarts_1.getInstanceByDom)(chartRefCurrentElement);
|
|
100
|
+
chart === null || chart === void 0 ? void 0 : chart.getZr().off('mousedown', handleMouseDown);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
if (chartEchartRef.current !== null && !isChartZoomDisabled) {
|
|
105
|
+
const chart = (0, echarts_1.getInstanceByDom)(chartEchartRef.current);
|
|
106
|
+
if (chart) {
|
|
107
|
+
// Needs to be re-set on every re-render. Sets the selectable zoom area
|
|
108
|
+
// over the chart body, not the slider.
|
|
109
|
+
chart.dispatchAction({
|
|
110
|
+
dataZoomSelectActive: true,
|
|
111
|
+
key: 'dataZoomSelect',
|
|
112
|
+
type: 'takeGlobalCursor',
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=use-chart-zoom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chart-zoom.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-chart-zoom.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { getInstanceByDom } from 'echarts';\nimport { useEffect } from 'react';\n\nimport type { ChartProps } from '../utils/chart-types';\nimport { useChartRefsContext } from './use-chart-refs';\n\ntype UseChartZoomParams = {\n callbacks: ChartProps['callbacks'];\n isChartZoomDisabled: boolean;\n};\n\n/**\n * Owns ECharts zoom interactions and forwards zoom changes to consumers.\n *\n * The hook subscribes to ECharts `datazoom` events, enables drag-to-zoom through\n * ECharts' global cursor API, resets zoom on double click, and clears ECharts'\n * SVG cursor override after mouse movement so Needle's default cursor styling is\n * preserved.\n */\nexport function useChartZoom({\n callbacks,\n isChartZoomDisabled,\n}: UseChartZoomParams) {\n const { chartEchartRef } = useChartRefsContext();\n\n useEffect(() => {\n const chart =\n chartEchartRef.current === null\n ? undefined\n : getInstanceByDom(chartEchartRef.current);\n\n if (callbacks?.onZoom) {\n chart?.on('datazoom', () => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const currentChart = getInstanceByDom(chartEchartRef.current);\n if (!currentChart) {\n return;\n }\n\n const option = currentChart.getOption();\n if (!option || !option.dataZoom) {\n return;\n }\n\n const dataZoom = Array.isArray(option.dataZoom)\n ? option.dataZoom[0]\n : option.dataZoom;\n const { startValue, endValue } = dataZoom as {\n startValue: number;\n endValue: number;\n };\n\n callbacks?.onZoom?.({ endValue, startValue });\n });\n }\n\n const handleMouseMove = () => {\n // ECharts updates SVG cursor styles on mouse move, so Needle has to\n // reset it after ECharts' internal handler runs.\n chart?.getZr().setCursorStyle('default');\n };\n const chartChild = chartEchartRef.current?.children[0] as\n | HTMLElement\n | undefined;\n if (!isChartZoomDisabled) {\n chartChild?.addEventListener('mousemove', handleMouseMove);\n }\n\n const handleMouseDown = (params: { event: MouseEvent }) => {\n const event = params.event;\n const amountOfMouseClicks = event.detail;\n const isDoubleClick = amountOfMouseClicks === 2;\n if (isDoubleClick) {\n if (chart === undefined) {\n return;\n }\n chart?.dispatchAction({\n end: 100,\n start: 0,\n type: 'dataZoom',\n });\n if (callbacks?.onZoom) {\n callbacks?.onZoom?.({ endValue: 100, startValue: 0 });\n }\n }\n };\n if (!isChartZoomDisabled) {\n chart?.getZr().on('mousedown', handleMouseDown);\n }\n\n const chartRefCurrentElement = chartEchartRef.current;\n const element = chartRefCurrentElement?.children[0];\n return () => {\n element?.removeEventListener('mousemove', handleMouseMove);\n\n if (chartRefCurrentElement) {\n const chart = getInstanceByDom(chartRefCurrentElement);\n chart?.getZr().off('mousedown', handleMouseDown);\n }\n };\n });\n\n if (chartEchartRef.current !== null && !isChartZoomDisabled) {\n const chart = getInstanceByDom(chartEchartRef.current);\n if (chart) {\n // Needs to be re-set on every re-render. Sets the selectable zoom area\n // over the chart body, not the slider.\n chart.dispatchAction({\n dataZoomSelectActive: true,\n key: 'dataZoomSelect',\n type: 'takeGlobalCursor',\n });\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.useLegendSelection = useLegendSelection;
|
|
24
|
+
exports.useLegendHoverHighlight = useLegendHoverHighlight;
|
|
25
|
+
const echarts_1 = require("echarts");
|
|
26
|
+
const react_1 = require("react");
|
|
27
|
+
const legend_utils_1 = require("../utils/legend-utils");
|
|
28
|
+
const threshold_1 = require("../utils/threshold");
|
|
29
|
+
const use_chart_refs_1 = require("./use-chart-refs");
|
|
30
|
+
const LEGEND_HOVER_HIGHLIGHT_DELAY_MS = 80;
|
|
31
|
+
const LEGEND_SELECTION_EVENT_TYPES = [
|
|
32
|
+
'legendselectchanged',
|
|
33
|
+
'legendselectall',
|
|
34
|
+
'legendselected',
|
|
35
|
+
'legendunselected',
|
|
36
|
+
];
|
|
37
|
+
const getAllSeriesSelected = (series) => Object.fromEntries(series.map((s) => { var _a; return [(_a = s.name) !== null && _a !== void 0 ? _a : '', true]; }));
|
|
38
|
+
const hasSelectionForCurrentSeries = (selection, series) => {
|
|
39
|
+
const selectedNames = Object.keys(selection);
|
|
40
|
+
return (selectedNames.length === series.length &&
|
|
41
|
+
series.every((s) => { var _a; return Object.prototype.hasOwnProperty.call(selection, (_a = s.name) !== null && _a !== void 0 ? _a : ''); }));
|
|
42
|
+
};
|
|
43
|
+
const filterThresholdLineSelection = (selected) => Object.fromEntries(Object.entries(selected).filter(([key]) => { var _a; return !((_a = (0, threshold_1.isThresholdLine)(key)) !== null && _a !== void 0 ? _a : false); }));
|
|
44
|
+
const clearTimeoutRef = (timeoutRef) => {
|
|
45
|
+
if (timeoutRef.current) {
|
|
46
|
+
clearTimeout(timeoutRef.current);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const createLegendSelectionEventHandler = (chart, eventType, setSelectedSeries) => (params) => {
|
|
50
|
+
var _a;
|
|
51
|
+
if (typeof params !== 'object' ||
|
|
52
|
+
params === null ||
|
|
53
|
+
!('selected' in params) ||
|
|
54
|
+
params.selected === null) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (eventType === 'legendselectchanged') {
|
|
58
|
+
(0, legend_utils_1.resetAllSeriesHighlight)(chart);
|
|
59
|
+
}
|
|
60
|
+
setSelectedSeries(filterThresholdLineSelection((_a = params.selected) !== null && _a !== void 0 ? _a : {}));
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Owns React legend selection and keeps it synchronized with ECharts.
|
|
64
|
+
*
|
|
65
|
+
* Current series changes preserve existing selection by name, new series default
|
|
66
|
+
* to visible, removed series are dropped, and ECharts legend events update the
|
|
67
|
+
* React state used to render legend items.
|
|
68
|
+
*/
|
|
69
|
+
function useLegendSelection({ series }) {
|
|
70
|
+
const { chartEchartRef, legendSelectedRef } = (0, use_chart_refs_1.useChartRefsContext)();
|
|
71
|
+
const initialSelected = (0, react_1.useMemo)(() => getAllSeriesSelected(series), [series]);
|
|
72
|
+
const [selectedSeries, setSelectedSeries] = (0, react_1.useState)(initialSelected);
|
|
73
|
+
const renderedSelectedSeries = hasSelectionForCurrentSeries(selectedSeries, series)
|
|
74
|
+
? selectedSeries
|
|
75
|
+
: initialSelected;
|
|
76
|
+
(0, react_1.useEffect)(() => {
|
|
77
|
+
var _a, _b, _c;
|
|
78
|
+
const prev = (_a = legendSelectedRef.current) !== null && _a !== void 0 ? _a : {};
|
|
79
|
+
const next = {};
|
|
80
|
+
for (const s of series) {
|
|
81
|
+
const name = (_b = s.name) !== null && _b !== void 0 ? _b : '';
|
|
82
|
+
next[name] = (_c = prev[name]) !== null && _c !== void 0 ? _c : true;
|
|
83
|
+
}
|
|
84
|
+
setSelectedSeries(next);
|
|
85
|
+
}, [legendSelectedRef, series]);
|
|
86
|
+
(0, react_1.useEffect)(() => {
|
|
87
|
+
legendSelectedRef.current = selectedSeries;
|
|
88
|
+
}, [legendSelectedRef, selectedSeries]);
|
|
89
|
+
(0, react_1.useEffect)(() => {
|
|
90
|
+
if (chartEchartRef.current === null) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const chart = (0, echarts_1.getInstanceByDom)(chartEchartRef.current);
|
|
94
|
+
if (!chart) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const eventHandlers = LEGEND_SELECTION_EVENT_TYPES.map((eventType) => {
|
|
98
|
+
const handler = createLegendSelectionEventHandler(chart, eventType, setSelectedSeries);
|
|
99
|
+
chart.on(eventType, handler);
|
|
100
|
+
return { eventType, handler };
|
|
101
|
+
});
|
|
102
|
+
return () => {
|
|
103
|
+
eventHandlers.forEach(({ eventType, handler }) => {
|
|
104
|
+
chart.off(eventType, handler);
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
}, [chartEchartRef]);
|
|
108
|
+
return { renderedSelectedSeries };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Creates a delayed ECharts highlighter for legend item hover state.
|
|
112
|
+
*
|
|
113
|
+
* Legend hover moves often happen as a quick leave/enter pair between adjacent
|
|
114
|
+
* items. Keeping separate highlight and downplay timers lets the next hover
|
|
115
|
+
* cancel the previous opposite action, preventing the chart from flickering
|
|
116
|
+
* between emphasized and reset states. Deselected legend items are ignored so
|
|
117
|
+
* hidden series do not get emphasized through hover.
|
|
118
|
+
*/
|
|
119
|
+
function useLegendHoverHighlight({ selectedSeries, series, }) {
|
|
120
|
+
const { chartEchartRef } = (0, use_chart_refs_1.useChartRefsContext)();
|
|
121
|
+
const highlightTimeOut = (0, react_1.useRef)(null);
|
|
122
|
+
const downplayTimeOut = (0, react_1.useRef)(null);
|
|
123
|
+
(0, react_1.useEffect)(() => {
|
|
124
|
+
return () => {
|
|
125
|
+
clearTimeoutRef(highlightTimeOut);
|
|
126
|
+
clearTimeoutRef(downplayTimeOut);
|
|
127
|
+
};
|
|
128
|
+
}, []);
|
|
129
|
+
const toggleHighlight = (0, react_1.useCallback)((seriesToUpdate, shouldHighlight) => {
|
|
130
|
+
const isDeselected = seriesToUpdate.name === undefined
|
|
131
|
+
? false
|
|
132
|
+
: !selectedSeries[seriesToUpdate.name];
|
|
133
|
+
if (isDeselected) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const timeoutToClear = shouldHighlight
|
|
137
|
+
? downplayTimeOut
|
|
138
|
+
: highlightTimeOut;
|
|
139
|
+
const timeoutToSet = shouldHighlight ? highlightTimeOut : downplayTimeOut;
|
|
140
|
+
if (timeoutToClear.current) {
|
|
141
|
+
clearTimeout(timeoutToClear.current);
|
|
142
|
+
}
|
|
143
|
+
timeoutToSet.current = setTimeout(() => {
|
|
144
|
+
(0, legend_utils_1.highlightOrDownplaySeries)(chartEchartRef, series, selectedSeries, [seriesToUpdate], shouldHighlight ? 'highlight' : 'downplay');
|
|
145
|
+
}, LEGEND_HOVER_HIGHLIGHT_DELAY_MS);
|
|
146
|
+
}, [chartEchartRef, selectedSeries, series]);
|
|
147
|
+
return { toggleHighlight };
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=use-legend-interactions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-legend-interactions.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-interactions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { type EChartsType, getInstanceByDom } from 'echarts';\nimport {\n type Dispatch,\n type MutableRefObject,\n type SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport type { LegendProps } from '../utils/chart-types';\nimport {\n highlightOrDownplaySeries,\n resetAllSeriesHighlight,\n} from '../utils/legend-utils';\nimport { isThresholdLine } from '../utils/threshold';\nimport { useChartRefsContext } from './use-chart-refs';\n\nconst LEGEND_HOVER_HIGHLIGHT_DELAY_MS = 80;\nconst LEGEND_SELECTION_EVENT_TYPES = [\n 'legendselectchanged',\n 'legendselectall',\n 'legendselected',\n 'legendunselected',\n] as const;\n\ntype LegendSeries = LegendProps['series'];\ntype LegendSelectionEventType = (typeof LEGEND_SELECTION_EVENT_TYPES)[number];\n\ntype LegendSelectionEventParams = {\n selected?: Record<string, boolean> | null;\n};\n\ntype UseLegendHoverHighlightParams = {\n selectedSeries: Record<string, boolean>;\n series: LegendSeries;\n};\n\ntype UseLegendSelectionParams = {\n series: LegendProps['series'];\n};\n\nconst getAllSeriesSelected = (series: LegendProps['series']) =>\n Object.fromEntries(series.map((s) => [s.name ?? '', true]));\n\nconst hasSelectionForCurrentSeries = (\n selection: Record<string, boolean>,\n series: LegendProps['series'],\n) => {\n const selectedNames = Object.keys(selection);\n\n return (\n selectedNames.length === series.length &&\n series.every((s) =>\n Object.prototype.hasOwnProperty.call(selection, s.name ?? ''),\n )\n );\n};\n\nconst filterThresholdLineSelection = (selected: Record<string, boolean>) =>\n Object.fromEntries(\n Object.entries(selected).filter(\n ([key]) => !(isThresholdLine(key) ?? false),\n ),\n );\n\nconst clearTimeoutRef = (\n timeoutRef: MutableRefObject<ReturnType<typeof setTimeout> | null>,\n) => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n};\n\nconst createLegendSelectionEventHandler =\n (\n chart: EChartsType,\n eventType: LegendSelectionEventType,\n setSelectedSeries: Dispatch<SetStateAction<Record<string, boolean>>>,\n ) =>\n (params: unknown) => {\n if (\n typeof params !== 'object' ||\n params === null ||\n !('selected' in params) ||\n params.selected === null\n ) {\n return;\n }\n\n if (eventType === 'legendselectchanged') {\n resetAllSeriesHighlight(chart);\n }\n\n setSelectedSeries(\n filterThresholdLineSelection(\n (params as LegendSelectionEventParams).selected ?? {},\n ),\n );\n };\n\n/**\n * Owns React legend selection and keeps it synchronized with ECharts.\n *\n * Current series changes preserve existing selection by name, new series default\n * to visible, removed series are dropped, and ECharts legend events update the\n * React state used to render legend items.\n */\nexport function useLegendSelection({ series }: UseLegendSelectionParams) {\n const { chartEchartRef, legendSelectedRef } = useChartRefsContext();\n const initialSelected = useMemo(() => getAllSeriesSelected(series), [series]);\n const [selectedSeries, setSelectedSeries] =\n useState<Record<string, boolean>>(initialSelected);\n\n const renderedSelectedSeries = hasSelectionForCurrentSeries(\n selectedSeries,\n series,\n )\n ? selectedSeries\n : initialSelected;\n\n useEffect(() => {\n const prev = legendSelectedRef.current ?? {};\n const next: Record<string, boolean> = {};\n\n for (const s of series) {\n const name = s.name ?? '';\n next[name] = prev[name] ?? true;\n }\n\n setSelectedSeries(next);\n }, [legendSelectedRef, series]);\n\n useEffect(() => {\n legendSelectedRef.current = selectedSeries;\n }, [legendSelectedRef, selectedSeries]);\n\n useEffect(() => {\n if (chartEchartRef.current === null) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n if (!chart) {\n return;\n }\n\n const eventHandlers = LEGEND_SELECTION_EVENT_TYPES.map((eventType) => {\n const handler = createLegendSelectionEventHandler(\n chart,\n eventType,\n setSelectedSeries,\n );\n chart.on(eventType, handler);\n\n return { eventType, handler };\n });\n\n return () => {\n eventHandlers.forEach(({ eventType, handler }) => {\n chart.off(eventType, handler);\n });\n };\n }, [chartEchartRef]);\n\n return { renderedSelectedSeries };\n}\n\n/**\n * Creates a delayed ECharts highlighter for legend item hover state.\n *\n * Legend hover moves often happen as a quick leave/enter pair between adjacent\n * items. Keeping separate highlight and downplay timers lets the next hover\n * cancel the previous opposite action, preventing the chart from flickering\n * between emphasized and reset states. Deselected legend items are ignored so\n * hidden series do not get emphasized through hover.\n */\nexport function useLegendHoverHighlight({\n selectedSeries,\n series,\n}: UseLegendHoverHighlightParams) {\n const { chartEchartRef } = useChartRefsContext();\n const highlightTimeOut = useRef<ReturnType<typeof setTimeout> | null>(null);\n const downplayTimeOut = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n clearTimeoutRef(highlightTimeOut);\n clearTimeoutRef(downplayTimeOut);\n };\n }, []);\n\n const toggleHighlight = useCallback(\n (\n seriesToUpdate: { name: string; color: string },\n shouldHighlight: boolean,\n ) => {\n const isDeselected =\n seriesToUpdate.name === undefined\n ? false\n : !selectedSeries[seriesToUpdate.name];\n\n if (isDeselected) {\n return;\n }\n\n const timeoutToClear = shouldHighlight\n ? downplayTimeOut\n : highlightTimeOut;\n const timeoutToSet = shouldHighlight ? highlightTimeOut : downplayTimeOut;\n\n if (timeoutToClear.current) {\n clearTimeout(timeoutToClear.current);\n }\n\n timeoutToSet.current = setTimeout(() => {\n highlightOrDownplaySeries(\n chartEchartRef,\n series,\n selectedSeries,\n [seriesToUpdate],\n shouldHighlight ? 'highlight' : 'downplay',\n );\n }, LEGEND_HOVER_HIGHLIGHT_DELAY_MS);\n },\n [chartEchartRef, selectedSeries, series],\n );\n\n return { toggleHighlight };\n}\n"]}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) "Neo4j"
|
|
5
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
6
|
+
*
|
|
7
|
+
* This file is part of Neo4j.
|
|
8
|
+
*
|
|
9
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
10
|
+
* it under the terms of the GNU General Public License as published by
|
|
11
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
* (at your option) any later version.
|
|
13
|
+
*
|
|
14
|
+
* This program is distributed in the hope that it will be useful,
|
|
15
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
* GNU General Public License for more details.
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License
|
|
20
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.useLegendSeries = useLegendSeries;
|
|
24
|
+
const echarts_1 = require("echarts");
|
|
25
|
+
const react_1 = require("react");
|
|
26
|
+
const threshold_1 = require("../utils/threshold");
|
|
27
|
+
const use_chart_refs_1 = require("./use-chart-refs");
|
|
28
|
+
const isThresholdLineSeries = (series) => series.type === 'line' &&
|
|
29
|
+
typeof series.name === 'string' &&
|
|
30
|
+
(0, threshold_1.isThresholdLine)(series.name);
|
|
31
|
+
const getDatasetForSeries = (optionDataset, series) => {
|
|
32
|
+
const datasetList = Array.isArray(optionDataset)
|
|
33
|
+
? optionDataset
|
|
34
|
+
: [optionDataset];
|
|
35
|
+
if (series.datasetId && Array.isArray(optionDataset)) {
|
|
36
|
+
return datasetList.find((dataset) => (dataset === null || dataset === void 0 ? void 0 : dataset.id) === series.datasetId);
|
|
37
|
+
}
|
|
38
|
+
if (series.datasetIndex !== undefined) {
|
|
39
|
+
return datasetList[series.datasetIndex];
|
|
40
|
+
}
|
|
41
|
+
return datasetList[0];
|
|
42
|
+
};
|
|
43
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
44
|
+
const getCachedLegendColor = ({ chart, isAllVisible, legendColorCacheRef, name, seriesIndex, dataIndexInside, }) => {
|
|
45
|
+
var _a;
|
|
46
|
+
const freshColor = chart === null || chart === void 0 ? void 0 : chart.getVisual({ dataIndexInside, seriesIndex }, 'color');
|
|
47
|
+
if (isAllVisible && typeof freshColor === 'string') {
|
|
48
|
+
legendColorCacheRef.current.set(name, freshColor);
|
|
49
|
+
}
|
|
50
|
+
return ((_a = legendColorCacheRef.current.get(name)) !== null && _a !== void 0 ? _a : (typeof freshColor === 'string' ? freshColor : '#000000'));
|
|
51
|
+
};
|
|
52
|
+
const createPieLegendSeriesItem = ({ chart, dataIndexInside, isAllVisible, legendColorCacheRef, name, seriesIndex, }) => ({
|
|
53
|
+
color: getCachedLegendColor({
|
|
54
|
+
chart,
|
|
55
|
+
dataIndexInside,
|
|
56
|
+
isAllVisible,
|
|
57
|
+
legendColorCacheRef,
|
|
58
|
+
name,
|
|
59
|
+
seriesIndex,
|
|
60
|
+
}),
|
|
61
|
+
name,
|
|
62
|
+
});
|
|
63
|
+
const getPieLegendSeriesFromArrayRows = ({ chart, dataset, encodedItemName, isAllVisible, legendColorCacheRef, seriesIndex, }) => {
|
|
64
|
+
const source = dataset === null || dataset === void 0 ? void 0 : dataset.source;
|
|
65
|
+
if (!Array.isArray(source) || !Array.isArray(source[0])) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const itemNameIndex = source[0].findIndex((item) => item === encodedItemName);
|
|
69
|
+
if (itemNameIndex === -1) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
return source.slice(1).flatMap((row, rowIndex) => {
|
|
73
|
+
if (!Array.isArray(row)) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
return createPieLegendSeriesItem({
|
|
77
|
+
chart,
|
|
78
|
+
dataIndexInside: rowIndex,
|
|
79
|
+
isAllVisible,
|
|
80
|
+
legendColorCacheRef,
|
|
81
|
+
name: String(row[itemNameIndex]),
|
|
82
|
+
seriesIndex,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
const getPieLegendSeriesFromObjectRows = ({ chart, dataset, encodedItemName, isAllVisible, legendColorCacheRef, seriesIndex, }) => {
|
|
87
|
+
const source = dataset === null || dataset === void 0 ? void 0 : dataset.source;
|
|
88
|
+
if (!Array.isArray(source) || typeof encodedItemName !== 'string') {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return source.flatMap((row, rowIndex) => {
|
|
92
|
+
if (!isRecord(row) || !(encodedItemName in row)) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
return createPieLegendSeriesItem({
|
|
96
|
+
chart,
|
|
97
|
+
dataIndexInside: rowIndex,
|
|
98
|
+
isAllVisible,
|
|
99
|
+
legendColorCacheRef,
|
|
100
|
+
name: String(row[encodedItemName]),
|
|
101
|
+
seriesIndex,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
const getPieLegendSeries = (params) => {
|
|
106
|
+
var _a;
|
|
107
|
+
const source = (_a = params.dataset) === null || _a === void 0 ? void 0 : _a.source;
|
|
108
|
+
if (!Array.isArray(source) || source.length === 0) {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
return Array.isArray(source[0])
|
|
112
|
+
? getPieLegendSeriesFromArrayRows(params)
|
|
113
|
+
: getPieLegendSeriesFromObjectRows(params);
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Derives Needle legend rows from ECharts' normalized option and visual state.
|
|
117
|
+
*
|
|
118
|
+
* Standard series map one-to-one with legend items. Pie charts instead create a
|
|
119
|
+
* legend item for each data row, so the hook reads the encoded item-name column
|
|
120
|
+
* from the dataset and asks ECharts for each slice color. Fresh colors are
|
|
121
|
+
* cached while all slices are visible because ECharts reports dimmed colors for
|
|
122
|
+
* deselected slices.
|
|
123
|
+
*
|
|
124
|
+
* The hook waits until the first chart resize has completed so color lookups run
|
|
125
|
+
* against an initialized ECharts instance.
|
|
126
|
+
*/
|
|
127
|
+
function useLegendSeries({ chartOption, isWaitingForFirstResize, }) {
|
|
128
|
+
const { chartEchartRef, legendColorCacheRef, legendSelectedRef } = (0, use_chart_refs_1.useChartRefsContext)();
|
|
129
|
+
return (0, react_1.useMemo)(() => {
|
|
130
|
+
var _a;
|
|
131
|
+
if (chartEchartRef.current === null || isWaitingForFirstResize) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const chart = (0, echarts_1.getInstanceByDom)(chartEchartRef.current);
|
|
135
|
+
const optionSeries = (_a = chartOption === null || chartOption === void 0 ? void 0 : chartOption.series) !== null && _a !== void 0 ? _a : [];
|
|
136
|
+
const optionDataset = chartOption === null || chartOption === void 0 ? void 0 : chartOption.dataset;
|
|
137
|
+
const isAllLegendSeriesVisible = Object.values(legendSelectedRef.current).every((v) => v);
|
|
138
|
+
const legendSeries = [];
|
|
139
|
+
if (Array.isArray(optionSeries)) {
|
|
140
|
+
optionSeries.forEach((currentSeries, index) => {
|
|
141
|
+
var _a;
|
|
142
|
+
if (currentSeries === null) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
else if (isThresholdLineSeries(currentSeries)) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
else if (currentSeries.type === 'pie') {
|
|
149
|
+
legendSeries.push(...getPieLegendSeries({
|
|
150
|
+
chart,
|
|
151
|
+
dataset: getDatasetForSeries(optionDataset, currentSeries),
|
|
152
|
+
encodedItemName: (_a = currentSeries.encode) === null || _a === void 0 ? void 0 : _a.itemName,
|
|
153
|
+
isAllVisible: isAllLegendSeriesVisible,
|
|
154
|
+
legendColorCacheRef,
|
|
155
|
+
seriesIndex: index,
|
|
156
|
+
}));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
const name = currentSeries.name;
|
|
161
|
+
if (name === undefined) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const color = chart === null || chart === void 0 ? void 0 : chart.getVisual({ seriesIndex: index }, 'color');
|
|
165
|
+
legendSeries.push({
|
|
166
|
+
color: typeof color === 'string' ? color : '#000000',
|
|
167
|
+
name: String(name),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
return legendSeries;
|
|
173
|
+
}, [
|
|
174
|
+
chartEchartRef,
|
|
175
|
+
chartOption,
|
|
176
|
+
isWaitingForFirstResize,
|
|
177
|
+
legendColorCacheRef,
|
|
178
|
+
legendSelectedRef,
|
|
179
|
+
]);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=use-legend-series.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-legend-series.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-series.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n DatasetComponentOption,\n EChartsOption,\n EChartsType,\n} from 'echarts';\nimport { getInstanceByDom } from 'echarts';\nimport { useMemo } from 'react';\n\nimport type {\n LegendProps,\n NeedleSeries,\n SeriesOption,\n} from '../utils/chart-types';\nimport { isThresholdLine } from '../utils/threshold';\nimport { type ChartRefs, useChartRefsContext } from './use-chart-refs';\n\ntype UseLegendSeriesParams = {\n chartOption: EChartsOption | undefined;\n isWaitingForFirstResize: boolean;\n};\n\ntype LegendSeries = LegendProps['series'];\ntype NeedleSeriesItem = NeedleSeries[number];\ntype SeriesWithDataset = SeriesOption & {\n datasetId?: string;\n datasetIndex?: number;\n};\n\ntype PieLegendSeriesParams = {\n chart: EChartsType | undefined;\n dataset: DatasetComponentOption | undefined;\n encodedItemName: unknown;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n seriesIndex: number;\n};\n\ntype GetCachedLegendColorParams = {\n chart: EChartsType | undefined;\n dataIndexInside: number;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n name: string;\n seriesIndex: number;\n};\n\nconst isThresholdLineSeries = (series: NeedleSeriesItem) =>\n series.type === 'line' &&\n typeof series.name === 'string' &&\n isThresholdLine(series.name);\n\nconst getDatasetForSeries = (\n optionDataset: EChartsOption['dataset'],\n series: SeriesWithDataset,\n) => {\n const datasetList = Array.isArray(optionDataset)\n ? optionDataset\n : [optionDataset];\n\n if (series.datasetId && Array.isArray(optionDataset)) {\n return datasetList.find((dataset) => dataset?.id === series.datasetId);\n }\n\n if (series.datasetIndex !== undefined) {\n return datasetList[series.datasetIndex];\n }\n\n return datasetList[0];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst getCachedLegendColor = ({\n chart,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n dataIndexInside,\n}: GetCachedLegendColorParams) => {\n const freshColor = chart?.getVisual(\n { dataIndexInside, seriesIndex },\n 'color',\n );\n\n if (isAllVisible && typeof freshColor === 'string') {\n legendColorCacheRef.current.set(name, freshColor);\n }\n\n return (\n legendColorCacheRef.current.get(name) ??\n (typeof freshColor === 'string' ? freshColor : '#000000')\n );\n};\n\nconst createPieLegendSeriesItem = ({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n}: GetCachedLegendColorParams) => ({\n color: getCachedLegendColor({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n }),\n name,\n});\n\nconst getPieLegendSeriesFromArrayRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || !Array.isArray(source[0])) {\n return [];\n }\n\n const itemNameIndex = source[0].findIndex((item) => item === encodedItemName);\n if (itemNameIndex === -1) {\n return [];\n }\n\n return source.slice(1).flatMap((row, rowIndex) => {\n if (!Array.isArray(row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[itemNameIndex]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeriesFromObjectRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || typeof encodedItemName !== 'string') {\n return [];\n }\n\n return source.flatMap((row, rowIndex) => {\n if (!isRecord(row) || !(encodedItemName in row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[encodedItemName]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeries = (params: PieLegendSeriesParams): LegendSeries => {\n const source = params.dataset?.source;\n if (!Array.isArray(source) || source.length === 0) {\n return [];\n }\n\n return Array.isArray(source[0])\n ? getPieLegendSeriesFromArrayRows(params)\n : getPieLegendSeriesFromObjectRows(params);\n};\n\n/**\n * Derives Needle legend rows from ECharts' normalized option and visual state.\n *\n * Standard series map one-to-one with legend items. Pie charts instead create a\n * legend item for each data row, so the hook reads the encoded item-name column\n * from the dataset and asks ECharts for each slice color. Fresh colors are\n * cached while all slices are visible because ECharts reports dimmed colors for\n * deselected slices.\n *\n * The hook waits until the first chart resize has completed so color lookups run\n * against an initialized ECharts instance.\n */\nexport function useLegendSeries({\n chartOption,\n isWaitingForFirstResize,\n}: UseLegendSeriesParams): LegendSeries | undefined {\n const { chartEchartRef, legendColorCacheRef, legendSelectedRef } =\n useChartRefsContext();\n\n return useMemo(() => {\n if (chartEchartRef.current === null || isWaitingForFirstResize) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n const optionSeries = (chartOption?.series as NeedleSeries) ?? [];\n const optionDataset = chartOption?.dataset;\n const isAllLegendSeriesVisible = Object.values(\n legendSelectedRef.current,\n ).every((v) => v);\n\n const legendSeries: LegendSeries = [];\n if (Array.isArray(optionSeries)) {\n optionSeries.forEach((currentSeries, index) => {\n if (currentSeries === null) {\n return;\n } else if (isThresholdLineSeries(currentSeries)) {\n return;\n } else if (currentSeries.type === 'pie') {\n legendSeries.push(\n ...getPieLegendSeries({\n chart,\n dataset: getDatasetForSeries(\n optionDataset,\n currentSeries as SeriesWithDataset,\n ),\n encodedItemName: currentSeries.encode?.itemName,\n isAllVisible: isAllLegendSeriesVisible,\n legendColorCacheRef,\n seriesIndex: index,\n }),\n );\n return;\n } else {\n const name = currentSeries.name;\n\n if (name === undefined) {\n return;\n }\n\n const color = chart?.getVisual({ seriesIndex: index }, 'color');\n legendSeries.push({\n color: typeof color === 'string' ? color : '#000000',\n name: String(name),\n });\n }\n });\n }\n return legendSeries;\n }, [\n chartEchartRef,\n chartOption,\n isWaitingForFirstResize,\n legendColorCacheRef,\n legendSelectedRef,\n ]);\n}\n"]}
|