@neo4j-ndl/react-charts 1.2.13 → 1.3.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/lib/cjs/charts/Chart.js +20 -0
- package/lib/cjs/charts/Chart.js.map +1 -1
- package/lib/cjs/charts/ChartRender.js +1 -3
- package/lib/cjs/charts/ChartRender.js.map +1 -1
- package/lib/cjs/charts/hooks/use-chart-option.js +1 -3
- package/lib/cjs/charts/hooks/use-chart-option.js.map +1 -1
- package/lib/cjs/charts/tests/HorizontalBarWithVerticalSlider.js +78 -0
- package/lib/cjs/charts/tests/HorizontalBarWithVerticalSlider.js.map +1 -0
- package/lib/cjs/charts/utils/build-chart-option.js +48 -16
- package/lib/cjs/charts/utils/build-chart-option.js.map +1 -1
- package/lib/cjs/charts/utils/user-option-utils.js +171 -8
- package/lib/cjs/charts/utils/user-option-utils.js.map +1 -1
- package/lib/esm/charts/Chart.js +20 -0
- package/lib/esm/charts/Chart.js.map +1 -1
- package/lib/esm/charts/ChartRender.js +2 -4
- package/lib/esm/charts/ChartRender.js.map +1 -1
- package/lib/esm/charts/hooks/use-chart-option.js +1 -3
- package/lib/esm/charts/hooks/use-chart-option.js.map +1 -1
- package/lib/esm/charts/tests/HorizontalBarWithVerticalSlider.js +74 -0
- package/lib/esm/charts/tests/HorizontalBarWithVerticalSlider.js.map +1 -0
- package/lib/esm/charts/utils/build-chart-option.js +46 -16
- package/lib/esm/charts/utils/build-chart-option.js.map +1 -1
- package/lib/esm/charts/utils/user-option-utils.js +168 -7
- package/lib/esm/charts/utils/user-option-utils.js.map +1 -1
- package/lib/types/charts/Chart.d.ts +20 -0
- package/lib/types/charts/Chart.d.ts.map +1 -1
- package/lib/types/charts/ChartRender.d.ts.map +1 -1
- package/lib/types/charts/hooks/use-chart-option.d.ts +1 -2
- package/lib/types/charts/hooks/use-chart-option.d.ts.map +1 -1
- package/lib/types/charts/tests/HorizontalBarWithVerticalSlider.d.ts +38 -0
- package/lib/types/charts/tests/HorizontalBarWithVerticalSlider.d.ts.map +1 -0
- package/lib/types/charts/utils/build-chart-option.d.ts +17 -4
- package/lib/types/charts/utils/build-chart-option.d.ts.map +1 -1
- package/lib/types/charts/utils/user-option-utils.d.ts +26 -2
- package/lib/types/charts/utils/user-option-utils.d.ts.map +1 -1
- package/package.json +3 -3
- package/skills/ndl-react-charts/SKILL.md +1 -1
- package/skills/ndl-react-charts/components/charts.md +195 -0
package/lib/cjs/charts/Chart.js
CHANGED
|
@@ -71,6 +71,26 @@ const ChartLegend = ({ chartOption, isLayoutReady, isWaitingForFirstResize, onLa
|
|
|
71
71
|
* <Chart dataset={dataset} series={series} xAxis={xAxis} yAxis={yAxis} />
|
|
72
72
|
* </div>
|
|
73
73
|
* ```
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* **Data zoom sliders.** A `dataZoom` slider passed through `option` targets
|
|
77
|
+
* the x-axis unless it is bound to an axis explicitly, so on a horizontal bar
|
|
78
|
+
* chart it zooms the value axis rather than the categories. Bind the slider to
|
|
79
|
+
* the category axis with `yAxisIndex: [0]` (or set `orient: 'vertical'`) to
|
|
80
|
+
* page through the bars instead; Needle then lays the slider out vertically on
|
|
81
|
+
* the right of the chart and reserves grid space for it. Sliders that target a
|
|
82
|
+
* continuous (`value`, `time`, or `log`) axis default to `filterMode: 'none'`
|
|
83
|
+
* so out-of-window data is clipped rather than removed, while category-axis
|
|
84
|
+
* sliders keep ECharts' `'filter'` default so the opposite value axis rescales
|
|
85
|
+
* to the visible data.
|
|
86
|
+
*
|
|
87
|
+
* **Drag-to-zoom.** Dragging in the plot area zooms the axes your `dataZoom`
|
|
88
|
+
* config targets: entries bound to a y-axis (`yAxisIndex` or
|
|
89
|
+
* `orient: 'vertical'`) make the drag select a y band, entries on both axes
|
|
90
|
+
* make it select a rectangle, and without any `dataZoom` config the drag zooms
|
|
91
|
+
* the x-axis. Set `toolbox.feature.dataZoom` through `option` to override the
|
|
92
|
+
* derived axes explicitly. When every drag-targeted axis is continuous the
|
|
93
|
+
* drag defaults to `filterMode: 'none'`, matching the slider rule above.
|
|
74
94
|
*/
|
|
75
95
|
const Chart = (_a) => {
|
|
76
96
|
var { style, legend } = _a, chartProps = __rest(_a, ["style", "legend"]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chart.js","sourceRoot":"","sources":["../../../src/charts/Chart.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAsBA,iCAAyD;AAEzD,qDAAkD;AAClD,+CAA4C;AAC5C,2DAA2D;AAC3D,iEAA4D;AAC5D,qCAAkC;AAUlC;;;;;;;GAOG;AACH,MAAM,WAAW,GAAG,CAAC,EACnB,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,aAAa,GACI,EAAE,EAAE;IACrB,MAAM,YAAY,GAAG,IAAA,mCAAe,EAAC;QACnC,WAAW;QACX,uBAAuB;KACxB,CAAC,CAAC;IAEH,IAAI,uBAAuB,EAAE,CAAC;QAC5B,OAAO,CACL,+CACc,MAAM,EAClB,SAAS,EAAC,mEAAmE,GAC7E,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,uBAAC,eAAM,IACL,MAAM,EAAE,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,EAAE,EAC1B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,GAC5B,CACH,CAAC;AACJ,CAAC,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"Chart.js","sourceRoot":"","sources":["../../../src/charts/Chart.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;AAsBA,iCAAyD;AAEzD,qDAAkD;AAClD,+CAA4C;AAC5C,2DAA2D;AAC3D,iEAA4D;AAC5D,qCAAkC;AAUlC;;;;;;;GAOG;AACH,MAAM,WAAW,GAAG,CAAC,EACnB,WAAW,EACX,aAAa,EACb,uBAAuB,EACvB,aAAa,GACI,EAAE,EAAE;IACrB,MAAM,YAAY,GAAG,IAAA,mCAAe,EAAC;QACnC,WAAW;QACX,uBAAuB;KACxB,CAAC,CAAC;IAEH,IAAI,uBAAuB,EAAE,CAAC;QAC5B,OAAO,CACL,+CACc,MAAM,EAClB,SAAS,EAAC,mEAAmE,GAC7E,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CACL,uBAAC,eAAM,IACL,MAAM,EAAE,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,EAAE,EAC1B,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,aAAa,GAC5B,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACI,MAAM,KAAK,GAAG,CAAC,EAA4C,EAAE,EAAE;QAAhD,EAAE,KAAK,EAAE,MAAM,OAA6B,EAAxB,UAAU,cAA9B,mBAAgC,CAAF;IAClD,MAAM,CAAC,uBAAuB,EAAE,0BAA0B,CAAC,GAAG,IAAA,gBAAQ,EAAC,IAAI,CAAC,CAAC;IAC7E,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,GAAiB,CAAC;IAChE,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAA,CAAC,CAAC;IAE9E,MAAM,uBAAuB,GAAG,IAAA,mBAAW,EAAC,GAAG,EAAE;QAC/C,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAA,EAAE,CAAC;YAClB,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC,EAAE,CAAC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CAAC,CAAC,CAAC;IAEnB,MAAM,oBAAoB,GACxB,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,KAAI,CAAC,mBAAmB;QAClC,CAAC,CAAC,0CAA0C;QAC5C,CAAC,CAAC,kBAAkB,CAAC;IAEzB,OAAO,CACL,uBAAC,kCAAiB,cAChB,wBAAC,+BAAc,IAAC,KAAK,EAAE,KAAK,aAC1B,gCAAK,SAAS,EAAE,oBAAoB,YAClC,uBAAC,yBAAW,oBACN,UAAU,IACd,mBAAmB,EAAE,cAAc,EACnC,mBAAmB,EAAE,0BAA0B,IAC/C,GACE,EACL,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,KAAI,CACf,uBAAC,WAAW,IACV,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,mBAAmB,EAClC,uBAAuB,EAAE,uBAAuB,EAChD,aAAa,EAAE,uBAAuB,GACtC,CACH,IACc,GACC,CACrB,CAAC;AACJ,CAAC,CAAC;AAzCW,QAAA,KAAK,SAyChB","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 { useCallback, useEffect, useState } from 'react';\n\nimport { ChartContainer } from './ChartContainer';\nimport { ChartRender } from './ChartRender';\nimport { ChartRefsProvider } from './hooks/use-chart-refs';\nimport { useLegendSeries } from './hooks/use-legend-series';\nimport { Legend } from './Legend';\nimport { type ChartProps } from './utils/chart-types';\n\ntype ChartLegendProps = {\n chartOption: EChartsOption | undefined;\n isLayoutReady: boolean;\n isWaitingForFirstResize: boolean;\n onLayoutReady?: () => void;\n};\n\n/**\n * Bridges the rendered ECharts option into the React legend.\n *\n * `useLegendSeries` reads the current chart option and ECharts color state to\n * derive the legend rows. Rendering is deferred until the chart has completed\n * its first resize so the legend does not measure against an uninitialized\n * chart instance.\n */\nconst ChartLegend = ({\n chartOption,\n isLayoutReady,\n isWaitingForFirstResize,\n onLayoutReady,\n}: ChartLegendProps) => {\n const legendSeries = useLegendSeries({\n chartOption,\n isWaitingForFirstResize,\n });\n\n if (isWaitingForFirstResize) {\n return (\n <div\n aria-hidden=\"true\"\n className=\"ndl-chart-legend-container ndl-chart-legend-container-placeholder\"\n />\n );\n }\n\n return (\n <Legend\n series={legendSeries ?? []}\n onLayoutReady={onLayoutReady}\n isLayoutReady={isLayoutReady}\n />\n );\n};\n\n/**\n * A chart component powered by Apache ECharts with Needle's customization and theming.\n *\n * The `Chart` component fills 100% of its parent's width and height. Because it\n * relies on the container's `clientHeight` to size the canvas, **the parent element\n * must have an explicit height** (e.g. a fixed px/rem value or a viewport unit).\n *\n * @example\n * ```tsx\n * <div style={{ height: '350px' }}>\n * <Chart dataset={dataset} series={series} xAxis={xAxis} yAxis={yAxis} />\n * </div>\n * ```\n *\n * @remarks\n * **Data zoom sliders.** A `dataZoom` slider passed through `option` targets\n * the x-axis unless it is bound to an axis explicitly, so on a horizontal bar\n * chart it zooms the value axis rather than the categories. Bind the slider to\n * the category axis with `yAxisIndex: [0]` (or set `orient: 'vertical'`) to\n * page through the bars instead; Needle then lays the slider out vertically on\n * the right of the chart and reserves grid space for it. Sliders that target a\n * continuous (`value`, `time`, or `log`) axis default to `filterMode: 'none'`\n * so out-of-window data is clipped rather than removed, while category-axis\n * sliders keep ECharts' `'filter'` default so the opposite value axis rescales\n * to the visible data.\n *\n * **Drag-to-zoom.** Dragging in the plot area zooms the axes your `dataZoom`\n * config targets: entries bound to a y-axis (`yAxisIndex` or\n * `orient: 'vertical'`) make the drag select a y band, entries on both axes\n * make it select a rectangle, and without any `dataZoom` config the drag zooms\n * the x-axis. Set `toolbox.feature.dataZoom` through `option` to override the\n * derived axes explicitly. When every drag-targeted axis is continuous the\n * drag defaults to `filterMode: 'none'`, matching the slider rule above.\n */\nexport const Chart = ({ style, legend, ...chartProps }: ChartProps) => {\n const [isWaitingForFirstResize, setIsWaitingForFirstResize] = useState(true);\n const [chartOption, setChartOption] = useState<EChartsOption>();\n const [isLegendLayoutReady, setIsLegendLayoutReady] = useState(!legend?.show);\n\n const handleLegendLayoutReady = useCallback(() => {\n setIsLegendLayoutReady(true);\n }, []);\n\n useEffect(() => {\n if (!legend?.show) {\n setIsLegendLayoutReady(true);\n }\n }, [legend?.show]);\n\n const chartLayoutClassName =\n legend?.show && !isLegendLayoutReady\n ? 'ndl-chart-layout ndl-chart-layout-hidden'\n : 'ndl-chart-layout';\n\n return (\n <ChartRefsProvider>\n <ChartContainer style={style}>\n <div className={chartLayoutClassName}>\n <ChartRender\n {...chartProps}\n onChartOptionChange={setChartOption}\n onFirstResizeChange={setIsWaitingForFirstResize}\n />\n </div>\n {legend?.show && (\n <ChartLegend\n chartOption={chartOption}\n isLayoutReady={isLegendLayoutReady}\n isWaitingForFirstResize={isWaitingForFirstResize}\n onLayoutReady={handleLegendLayoutReady}\n />\n )}\n </ChartContainer>\n </ChartRefsProvider>\n );\n};\n"]}
|
|
@@ -44,9 +44,8 @@ const ChartRender = ({ callbacks, dataset, isChartZoomDisabled = false, isLoadin
|
|
|
44
44
|
const dataZoomOptions = userOption === null || userOption === void 0 ? void 0 : userOption.dataZoom;
|
|
45
45
|
const toolboxOptions = userOption === null || userOption === void 0 ? void 0 : userOption.toolbox;
|
|
46
46
|
const { theme } = (0, react_1.useNeedleTheme)();
|
|
47
|
-
const hasSliderZoom = (0, build_chart_option_1.hasSliderDataZoom)(dataZoomOptions);
|
|
48
47
|
const thresholdLines = (0, react_2.useMemo)(() => (0, threshold_1.normalizeThresholdLines)(propsSeries), [propsSeries]);
|
|
49
|
-
const dataZoom = (0, react_2.useMemo)(() => (0, user_option_utils_1.mergeDataZoom)(dataZoomOptions), [dataZoomOptions]);
|
|
48
|
+
const dataZoom = (0, react_2.useMemo)(() => (0, user_option_utils_1.mergeDataZoom)(dataZoomOptions, { xAxis: propXAxis, yAxis: propYAxis }), [dataZoomOptions, propXAxis, propYAxis]);
|
|
50
49
|
const series = (0, react_2.useMemo)(() => (0, user_option_utils_1.mergeSeries)(propsSeries, theme, userOption, palette), [palette, propsSeries, theme, userOption]);
|
|
51
50
|
const xAxis = (0, react_2.useMemo)(() => (0, user_option_utils_1.mergeXAxis)(propXAxis, theme), [propXAxis, theme]);
|
|
52
51
|
const yAxis = (0, react_2.useMemo)(() => (0, user_option_utils_1.mergeYAxis)(propYAxis, theme), [propYAxis, theme]);
|
|
@@ -67,7 +66,6 @@ const ChartRender = ({ callbacks, dataset, isChartZoomDisabled = false, isLoadin
|
|
|
67
66
|
dataset,
|
|
68
67
|
hasCategoryXAxis,
|
|
69
68
|
hasMarkArea,
|
|
70
|
-
hasSliderZoom,
|
|
71
69
|
propsSeries,
|
|
72
70
|
series,
|
|
73
71
|
settings,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartRender.js","sourceRoot":"","sources":["../../../src/charts/ChartRender.tsx"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,4CAAkD;AAElD,iCAA2C;AAE3C,mEAIoC;AACpC,+DAA0D;AAC1D,2DAA6D;AAC7D,2DAAsD;AACtD,
|
|
1
|
+
{"version":3,"file":"ChartRender.js","sourceRoot":"","sources":["../../../src/charts/ChartRender.tsx"],"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 { useNeedleTheme } from '@neo4j-ndl/react';\nimport type { EChartsOption } from 'echarts';\nimport { useEffect, useMemo } from 'react';\n\nimport {\n useChartLifecycle,\n useChartLoading,\n useChartResize,\n} from './hooks/use-chart-instance';\nimport { useChartOption } from './hooks/use-chart-option';\nimport { useChartRefsContext } from './hooks/use-chart-refs';\nimport { useChartZoom } from './hooks/use-chart-zoom';\nimport {\n hasCategoryXAxis as getHasCategoryXAxis,\n hasMarkAreaInSeries,\n} from './utils/build-chart-option';\nimport type { ChartProps } from './utils/chart-types';\nimport { defaultChartSettings } from './utils/defaults';\nimport { normalizeThresholdLines } from './utils/threshold';\nimport {\n mergeDataZoom,\n mergeSeries,\n mergeXAxis,\n mergeYAxis,\n} from './utils/user-option-utils';\n\ntype ChartRenderProps = Omit<ChartProps, 'legend' | 'style'> & {\n onChartOptionChange: (chartOption: EChartsOption | undefined) => void;\n onFirstResizeChange: (isWaitingForFirstResize: boolean) => void;\n};\n\n/**\n * Owns the ECharts instance element and coordinates chart-specific hooks.\n *\n * The component normalizes user props into Needle-themed ECharts options,\n * initializes/resizes the chart instance, applies loading and zoom behavior, and\n * reports derived chart state back to `Chart` for legend rendering.\n */\nexport const ChartRender = ({\n callbacks,\n dataset,\n isChartZoomDisabled = false,\n isLoading,\n onChartOptionChange,\n onFirstResizeChange,\n option: userOption,\n palette,\n series: propsSeries,\n settings = defaultChartSettings,\n xAxis: propXAxis,\n yAxis: propYAxis,\n}: ChartRenderProps) => {\n const { chartEchartRef } = useChartRefsContext();\n const dataZoomOptions = (userOption as EChartsOption)?.dataZoom;\n const toolboxOptions = (userOption as EChartsOption)?.toolbox;\n const { theme } = useNeedleTheme();\n\n const thresholdLines = useMemo(\n () => normalizeThresholdLines(propsSeries),\n [propsSeries],\n );\n const dataZoom = useMemo(\n () =>\n mergeDataZoom(dataZoomOptions, { xAxis: propXAxis, yAxis: propYAxis }),\n [dataZoomOptions, propXAxis, propYAxis],\n );\n const series = useMemo(\n () => mergeSeries(propsSeries, theme, userOption, palette),\n [palette, propsSeries, theme, userOption],\n );\n const xAxis = useMemo(() => mergeXAxis(propXAxis, theme), [propXAxis, theme]);\n const yAxis = useMemo(() => mergeYAxis(propYAxis, theme), [propYAxis, theme]);\n const hasCategoryXAxis = getHasCategoryXAxis(xAxis);\n const hasMarkArea = hasMarkAreaInSeries(series);\n\n /**\n * Hook responsibilities:\n * - `useChartLifecycle` creates/disposes the ECharts instance and updates theme data.\n * - `useChartResize` keeps the canvas sized to its container before first render.\n * - `useChartOption` builds and applies the merged ECharts option.\n * - `useChartZoom` attaches consumer zoom callbacks.\n * - `useChartLoading` synchronizes the loading overlay with chart readiness.\n */\n useChartLifecycle({ palette, theme });\n const { isWaitingForFirstResize } = useChartResize();\n const chartOption = useChartOption({\n dataZoom,\n dataset,\n hasCategoryXAxis,\n hasMarkArea,\n propsSeries,\n series,\n settings,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n });\n useChartZoom({ callbacks, isChartZoomDisabled });\n useChartLoading({\n isLoading,\n isWaitingForFirstResize,\n theme,\n });\n\n useEffect(() => {\n onFirstResizeChange(isWaitingForFirstResize);\n }, [isWaitingForFirstResize, onFirstResizeChange]);\n\n useEffect(() => {\n onChartOptionChange(chartOption);\n }, [chartOption, onChartOptionChange]);\n\n return <div ref={chartEchartRef} className=\"ndl-chart-echart\" />;\n};\n"]}
|
|
@@ -34,7 +34,7 @@ const use_chart_refs_1 = require("./use-chart-refs");
|
|
|
34
34
|
* downstream code, especially the custom legend, can read the final series and
|
|
35
35
|
* dataset shape ECharts is actually using.
|
|
36
36
|
*/
|
|
37
|
-
function useChartOption({ dataZoom, dataset, hasCategoryXAxis,
|
|
37
|
+
function useChartOption({ dataZoom, dataset, hasCategoryXAxis, propsSeries, series, settings, thresholdLines, toolboxOptions, userOption, xAxis, yAxis, hasMarkArea, }) {
|
|
38
38
|
const { chartEchartRef, legendSelectedRef } = (0, use_chart_refs_1.useChartRefsContext)();
|
|
39
39
|
const [chartOption, setChartOption] = (0, react_1.useState)();
|
|
40
40
|
(0, react_1.useEffect)(() => {
|
|
@@ -47,7 +47,6 @@ function useChartOption({ dataZoom, dataset, hasCategoryXAxis, hasSliderZoom, pr
|
|
|
47
47
|
dataset,
|
|
48
48
|
hasCategoryXAxis,
|
|
49
49
|
hasMarkArea,
|
|
50
|
-
hasSliderZoom,
|
|
51
50
|
legendSelected: legendSelectedRef.current || {},
|
|
52
51
|
propsSeries,
|
|
53
52
|
series,
|
|
@@ -65,7 +64,6 @@ function useChartOption({ dataZoom, dataset, hasCategoryXAxis, hasSliderZoom, pr
|
|
|
65
64
|
dataset,
|
|
66
65
|
hasCategoryXAxis,
|
|
67
66
|
hasMarkArea,
|
|
68
|
-
hasSliderZoom,
|
|
69
67
|
legendSelectedRef,
|
|
70
68
|
propsSeries,
|
|
71
69
|
series,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-chart-option.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-chart-option.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;
|
|
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,WAAW,EACX,MAAM,EACN,QAAQ,EACR,cAAc,EACd,cAAc,EACd,UAAU,EACV,KAAK,EACL,KAAK,EACL,WAAW,GACU;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,WAAW;YACX,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,WAAW;QACX,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 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 hasMarkArea: boolean;\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 propsSeries,\n series,\n settings,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n hasMarkArea,\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 hasMarkArea,\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 hasMarkArea,\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,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HorizontalBarWithVerticalSlider = exports.verticalSliderCategories = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) "Neo4j"
|
|
8
|
+
* Neo4j Sweden AB [http://neo4j.com]
|
|
9
|
+
*
|
|
10
|
+
* This file is part of Neo4j.
|
|
11
|
+
*
|
|
12
|
+
* Neo4j is free software: you can redistribute it and/or modify
|
|
13
|
+
* it under the terms of the GNU General Public License as published by
|
|
14
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
15
|
+
* (at your option) any later version.
|
|
16
|
+
*
|
|
17
|
+
* This program is distributed in the hope that it will be useful,
|
|
18
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
* GNU General Public License for more details.
|
|
21
|
+
*
|
|
22
|
+
* You should have received a copy of the GNU General Public License
|
|
23
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
*/
|
|
25
|
+
const react_charts_1 = require("@neo4j-ndl/react-charts");
|
|
26
|
+
const echarts_1 = require("echarts");
|
|
27
|
+
const react_1 = require("react");
|
|
28
|
+
exports.verticalSliderCategories = [
|
|
29
|
+
'Friday',
|
|
30
|
+
'Saturday',
|
|
31
|
+
'Sunday',
|
|
32
|
+
'Monday',
|
|
33
|
+
'Tuesday',
|
|
34
|
+
'Wednesday',
|
|
35
|
+
'Thursday',
|
|
36
|
+
'Friday II',
|
|
37
|
+
];
|
|
38
|
+
const dataset = [
|
|
39
|
+
{
|
|
40
|
+
dimensions: ['day', 'First'],
|
|
41
|
+
source: exports.verticalSliderCategories.map((day, index) => [
|
|
42
|
+
day,
|
|
43
|
+
10 + index * 12,
|
|
44
|
+
]),
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const getChart = () => {
|
|
48
|
+
const element = document.querySelector('.ndl-chart-echart');
|
|
49
|
+
return element instanceof HTMLElement ? (0, echarts_1.getInstanceByDom)(element) : undefined;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Horizontal bar chart (value x-axis, category y-axis) with a slider bound to
|
|
53
|
+
* the category axis, which Needle lays out as a vertical slider on the right.
|
|
54
|
+
*/
|
|
55
|
+
const HorizontalBarWithVerticalSlider = () => {
|
|
56
|
+
(0, react_1.useEffect)(() => {
|
|
57
|
+
window.verticalSliderHarness = {
|
|
58
|
+
getResolvedLayout: () => {
|
|
59
|
+
var _a, _b, _c, _d, _e;
|
|
60
|
+
const option = (_a = getChart()) === null || _a === void 0 ? void 0 : _a.getOption();
|
|
61
|
+
return {
|
|
62
|
+
grid: (_c = (_b = option === null || option === void 0 ? void 0 : option.grid) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : {},
|
|
63
|
+
slider: (_e = (_d = option === null || option === void 0 ? void 0 : option.dataZoom) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : {},
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
zoomTo: (start, end) => {
|
|
67
|
+
var _a;
|
|
68
|
+
(_a = getChart()) === null || _a === void 0 ? void 0 : _a.dispatchAction({ end, start, type: 'dataZoom' });
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}, []);
|
|
72
|
+
return ((0, jsx_runtime_1.jsx)("div", { style: { height: '420px', width: '760px' }, children: (0, jsx_runtime_1.jsx)(react_charts_1.Chart, { dataset: dataset, series: [
|
|
73
|
+
// oxlint-disable-next-line
|
|
74
|
+
{ encode: { x: 'First', y: 'day' }, name: 'First', type: 'bar' },
|
|
75
|
+
], xAxis: { type: 'value' }, yAxis: { type: 'category' }, option: { dataZoom: [{ type: 'slider', yAxisIndex: [0] }] } }) }));
|
|
76
|
+
};
|
|
77
|
+
exports.HorizontalBarWithVerticalSlider = HorizontalBarWithVerticalSlider;
|
|
78
|
+
//# sourceMappingURL=HorizontalBarWithVerticalSlider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HorizontalBarWithVerticalSlider.js","sourceRoot":"","sources":["../../../../src/charts/tests/HorizontalBarWithVerticalSlider.tsx"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,0DAAgD;AAChD,qCAA2C;AAC3C,iCAAkC;AAErB,QAAA,wBAAwB,GAAG;IACtC,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,WAAW;IACX,UAAU;IACV,WAAW;CACZ,CAAC;AAEF,MAAM,OAAO,GAAG;IACd;QACE,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;QAC5B,MAAM,EAAE,gCAAwB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;YACnD,GAAG;YACH,EAAE,GAAG,KAAK,GAAG,EAAE;SAChB,CAAC;KACH;CACF,CAAC;AAgBF,MAAM,QAAQ,GAAG,GAAG,EAAE;IACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC5D,OAAO,OAAO,YAAY,WAAW,CAAC,CAAC,CAAC,IAAA,0BAAgB,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC,CAAC;AAEF;;;GAGG;AACI,MAAM,+BAA+B,GAAG,GAAG,EAAE;IAClD,IAAA,iBAAS,EAAC,GAAG,EAAE;QACZ,MAAwB,CAAC,qBAAqB,GAAG;YAChD,iBAAiB,EAAE,GAAG,EAAE;;gBACtB,MAAM,MAAM,GAAG,MAAA,QAAQ,EAAE,0CAAE,SAAS,EAKvB,CAAC;gBAEd,OAAO;oBACL,IAAI,EAAE,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,0CAAG,CAAC,CAAC,mCAAI,EAAE;oBAC7B,MAAM,EAAE,MAAA,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,QAAQ,0CAAG,CAAC,CAAC,mCAAI,EAAE;iBACpC,CAAC;YACJ,CAAC;YACD,MAAM,EAAE,CAAC,KAAa,EAAE,GAAW,EAAE,EAAE;;gBACrC,MAAA,QAAQ,EAAE,0CAAE,cAAc,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAC/D,CAAC;SACF,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,gCAAK,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAC7C,uBAAC,oBAAK,IACJ,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE;gBACN,2BAA2B;gBAC3B,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE;aACjE,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EACxB,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAC3B,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAC3D,GACE,CACP,CAAC;AACJ,CAAC,CAAC;AApCW,QAAA,+BAA+B,mCAoC1C","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 { Chart } from '@neo4j-ndl/react-charts';\nimport { getInstanceByDom } from 'echarts';\nimport { useEffect } from 'react';\n\nexport const verticalSliderCategories = [\n 'Friday',\n 'Saturday',\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday II',\n];\n\nconst dataset = [\n {\n dimensions: ['day', 'First'],\n source: verticalSliderCategories.map((day, index) => [\n day,\n 10 + index * 12,\n ]),\n },\n];\n\nexport type VerticalSliderHarnessApi = {\n /** Resolved layout of the first dataZoom component and the grid. */\n getResolvedLayout: () => {\n grid: { right?: number | string };\n slider: Record<string, unknown>;\n };\n /** Applies a zoom window through the slider's dataZoom action. */\n zoomTo: (start: number, end: number) => void;\n};\n\ntype HarnessWindow = Window & {\n verticalSliderHarness?: VerticalSliderHarnessApi;\n};\n\nconst getChart = () => {\n const element = document.querySelector('.ndl-chart-echart');\n return element instanceof HTMLElement ? getInstanceByDom(element) : undefined;\n};\n\n/**\n * Horizontal bar chart (value x-axis, category y-axis) with a slider bound to\n * the category axis, which Needle lays out as a vertical slider on the right.\n */\nexport const HorizontalBarWithVerticalSlider = () => {\n useEffect(() => {\n (window as HarnessWindow).verticalSliderHarness = {\n getResolvedLayout: () => {\n const option = getChart()?.getOption() as\n | {\n dataZoom?: Record<string, unknown>[];\n grid?: { right?: number | string }[];\n }\n | undefined;\n\n return {\n grid: option?.grid?.[0] ?? {},\n slider: option?.dataZoom?.[0] ?? {},\n };\n },\n zoomTo: (start: number, end: number) => {\n getChart()?.dispatchAction({ end, start, type: 'dataZoom' });\n },\n };\n }, []);\n\n return (\n <div style={{ height: '420px', width: '760px' }}>\n <Chart\n dataset={dataset}\n series={[\n // oxlint-disable-next-line\n { encode: { x: 'First', y: 'day' }, name: 'First', type: 'bar' },\n ]}\n xAxis={{ type: 'value' }}\n yAxis={{ type: 'category' }}\n option={{ dataZoom: [{ type: 'slider', yAxisIndex: [0] }] }}\n />\n </div>\n );\n};\n"]}
|
|
@@ -21,8 +21,10 @@
|
|
|
21
21
|
*/
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.hasMarkAreaInSeries = void 0;
|
|
24
|
-
exports.
|
|
24
|
+
exports.hasHorizontalSliderZoom = hasHorizontalSliderZoom;
|
|
25
|
+
exports.hasVerticalSliderZoom = hasVerticalSliderZoom;
|
|
25
26
|
exports.getSliderBottomOuterBound = getSliderBottomOuterBound;
|
|
27
|
+
exports.getSliderRightOuterBound = getSliderRightOuterBound;
|
|
26
28
|
exports.hasCategoryXAxis = hasCategoryXAxis;
|
|
27
29
|
exports.buildChartOption = buildChartOption;
|
|
28
30
|
const aria_description_1 = require("./aria-description");
|
|
@@ -30,15 +32,20 @@ const chart_tooltip_formatter_1 = require("./chart-tooltip-formatter");
|
|
|
30
32
|
const user_option_utils_1 = require("./user-option-utils");
|
|
31
33
|
const SLIDER_OUTER_BOUND_GAP = 8;
|
|
32
34
|
const SLIDER_OUTER_BOUND_FALLBACK = 60;
|
|
35
|
+
const toDataZoomArray = (dataZoom) => Array.isArray(dataZoom) ? dataZoom : [dataZoom];
|
|
33
36
|
/**
|
|
34
|
-
*
|
|
37
|
+
* Horizontal slider zoom needs extra bottom grid space for ECharts' slider
|
|
38
|
+
* control.
|
|
35
39
|
*/
|
|
36
|
-
function
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
function hasHorizontalSliderZoom(dataZoom) {
|
|
41
|
+
return toDataZoomArray(dataZoom).some((dataZoomOption) => (dataZoomOption === null || dataZoomOption === void 0 ? void 0 : dataZoomOption.type) === 'slider' && !(0, user_option_utils_1.isVerticalSlider)(dataZoomOption));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Vertical slider zoom needs extra right grid space for ECharts' slider
|
|
45
|
+
* control.
|
|
46
|
+
*/
|
|
47
|
+
function hasVerticalSliderZoom(dataZoom) {
|
|
48
|
+
return toDataZoomArray(dataZoom).some((dataZoomOption) => (0, user_option_utils_1.isVerticalSlider)(dataZoomOption));
|
|
42
49
|
}
|
|
43
50
|
const getPixelValue = (value) => {
|
|
44
51
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
@@ -58,10 +65,9 @@ const getPixelValue = (value) => {
|
|
|
58
65
|
* reserve because they cannot be resolved without the rendered chart size.
|
|
59
66
|
*/
|
|
60
67
|
function getSliderBottomOuterBound(dataZoom) {
|
|
61
|
-
const
|
|
62
|
-
const sliderOuterBounds = dataZoomOptions.flatMap((option) => {
|
|
68
|
+
const sliderOuterBounds = toDataZoomArray(dataZoom).flatMap((option) => {
|
|
63
69
|
const slider = option;
|
|
64
|
-
if ((slider === null || slider === void 0 ? void 0 : slider.type) !== 'slider' ||
|
|
70
|
+
if ((slider === null || slider === void 0 ? void 0 : slider.type) !== 'slider' || (0, user_option_utils_1.isVerticalSlider)(slider)) {
|
|
65
71
|
return [];
|
|
66
72
|
}
|
|
67
73
|
const bottom = getPixelValue(slider.bottom);
|
|
@@ -75,6 +81,30 @@ function getSliderBottomOuterBound(dataZoom) {
|
|
|
75
81
|
? Math.max(...sliderOuterBounds)
|
|
76
82
|
: undefined;
|
|
77
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Reserves the area occupied by right-positioned vertical slider controls,
|
|
86
|
+
* mirroring `getSliderBottomOuterBound` for horizontal ones. Normalized
|
|
87
|
+
* sliders use pixel values; custom percentage-based layouts fall back to the
|
|
88
|
+
* 60px reserve because they cannot be resolved without the rendered chart
|
|
89
|
+
* size.
|
|
90
|
+
*/
|
|
91
|
+
function getSliderRightOuterBound(dataZoom) {
|
|
92
|
+
const sliderOuterBounds = toDataZoomArray(dataZoom).flatMap((option) => {
|
|
93
|
+
const slider = option;
|
|
94
|
+
if (!(0, user_option_utils_1.isVerticalSlider)(slider)) {
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
const right = getPixelValue(slider === null || slider === void 0 ? void 0 : slider.right);
|
|
98
|
+
const width = getPixelValue(slider === null || slider === void 0 ? void 0 : slider.width);
|
|
99
|
+
if (right === undefined || width === undefined) {
|
|
100
|
+
return [SLIDER_OUTER_BOUND_FALLBACK];
|
|
101
|
+
}
|
|
102
|
+
return [right + width + SLIDER_OUTER_BOUND_GAP];
|
|
103
|
+
});
|
|
104
|
+
return sliderOuterBounds.length > 0
|
|
105
|
+
? Math.max(...sliderOuterBounds)
|
|
106
|
+
: undefined;
|
|
107
|
+
}
|
|
78
108
|
/**
|
|
79
109
|
* Mark area needs extra top grid space to fit inside the chart.
|
|
80
110
|
*/
|
|
@@ -94,11 +124,13 @@ function hasCategoryXAxis(xAxis) {
|
|
|
94
124
|
* Builds the ECharts option object from Needle chart props and derived values.
|
|
95
125
|
* Applying the option to an ECharts instance happens in `useChartOption`.
|
|
96
126
|
*/
|
|
97
|
-
function buildChartOption({ dataZoom, dataset, hasCategoryXAxis,
|
|
127
|
+
function buildChartOption({ dataZoom, dataset, hasCategoryXAxis, legendSelected, propsSeries, series, thresholdLines, toolboxOptions, userOption, xAxis, yAxis, hasMarkArea, }) {
|
|
98
128
|
const customAriaDescription = (0, aria_description_1.generateThresholdAriaDescription)(propsSeries, dataset);
|
|
99
129
|
const sliderBottomOuterBound = getSliderBottomOuterBound(dataZoom);
|
|
100
|
-
const
|
|
130
|
+
const sliderRightOuterBound = getSliderRightOuterBound(dataZoom);
|
|
131
|
+
const gridBottom = hasHorizontalSliderZoom(dataZoom) ? 60 : 10;
|
|
101
132
|
const gridHorizontalInset = hasCategoryXAxis ? 15 : 10;
|
|
133
|
+
const gridRight = hasVerticalSliderZoom(dataZoom) ? 60 : gridHorizontalInset;
|
|
102
134
|
const gridTop = hasMarkArea ? 20 : 10;
|
|
103
135
|
return Object.assign(Object.assign({}, userOption), { aria: Object.assign(Object.assign({ decal: {
|
|
104
136
|
show: false,
|
|
@@ -108,14 +140,14 @@ function buildChartOption({ dataZoom, dataset, hasCategoryXAxis, hasSliderZoom,
|
|
|
108
140
|
dataset, grid: Object.assign({ bottom: `${gridBottom}px`, left: `${gridHorizontalInset}px`, outerBounds: {
|
|
109
141
|
bottom: sliderBottomOuterBound !== null && sliderBottomOuterBound !== void 0 ? sliderBottomOuterBound : gridBottom,
|
|
110
142
|
left: gridHorizontalInset,
|
|
111
|
-
right:
|
|
143
|
+
right: sliderRightOuterBound !== null && sliderRightOuterBound !== void 0 ? sliderRightOuterBound : gridRight,
|
|
112
144
|
top: gridTop,
|
|
113
|
-
}, outerBoundsContain: 'all', right: `${
|
|
145
|
+
}, outerBoundsContain: 'all', right: `${gridRight}px`, top: `${gridTop}px`, type: 'solid' }, userOption === null || userOption === void 0 ? void 0 : userOption.grid), legend: {
|
|
114
146
|
// ECharts mutates option.legend.selected internally; callers pass a
|
|
115
147
|
// copied object so the React ref remains the source of truth.
|
|
116
148
|
selected: Object.assign({}, legendSelected),
|
|
117
149
|
show: false,
|
|
118
|
-
}, series, toolbox: (0, user_option_utils_1.mergeToolbox)(toolboxOptions), tooltip: {
|
|
150
|
+
}, series, toolbox: (0, user_option_utils_1.mergeToolbox)(toolboxOptions, { dataZoom, xAxis, yAxis }), tooltip: {
|
|
119
151
|
borderRadius: 0,
|
|
120
152
|
borderWidth: 0,
|
|
121
153
|
confine: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-chart-option.js","sourceRoot":"","sources":["../../../../src/charts/utils/build-chart-option.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 { DataZoomComponentOption, EChartsOption } from 'echarts';\n\nimport { generateThresholdAriaDescription } from './aria-description';\nimport { createAxisTooltipFormatter } from './chart-tooltip-formatter';\nimport type { ChartProps, EchartsSeries } from './chart-types';\nimport type { NormalizedThresholdLine } from './threshold';\nimport { mergeToolbox } from './user-option-utils';\n\nconst SLIDER_OUTER_BOUND_GAP = 8;\nconst SLIDER_OUTER_BOUND_FALLBACK = 60;\n\ntype BuildChartOptionParams = {\n dataZoom: EChartsOption['dataZoom'];\n dataset: ChartProps['dataset'];\n hasCategoryXAxis: boolean;\n hasSliderZoom: boolean;\n legendSelected: Record<string, boolean>;\n propsSeries: ChartProps['series'];\n series: EchartsSeries;\n thresholdLines: NormalizedThresholdLine[];\n toolboxOptions: EChartsOption['toolbox'];\n userOption: ChartProps['option'];\n xAxis: EChartsOption['xAxis'];\n yAxis: EChartsOption['yAxis'];\n hasMarkArea: boolean;\n};\n\n/**\n * Slider zoom needs extra bottom grid space for ECharts' slider control.\n */\nexport function hasSliderDataZoom(\n dataZoom: EChartsOption['dataZoom'],\n): boolean {\n return Array.isArray(dataZoom)\n ? dataZoom.some((dataZoomOption: DataZoomComponentOption) => {\n return dataZoomOption?.type === 'slider';\n })\n : dataZoom?.type === 'slider';\n}\n\ntype SliderDataZoomLayout = DataZoomComponentOption & {\n bottom?: number | string;\n height?: number | string;\n orient?: 'horizontal' | 'vertical';\n};\n\nconst getPixelValue = (value: number | string | undefined) => {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string' || !/^-?\\d+(?:\\.\\d+)?px$/.test(value)) {\n return undefined;\n }\n\n return Number.parseFloat(value);\n};\n\n/**\n * Reserves the area occupied by bottom-positioned horizontal slider controls.\n *\n * ECharts lays data zoom controls outside the Cartesian grid, so its automatic\n * axis outer bounds do not account for them. Normalized sliders use pixel\n * values; custom percentage-based layouts fall back to the previous 60px\n * reserve because they cannot be resolved without the rendered chart size.\n */\nexport function getSliderBottomOuterBound(\n dataZoom: EChartsOption['dataZoom'],\n): number | undefined {\n const dataZoomOptions = Array.isArray(dataZoom) ? dataZoom : [dataZoom];\n const sliderOuterBounds = dataZoomOptions.flatMap((option) => {\n const slider = option as SliderDataZoomLayout | undefined;\n if (slider?.type !== 'slider' || slider.orient === 'vertical') {\n return [];\n }\n\n const bottom = getPixelValue(slider.bottom);\n const height = getPixelValue(slider.height);\n if (bottom === undefined || height === undefined) {\n return [SLIDER_OUTER_BOUND_FALLBACK];\n }\n\n return [bottom + height + SLIDER_OUTER_BOUND_GAP];\n });\n\n return sliderOuterBounds.length > 0\n ? Math.max(...sliderOuterBounds)\n : undefined;\n}\n\n/**\n * Mark area needs extra top grid space to fit inside the chart.\n */\nexport const hasMarkAreaInSeries = (series: EchartsSeries) =>\n Array.isArray(series)\n ? series.some((option) => !!option.markArea)\n : !!series.markArea;\n\n/**\n * Category x-axes use slightly wider grid padding to avoid clipped labels.\n */\nexport function hasCategoryXAxis(xAxis: EChartsOption['xAxis']): boolean {\n return Array.isArray(xAxis)\n ? xAxis.some((axis) => axis.type === 'category')\n : xAxis?.type === 'category';\n}\n\n/**\n * Builds the ECharts option object from Needle chart props and derived values.\n * Applying the option to an ECharts instance happens in `useChartOption`.\n */\nexport function buildChartOption({\n dataZoom,\n dataset,\n hasCategoryXAxis,\n hasSliderZoom,\n legendSelected,\n propsSeries,\n series,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n hasMarkArea,\n}: BuildChartOptionParams): EChartsOption {\n const customAriaDescription = generateThresholdAriaDescription(\n propsSeries,\n dataset,\n );\n const sliderBottomOuterBound = getSliderBottomOuterBound(dataZoom);\n const gridBottom = hasSliderZoom ? 60 : 10;\n const gridHorizontalInset = hasCategoryXAxis ? 15 : 10;\n const gridTop = hasMarkArea ? 20 : 10;\n\n return {\n ...userOption,\n aria: {\n decal: {\n show: false,\n },\n enabled: true,\n ...(customAriaDescription !== undefined && {\n label: { description: customAriaDescription },\n }),\n ...(userOption?.aria as EChartsOption['aria']),\n },\n dataZoom,\n dataset,\n grid: {\n bottom: `${gridBottom}px`,\n left: `${gridHorizontalInset}px`,\n outerBounds: {\n bottom: sliderBottomOuterBound ?? gridBottom,\n left: gridHorizontalInset,\n right: gridHorizontalInset,\n top: gridTop,\n },\n outerBoundsContain: 'all',\n right: `${gridHorizontalInset}px`,\n top: `${gridTop}px`,\n type: 'solid',\n ...(userOption?.grid as EChartsOption['grid']),\n },\n legend: {\n // ECharts mutates option.legend.selected internally; callers pass a\n // copied object so the React ref remains the source of truth.\n selected: { ...legendSelected },\n show: false,\n },\n series,\n toolbox: mergeToolbox(toolboxOptions),\n tooltip: {\n borderRadius: 0,\n borderWidth: 0,\n confine: true,\n extraCssText: 'box-shadow: none; background-color: transparent;',\n formatter: createAxisTooltipFormatter({ thresholdLines, userOption }),\n padding: 0,\n trigger: 'axis',\n },\n xAxis,\n yAxis,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"build-chart-option.js","sourceRoot":"","sources":["../../../../src/charts/utils/build-chart-option.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 { DataZoomComponentOption, EChartsOption } from 'echarts';\n\nimport { generateThresholdAriaDescription } from './aria-description';\nimport { createAxisTooltipFormatter } from './chart-tooltip-formatter';\nimport type { ChartProps, EchartsSeries } from './chart-types';\nimport type { NormalizedThresholdLine } from './threshold';\nimport { isVerticalSlider, mergeToolbox } from './user-option-utils';\n\nconst SLIDER_OUTER_BOUND_GAP = 8;\nconst SLIDER_OUTER_BOUND_FALLBACK = 60;\n\ntype BuildChartOptionParams = {\n dataZoom: EChartsOption['dataZoom'];\n dataset: ChartProps['dataset'];\n hasCategoryXAxis: boolean;\n legendSelected: Record<string, boolean>;\n propsSeries: ChartProps['series'];\n series: EchartsSeries;\n thresholdLines: NormalizedThresholdLine[];\n toolboxOptions: EChartsOption['toolbox'];\n userOption: ChartProps['option'];\n xAxis: EChartsOption['xAxis'];\n yAxis: EChartsOption['yAxis'];\n hasMarkArea: boolean;\n};\n\nconst toDataZoomArray = (dataZoom: EChartsOption['dataZoom']) =>\n Array.isArray(dataZoom) ? dataZoom : [dataZoom];\n\n/**\n * Horizontal slider zoom needs extra bottom grid space for ECharts' slider\n * control.\n */\nexport function hasHorizontalSliderZoom(\n dataZoom: EChartsOption['dataZoom'],\n): boolean {\n return toDataZoomArray(dataZoom).some(\n (dataZoomOption: DataZoomComponentOption | undefined) =>\n dataZoomOption?.type === 'slider' && !isVerticalSlider(dataZoomOption),\n );\n}\n\n/**\n * Vertical slider zoom needs extra right grid space for ECharts' slider\n * control.\n */\nexport function hasVerticalSliderZoom(\n dataZoom: EChartsOption['dataZoom'],\n): boolean {\n return toDataZoomArray(dataZoom).some(\n (dataZoomOption: DataZoomComponentOption | undefined) =>\n isVerticalSlider(dataZoomOption),\n );\n}\n\ntype SliderDataZoomLayout = DataZoomComponentOption & {\n bottom?: number | string;\n height?: number | string;\n orient?: 'horizontal' | 'vertical';\n right?: number | string;\n width?: number | string;\n};\n\nconst getPixelValue = (value: number | string | undefined) => {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n\n if (typeof value !== 'string' || !/^-?\\d+(?:\\.\\d+)?px$/.test(value)) {\n return undefined;\n }\n\n return Number.parseFloat(value);\n};\n\n/**\n * Reserves the area occupied by bottom-positioned horizontal slider controls.\n *\n * ECharts lays data zoom controls outside the Cartesian grid, so its automatic\n * axis outer bounds do not account for them. Normalized sliders use pixel\n * values; custom percentage-based layouts fall back to the previous 60px\n * reserve because they cannot be resolved without the rendered chart size.\n */\nexport function getSliderBottomOuterBound(\n dataZoom: EChartsOption['dataZoom'],\n): number | undefined {\n const sliderOuterBounds = toDataZoomArray(dataZoom).flatMap((option) => {\n const slider = option as SliderDataZoomLayout | undefined;\n if (slider?.type !== 'slider' || isVerticalSlider(slider)) {\n return [];\n }\n\n const bottom = getPixelValue(slider.bottom);\n const height = getPixelValue(slider.height);\n if (bottom === undefined || height === undefined) {\n return [SLIDER_OUTER_BOUND_FALLBACK];\n }\n\n return [bottom + height + SLIDER_OUTER_BOUND_GAP];\n });\n\n return sliderOuterBounds.length > 0\n ? Math.max(...sliderOuterBounds)\n : undefined;\n}\n\n/**\n * Reserves the area occupied by right-positioned vertical slider controls,\n * mirroring `getSliderBottomOuterBound` for horizontal ones. Normalized\n * sliders use pixel values; custom percentage-based layouts fall back to the\n * 60px reserve because they cannot be resolved without the rendered chart\n * size.\n */\nexport function getSliderRightOuterBound(\n dataZoom: EChartsOption['dataZoom'],\n): number | undefined {\n const sliderOuterBounds = toDataZoomArray(dataZoom).flatMap((option) => {\n const slider = option as SliderDataZoomLayout | undefined;\n if (!isVerticalSlider(slider)) {\n return [];\n }\n\n const right = getPixelValue(slider?.right);\n const width = getPixelValue(slider?.width);\n if (right === undefined || width === undefined) {\n return [SLIDER_OUTER_BOUND_FALLBACK];\n }\n\n return [right + width + SLIDER_OUTER_BOUND_GAP];\n });\n\n return sliderOuterBounds.length > 0\n ? Math.max(...sliderOuterBounds)\n : undefined;\n}\n\n/**\n * Mark area needs extra top grid space to fit inside the chart.\n */\nexport const hasMarkAreaInSeries = (series: EchartsSeries) =>\n Array.isArray(series)\n ? series.some((option) => !!option.markArea)\n : !!series.markArea;\n\n/**\n * Category x-axes use slightly wider grid padding to avoid clipped labels.\n */\nexport function hasCategoryXAxis(xAxis: EChartsOption['xAxis']): boolean {\n return Array.isArray(xAxis)\n ? xAxis.some((axis) => axis.type === 'category')\n : xAxis?.type === 'category';\n}\n\n/**\n * Builds the ECharts option object from Needle chart props and derived values.\n * Applying the option to an ECharts instance happens in `useChartOption`.\n */\nexport function buildChartOption({\n dataZoom,\n dataset,\n hasCategoryXAxis,\n legendSelected,\n propsSeries,\n series,\n thresholdLines,\n toolboxOptions,\n userOption,\n xAxis,\n yAxis,\n hasMarkArea,\n}: BuildChartOptionParams): EChartsOption {\n const customAriaDescription = generateThresholdAriaDescription(\n propsSeries,\n dataset,\n );\n const sliderBottomOuterBound = getSliderBottomOuterBound(dataZoom);\n const sliderRightOuterBound = getSliderRightOuterBound(dataZoom);\n const gridBottom = hasHorizontalSliderZoom(dataZoom) ? 60 : 10;\n const gridHorizontalInset = hasCategoryXAxis ? 15 : 10;\n const gridRight = hasVerticalSliderZoom(dataZoom) ? 60 : gridHorizontalInset;\n const gridTop = hasMarkArea ? 20 : 10;\n\n return {\n ...userOption,\n aria: {\n decal: {\n show: false,\n },\n enabled: true,\n ...(customAriaDescription !== undefined && {\n label: { description: customAriaDescription },\n }),\n ...(userOption?.aria as EChartsOption['aria']),\n },\n dataZoom,\n dataset,\n grid: {\n bottom: `${gridBottom}px`,\n left: `${gridHorizontalInset}px`,\n outerBounds: {\n bottom: sliderBottomOuterBound ?? gridBottom,\n left: gridHorizontalInset,\n right: sliderRightOuterBound ?? gridRight,\n top: gridTop,\n },\n outerBoundsContain: 'all',\n right: `${gridRight}px`,\n top: `${gridTop}px`,\n type: 'solid',\n ...(userOption?.grid as EChartsOption['grid']),\n },\n legend: {\n // ECharts mutates option.legend.selected internally; callers pass a\n // copied object so the React ref remains the source of truth.\n selected: { ...legendSelected },\n show: false,\n },\n series,\n toolbox: mergeToolbox(toolboxOptions, { dataZoom, xAxis, yAxis }),\n tooltip: {\n borderRadius: 0,\n borderWidth: 0,\n confine: true,\n extraCssText: 'box-shadow: none; background-color: transparent;',\n formatter: createAxisTooltipFormatter({ thresholdLines, userOption }),\n padding: 0,\n trigger: 'axis',\n },\n xAxis,\n yAxis,\n };\n}\n"]}
|