@neo4j-ndl/react-charts 1.3.18 → 1.4.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/ChartTooltip.js +6 -2
- package/lib/cjs/charts/ChartTooltip.js.map +1 -1
- package/lib/cjs/charts/hooks/use-chart-option.js +6 -0
- package/lib/cjs/charts/hooks/use-chart-option.js.map +1 -1
- package/lib/cjs/charts/hooks/use-legend-series.js +7 -1
- package/lib/cjs/charts/hooks/use-legend-series.js.map +1 -1
- package/lib/cjs/charts/index.js.map +1 -1
- package/lib/cjs/charts/tests/chart-test-utils.js +121 -1
- package/lib/cjs/charts/tests/chart-test-utils.js.map +1 -1
- package/lib/cjs/charts/utils/build-chart-option.js +39 -4
- package/lib/cjs/charts/utils/build-chart-option.js.map +1 -1
- package/lib/cjs/charts/utils/chart-tooltip-formatter.js +93 -0
- package/lib/cjs/charts/utils/chart-tooltip-formatter.js.map +1 -1
- package/lib/cjs/charts/utils/defaults.js +18 -1
- package/lib/cjs/charts/utils/defaults.js.map +1 -1
- package/lib/cjs/charts/utils/legend-utils.js +7 -2
- package/lib/cjs/charts/utils/legend-utils.js.map +1 -1
- package/lib/cjs/charts/utils/scatter-tooltip-points.js +301 -0
- package/lib/cjs/charts/utils/scatter-tooltip-points.js.map +1 -0
- package/lib/cjs/charts/utils/user-option-utils.js +16 -6
- package/lib/cjs/charts/utils/user-option-utils.js.map +1 -1
- package/lib/esm/charts/ChartTooltip.js +6 -2
- package/lib/esm/charts/ChartTooltip.js.map +1 -1
- package/lib/esm/charts/hooks/use-chart-option.js +6 -0
- package/lib/esm/charts/hooks/use-chart-option.js.map +1 -1
- package/lib/esm/charts/hooks/use-legend-series.js +7 -1
- package/lib/esm/charts/hooks/use-legend-series.js.map +1 -1
- package/lib/esm/charts/index.js.map +1 -1
- package/lib/esm/charts/tests/chart-test-utils.js +115 -0
- package/lib/esm/charts/tests/chart-test-utils.js.map +1 -1
- package/lib/esm/charts/utils/build-chart-option.js +40 -5
- package/lib/esm/charts/utils/build-chart-option.js.map +1 -1
- package/lib/esm/charts/utils/chart-tooltip-formatter.js +92 -0
- package/lib/esm/charts/utils/chart-tooltip-formatter.js.map +1 -1
- package/lib/esm/charts/utils/defaults.js +16 -1
- package/lib/esm/charts/utils/defaults.js.map +1 -1
- package/lib/esm/charts/utils/legend-utils.js +7 -2
- package/lib/esm/charts/utils/legend-utils.js.map +1 -1
- package/lib/esm/charts/utils/scatter-tooltip-points.js +291 -0
- package/lib/esm/charts/utils/scatter-tooltip-points.js.map +1 -0
- package/lib/esm/charts/utils/user-option-utils.js +17 -7
- package/lib/esm/charts/utils/user-option-utils.js.map +1 -1
- package/lib/types/charts/ChartTooltip.d.ts +6 -1
- package/lib/types/charts/ChartTooltip.d.ts.map +1 -1
- package/lib/types/charts/hooks/use-chart-option.d.ts.map +1 -1
- package/lib/types/charts/hooks/use-legend-series.d.ts.map +1 -1
- package/lib/types/charts/index.d.ts +1 -0
- package/lib/types/charts/index.d.ts.map +1 -1
- package/lib/types/charts/tests/chart-test-utils.d.ts +78 -0
- package/lib/types/charts/tests/chart-test-utils.d.ts.map +1 -1
- package/lib/types/charts/utils/build-chart-option.d.ts +4 -1
- package/lib/types/charts/utils/build-chart-option.d.ts.map +1 -1
- package/lib/types/charts/utils/chart-tooltip-formatter.d.ts +45 -2
- package/lib/types/charts/utils/chart-tooltip-formatter.d.ts.map +1 -1
- package/lib/types/charts/utils/defaults.d.ts +10 -1
- package/lib/types/charts/utils/defaults.d.ts.map +1 -1
- package/lib/types/charts/utils/legend-utils.d.ts.map +1 -1
- package/lib/types/charts/utils/scatter-tooltip-points.d.ts +84 -0
- package/lib/types/charts/utils/scatter-tooltip-points.d.ts.map +1 -0
- 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 +3 -3
- package/skills/ndl-react-charts/components/charts.md +279 -0
|
@@ -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 { 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"]}
|
|
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 {\n createAxisTooltipFormatter,\n createScatterTooltipFormatter,\n type SeriesAxisNames,\n} from './chart-tooltip-formatter';\nimport type { ChartProps, EchartsSeries } from './chart-types';\nimport { tooltipExtraCssText } from './defaults';\nimport type { ScatterTooltipChart } from './scatter-tooltip-points';\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 getChartInstance?: () => ScatterTooltipChart | undefined;\n getLegendSelected?: () => Record<string, boolean> | undefined;\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 * Reads the `name` of the axis at `axisIndex`, which scatter tooltips use to\n * label their x and y rows.\n */\nfunction getAxisName(\n axis: EChartsOption['xAxis'] | EChartsOption['yAxis'],\n axisIndex = 0,\n): string | undefined {\n const axisOption = (\n Array.isArray(axis) ? axis[axisIndex] : axisIndex === 0 ? axis : undefined\n ) as { name?: unknown } | undefined;\n\n return typeof axisOption?.name === 'string' && axisOption.name.length > 0\n ? axisOption.name\n : undefined;\n}\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 getChartInstance,\n getLegendSelected,\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 const seriesList = Array.isArray(series) ? series : [series];\n const isScatterChart =\n seriesList.length > 0 &&\n seriesList.every((seriesOption) => seriesOption.type === 'scatter');\n const seriesAxisNames: SeriesAxisNames[] = seriesList.map((seriesOption) => {\n const { xAxisIndex, yAxisIndex } = seriesOption as {\n xAxisIndex?: number;\n yAxisIndex?: number;\n };\n\n return {\n // oxlint-disable-next-line id-length\n x: getAxisName(xAxis, xAxisIndex),\n // oxlint-disable-next-line id-length\n y: getAxisName(yAxis, yAxisIndex),\n };\n });\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: tooltipExtraCssText,\n formatter: isScatterChart\n ? createScatterTooltipFormatter({\n dataset,\n getChartInstance,\n getLegendSelected,\n series,\n seriesAxisNames,\n userOption,\n })\n : createAxisTooltipFormatter({ thresholdLines, userOption }),\n padding: 0,\n // Scatter needs item trigger so the unique per-point `encode.tooltip`\n // value can title the tooltip. Axis trigger would group every point\n // that shares an x (or y) value.\n trigger: isScatterChart ? 'item' : 'axis',\n },\n xAxis,\n yAxis,\n };\n}\n"]}
|
|
@@ -23,6 +23,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
23
23
|
import { renderToString } from 'react-dom/server';
|
|
24
24
|
import { ChartTooltip } from '../ChartTooltip';
|
|
25
25
|
import { capitalizeFirstLetter, extractValueFromTooltipSeries, formatNumberEnUS, } from './format-utils';
|
|
26
|
+
import { encodedDimensionLabel, extraTooltipRefs, findNearbyScatterPoints, getEncodedAxisRefs, getScatterSymbolSize, readEncodedValue, } from './scatter-tooltip-points';
|
|
26
27
|
import { evaluateThresholdCondition } from './threshold';
|
|
27
28
|
import { getThresholdLineDisplayName, isThresholdLine, } from './threshold';
|
|
28
29
|
export function getTooltipValueFormatter(userOption) {
|
|
@@ -33,6 +34,11 @@ export function getTooltipValueFormatter(userOption) {
|
|
|
33
34
|
}
|
|
34
35
|
return formatNumberEnUS;
|
|
35
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Upper bound on the points one tooltip lists, so a dense cluster cannot grow
|
|
39
|
+
* a tooltip that covers the chart.
|
|
40
|
+
*/
|
|
41
|
+
const MAX_TOOLTIP_POINTS = 5;
|
|
36
42
|
/**
|
|
37
43
|
* Builds the ECharts axis-tooltip formatter used by line-like charts.
|
|
38
44
|
* It renders Needle tooltip markup and augments non-threshold series with
|
|
@@ -79,4 +85,90 @@ export function createAxisTooltipFormatter({ thresholdLines, userOption, }) {
|
|
|
79
85
|
})] }))}`;
|
|
80
86
|
};
|
|
81
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Builds the ECharts item-tooltip formatter used by scatter charts.
|
|
90
|
+
*
|
|
91
|
+
* The title comes from ECharts `encode.tooltip`, then `encode.itemName`, then
|
|
92
|
+
* an extra data dimension, and otherwise the series name. x and y are listed
|
|
93
|
+
* underneath. See https://echarts.apache.org/en/option.html#series-scatter.encode
|
|
94
|
+
*
|
|
95
|
+
* `tooltip.valueFormatter` runs on the x and y values only. Those calls pass
|
|
96
|
+
* `{ axis: 'x' | 'y' }` (`TooltipValueContext`) as the third argument. The
|
|
97
|
+
* title is shown unchanged.
|
|
98
|
+
*
|
|
99
|
+
* Points whose symbols overlap the hovered one are listed in the same tooltip,
|
|
100
|
+
* closest first, so a cluster is readable without zooming in. Each point gets
|
|
101
|
+
* its own block: the series color sits once on the block title, and the rows
|
|
102
|
+
* are labelled with the axis `name` when the consumer set one, falling back to
|
|
103
|
+
* the dataset dimension name.
|
|
104
|
+
*/
|
|
105
|
+
export function createScatterTooltipFormatter({ dataset, getChartInstance, getLegendSelected, series, seriesAxisNames, userOption, }) {
|
|
106
|
+
const valueFormatter = getTooltipValueFormatter(userOption);
|
|
107
|
+
const radius = getScatterSymbolSize(series);
|
|
108
|
+
const seriesList = Array.isArray(series) ? series : [series];
|
|
109
|
+
const renderPoint = (point, key) => {
|
|
110
|
+
var _a, _b, _c, _d;
|
|
111
|
+
// ECharts only copies x/y into the hovered point's `encode`. The dimension
|
|
112
|
+
// the consumer set on `encode.tooltip` (or `itemName`) still lives on the
|
|
113
|
+
// series option, which is what the nearby points are already read from.
|
|
114
|
+
const seriesOption = seriesList[(_a = point.seriesIndex) !== null && _a !== void 0 ? _a : 0];
|
|
115
|
+
// The hovered point's own color is its theme-colored interior. The swatch
|
|
116
|
+
// uses the series color, which is the ring.
|
|
117
|
+
const swatchColor = typeof (seriesOption === null || seriesOption === void 0 ? void 0 : seriesOption.color) === 'string'
|
|
118
|
+
? seriesOption.color
|
|
119
|
+
: point.color;
|
|
120
|
+
const seriesEncode = seriesOption === null || seriesOption === void 0 ? void 0 : seriesOption.encode;
|
|
121
|
+
const titleRef = extraTooltipRefs(Object.assign(Object.assign({}, point), { encode: Object.assign(Object.assign(Object.assign({}, point.encode), ((seriesEncode === null || seriesEncode === void 0 ? void 0 : seriesEncode.tooltip) !== undefined && {
|
|
122
|
+
tooltip: seriesEncode.tooltip,
|
|
123
|
+
})), ((seriesEncode === null || seriesEncode === void 0 ? void 0 : seriesEncode.itemName) !== undefined && {
|
|
124
|
+
itemName: seriesEncode.itemName,
|
|
125
|
+
})) }))[0];
|
|
126
|
+
// ECharts reports `name` as '' when a point has no name dimension, which
|
|
127
|
+
// would hide the title and the color swatch. The series name fills that in.
|
|
128
|
+
const pointName = point.name !== undefined && point.name !== ''
|
|
129
|
+
? point.name
|
|
130
|
+
: point.seriesName;
|
|
131
|
+
const titleValue = titleRef !== undefined
|
|
132
|
+
? readEncodedValue(point.value, titleRef, point.dimensionNames)
|
|
133
|
+
: pointName;
|
|
134
|
+
// The title identifies the point, so it is not run through
|
|
135
|
+
// `valueFormatter`. Only string and number titles are renderable children.
|
|
136
|
+
const titleText = typeof titleValue === 'string' || typeof titleValue === 'number'
|
|
137
|
+
? titleValue
|
|
138
|
+
: undefined;
|
|
139
|
+
const refs = getEncodedAxisRefs(point.encode);
|
|
140
|
+
const xValue = readEncodedValue(point.value, refs.x, point.dimensionNames);
|
|
141
|
+
const yValue = readEncodedValue(point.value, refs.y, point.dimensionNames);
|
|
142
|
+
const axisNames = seriesAxisNames === null || seriesAxisNames === void 0 ? void 0 : seriesAxisNames[(_b = point.seriesIndex) !== null && _b !== void 0 ? _b : 0];
|
|
143
|
+
return (_jsxs("div", { className: "ndl-charts-chart-tooltip-point", children: [titleText !== undefined && titleText !== '' && (_jsx(ChartTooltip.Title, { indentSquareColor: swatchColor, children: titleText })), xValue !== undefined && (_jsx(ChartTooltip.Content, { leadingElement: (_c = axisNames === null || axisNames === void 0 ? void 0 : axisNames.x) !== null && _c !== void 0 ? _c : encodedDimensionLabel(refs.x, point.dimensionNames, 'x'), trailingElement: valueFormatter(xValue, point.dataIndex, {
|
|
144
|
+
axis: 'x',
|
|
145
|
+
}) })), yValue !== undefined && (_jsx(ChartTooltip.Content, { leadingElement: (_d = axisNames === null || axisNames === void 0 ? void 0 : axisNames.y) !== null && _d !== void 0 ? _d : encodedDimensionLabel(refs.y, point.dimensionNames, 'y'), trailingElement: valueFormatter(yValue, point.dataIndex, {
|
|
146
|
+
axis: 'y',
|
|
147
|
+
}) }))] }, key));
|
|
148
|
+
};
|
|
149
|
+
return function scatterTooltipFormatter(params) {
|
|
150
|
+
const hovered = (Array.isArray(params) ? params[0] : params);
|
|
151
|
+
let points = [hovered];
|
|
152
|
+
// A tooltip that throws leaves the chart without any tooltip at all, so a
|
|
153
|
+
// failed neighbor lookup falls back to the hovered point.
|
|
154
|
+
try {
|
|
155
|
+
points = findNearbyScatterPoints({
|
|
156
|
+
chart: getChartInstance === null || getChartInstance === void 0 ? void 0 : getChartInstance(),
|
|
157
|
+
dataset,
|
|
158
|
+
hovered,
|
|
159
|
+
legendSelected: getLegendSelected === null || getLegendSelected === void 0 ? void 0 : getLegendSelected(),
|
|
160
|
+
maxPoints: MAX_TOOLTIP_POINTS,
|
|
161
|
+
radius,
|
|
162
|
+
series,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
catch (_a) {
|
|
166
|
+
points = [hovered];
|
|
167
|
+
}
|
|
168
|
+
return `${renderToString(_jsx("span", { className: "ndl-charts-chart-tooltip", children: points.map((point, index) => {
|
|
169
|
+
var _a;
|
|
170
|
+
return renderPoint(point, `${point.seriesIndex}-${(_a = point.dataIndex) !== null && _a !== void 0 ? _a : index}`);
|
|
171
|
+
}) }))}`;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
82
174
|
//# sourceMappingURL=chart-tooltip-formatter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-tooltip-formatter.js","sourceRoot":"","sources":["../../../../src/charts/utils/chart-tooltip-formatter.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 type React from 'react';\nimport { renderToString } from 'react-dom/server';\n\nimport { ChartTooltip } from '../ChartTooltip';\nimport type { ChartProps } from './chart-types';\nimport {\n capitalizeFirstLetter,\n extractValueFromTooltipSeries,\n formatNumberEnUS,\n} from './format-utils';\nimport { evaluateThresholdCondition } from './threshold';\nimport {\n getThresholdLineDisplayName,\n isThresholdLine,\n type NormalizedThresholdLine,\n} from './threshold';\n\ntype TooltipValueFormatter = (value: unknown) => React.ReactNode;\n\nexport function getTooltipValueFormatter(\n userOption: ChartProps['option'],\n): TooltipValueFormatter {\n if (\n typeof userOption?.tooltip === 'object' &&\n userOption.tooltip !== null &&\n 'valueFormatter' in userOption.tooltip\n ) {\n return userOption.tooltip.valueFormatter as TooltipValueFormatter;\n }\n\n return formatNumberEnUS as TooltipValueFormatter;\n}\n\ntype CreateAxisTooltipFormatterParams = {\n thresholdLines: NormalizedThresholdLine[];\n userOption: ChartProps['option'];\n};\n\n/**\n * Builds the ECharts axis-tooltip formatter used by line-like charts.\n * It renders Needle tooltip markup and augments non-threshold series with\n * threshold notifications when their current value crosses a threshold line.\n */\nexport function createAxisTooltipFormatter({\n thresholdLines,\n userOption,\n}: CreateAxisTooltipFormatterParams) {\n const valueFormatter = getTooltipValueFormatter(userOption);\n\n return function axisTooltipFormatter(params: unknown) {\n const paramsArray = Array.isArray(params) ? params : [params];\n const firstParam = paramsArray[0];\n\n return `${renderToString(\n <span className=\"ndl-charts-chart-tooltip\">\n <ChartTooltip.Title>\n {firstParam?.axisValueLabel ?? ''}\n </ChartTooltip.Title>\n {paramsArray.map((series) => {\n const value = extractValueFromTooltipSeries(\n series.value,\n series.encode,\n series.axisDim,\n );\n\n const seriesValue = typeof value === 'number' ? value : Number(value);\n\n const isSeriesThresholdLine = isThresholdLine(series.seriesName);\n\n const notifications = thresholdLines.flatMap((threshold) => {\n if (isSeriesThresholdLine || Number.isNaN(seriesValue)) {\n return [];\n }\n\n const {\n notificationType,\n value: thresholdValue,\n condition,\n customConditionText,\n customCondition,\n } = threshold;\n const conditionEvaluation = customCondition\n ? {\n conditionText: customConditionText,\n isConditionMet: customCondition(seriesValue, thresholdValue),\n }\n : evaluateThresholdCondition(\n seriesValue,\n condition,\n thresholdValue,\n );\n\n if (!conditionEvaluation.isConditionMet) {\n return [];\n }\n\n return [\n {\n id: `threshold-${notificationType}`,\n leadingElement: customCondition\n ? conditionEvaluation.conditionText\n : `${conditionEvaluation.conditionText} threshold`,\n notificationType,\n trailingElement: valueFormatter(thresholdValue),\n },\n ];\n });\n\n return (\n <ChartTooltip.Content\n key={series.seriesName}\n leadingElement={\n isSeriesThresholdLine\n ? `${capitalizeFirstLetter(\n getThresholdLineDisplayName(series.seriesName),\n )} threshold`\n : series.seriesName\n }\n trailingElement={valueFormatter(value)}\n indentSquareColor={series.color}\n notifications={notifications}\n />\n );\n })}\n </span>,\n )}`;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"chart-tooltip-formatter.js","sourceRoot":"","sources":["../../../../src/charts/utils/chart-tooltip-formatter.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 type React from 'react';\nimport { renderToString } from 'react-dom/server';\n\nimport { ChartTooltip } from '../ChartTooltip';\nimport type { ChartProps, EchartsSeries } from './chart-types';\nimport {\n capitalizeFirstLetter,\n extractValueFromTooltipSeries,\n formatNumberEnUS,\n} from './format-utils';\nimport {\n encodedDimensionLabel,\n extraTooltipRefs,\n findNearbyScatterPoints,\n getEncodedAxisRefs,\n getScatterSymbolSize,\n readEncodedValue,\n type ScatterTooltipChart,\n type ScatterTooltipPoint,\n} from './scatter-tooltip-points';\nimport { evaluateThresholdCondition } from './threshold';\nimport {\n getThresholdLineDisplayName,\n isThresholdLine,\n type NormalizedThresholdLine,\n} from './threshold';\n\n/**\n * Where a scatter tooltip value comes from. Passed to `tooltip.valueFormatter`\n * as its third argument for the x and y rows, so one formatter can give them\n * different units. The title is not passed to the formatter.\n */\nexport type TooltipValueContext = {\n axis: 'x' | 'y';\n};\n\ntype TooltipValueFormatter = (\n value: unknown,\n dataIndex?: number,\n context?: TooltipValueContext,\n) => React.ReactNode;\n\nexport function getTooltipValueFormatter(\n userOption: ChartProps['option'],\n): TooltipValueFormatter {\n if (\n typeof userOption?.tooltip === 'object' &&\n userOption.tooltip !== null &&\n 'valueFormatter' in userOption.tooltip\n ) {\n return userOption.tooltip.valueFormatter as TooltipValueFormatter;\n }\n\n return formatNumberEnUS as TooltipValueFormatter;\n}\n\n/**\n * `name` of the x and y axes one series is bound to. `seriesAxisNames` holds\n * one entry per series, indexed by series index.\n */\nexport type SeriesAxisNames = {\n // oxlint-disable-next-line id-length\n x?: string;\n // oxlint-disable-next-line id-length\n y?: string;\n};\n\ntype CreateAxisTooltipFormatterParams = {\n thresholdLines: NormalizedThresholdLine[];\n userOption: ChartProps['option'];\n};\n\ntype CreateScatterTooltipFormatterParams = {\n dataset: ChartProps['dataset'];\n getChartInstance?: () => ScatterTooltipChart | undefined;\n getLegendSelected?: () => Record<string, boolean> | undefined;\n series: EchartsSeries;\n seriesAxisNames?: Array<SeriesAxisNames | undefined>;\n userOption: ChartProps['option'];\n};\n\n/**\n * Upper bound on the points one tooltip lists, so a dense cluster cannot grow\n * a tooltip that covers the chart.\n */\nconst MAX_TOOLTIP_POINTS = 5;\n\n/**\n * Builds the ECharts axis-tooltip formatter used by line-like charts.\n * It renders Needle tooltip markup and augments non-threshold series with\n * threshold notifications when their current value crosses a threshold line.\n */\nexport function createAxisTooltipFormatter({\n thresholdLines,\n userOption,\n}: CreateAxisTooltipFormatterParams) {\n const valueFormatter = getTooltipValueFormatter(userOption);\n\n return function axisTooltipFormatter(params: unknown) {\n const paramsArray = Array.isArray(params) ? params : [params];\n const firstParam = paramsArray[0];\n\n return `${renderToString(\n <span className=\"ndl-charts-chart-tooltip\">\n <ChartTooltip.Title>\n {firstParam?.axisValueLabel ?? ''}\n </ChartTooltip.Title>\n {paramsArray.map((series) => {\n const value = extractValueFromTooltipSeries(\n series.value,\n series.encode,\n series.axisDim,\n );\n\n const seriesValue = typeof value === 'number' ? value : Number(value);\n\n const isSeriesThresholdLine = isThresholdLine(series.seriesName);\n\n const notifications = thresholdLines.flatMap((threshold) => {\n if (isSeriesThresholdLine || Number.isNaN(seriesValue)) {\n return [];\n }\n\n const {\n notificationType,\n value: thresholdValue,\n condition,\n customConditionText,\n customCondition,\n } = threshold;\n const conditionEvaluation = customCondition\n ? {\n conditionText: customConditionText,\n isConditionMet: customCondition(seriesValue, thresholdValue),\n }\n : evaluateThresholdCondition(\n seriesValue,\n condition,\n thresholdValue,\n );\n\n if (!conditionEvaluation.isConditionMet) {\n return [];\n }\n\n return [\n {\n id: `threshold-${notificationType}`,\n leadingElement: customCondition\n ? conditionEvaluation.conditionText\n : `${conditionEvaluation.conditionText} threshold`,\n notificationType,\n trailingElement: valueFormatter(thresholdValue),\n },\n ];\n });\n\n return (\n <ChartTooltip.Content\n key={series.seriesName}\n leadingElement={\n isSeriesThresholdLine\n ? `${capitalizeFirstLetter(\n getThresholdLineDisplayName(series.seriesName),\n )} threshold`\n : series.seriesName\n }\n trailingElement={valueFormatter(value)}\n indentSquareColor={series.color}\n notifications={notifications}\n />\n );\n })}\n </span>,\n )}`;\n };\n}\n\n/**\n * Builds the ECharts item-tooltip formatter used by scatter charts.\n *\n * The title comes from ECharts `encode.tooltip`, then `encode.itemName`, then\n * an extra data dimension, and otherwise the series name. x and y are listed\n * underneath. See https://echarts.apache.org/en/option.html#series-scatter.encode\n *\n * `tooltip.valueFormatter` runs on the x and y values only. Those calls pass\n * `{ axis: 'x' | 'y' }` (`TooltipValueContext`) as the third argument. The\n * title is shown unchanged.\n *\n * Points whose symbols overlap the hovered one are listed in the same tooltip,\n * closest first, so a cluster is readable without zooming in. Each point gets\n * its own block: the series color sits once on the block title, and the rows\n * are labelled with the axis `name` when the consumer set one, falling back to\n * the dataset dimension name.\n */\nexport function createScatterTooltipFormatter({\n dataset,\n getChartInstance,\n getLegendSelected,\n series,\n seriesAxisNames,\n userOption,\n}: CreateScatterTooltipFormatterParams) {\n const valueFormatter = getTooltipValueFormatter(userOption);\n const radius = getScatterSymbolSize(series);\n const seriesList = Array.isArray(series) ? series : [series];\n\n const renderPoint = (point: ScatterTooltipPoint, key: string) => {\n // ECharts only copies x/y into the hovered point's `encode`. The dimension\n // the consumer set on `encode.tooltip` (or `itemName`) still lives on the\n // series option, which is what the nearby points are already read from.\n const seriesOption = seriesList[point.seriesIndex ?? 0] as\n | { color?: unknown; encode?: Record<string, unknown> }\n | undefined;\n // The hovered point's own color is its theme-colored interior. The swatch\n // uses the series color, which is the ring.\n const swatchColor =\n typeof seriesOption?.color === 'string'\n ? seriesOption.color\n : point.color;\n const seriesEncode = seriesOption?.encode;\n const titleRef = extraTooltipRefs({\n ...point,\n encode: {\n ...point.encode,\n ...(seriesEncode?.tooltip !== undefined && {\n tooltip: seriesEncode.tooltip,\n }),\n ...(seriesEncode?.itemName !== undefined && {\n itemName: seriesEncode.itemName,\n }),\n },\n })[0];\n // ECharts reports `name` as '' when a point has no name dimension, which\n // would hide the title and the color swatch. The series name fills that in.\n const pointName =\n point.name !== undefined && point.name !== ''\n ? point.name\n : point.seriesName;\n const titleValue =\n titleRef !== undefined\n ? readEncodedValue(point.value, titleRef, point.dimensionNames)\n : pointName;\n // The title identifies the point, so it is not run through\n // `valueFormatter`. Only string and number titles are renderable children.\n const titleText =\n typeof titleValue === 'string' || typeof titleValue === 'number'\n ? titleValue\n : undefined;\n const refs = getEncodedAxisRefs(point.encode);\n const xValue = readEncodedValue(point.value, refs.x, point.dimensionNames);\n const yValue = readEncodedValue(point.value, refs.y, point.dimensionNames);\n const axisNames = seriesAxisNames?.[point.seriesIndex ?? 0];\n\n return (\n <div className=\"ndl-charts-chart-tooltip-point\" key={key}>\n {titleText !== undefined && titleText !== '' && (\n <ChartTooltip.Title indentSquareColor={swatchColor}>\n {titleText}\n </ChartTooltip.Title>\n )}\n {xValue !== undefined && (\n <ChartTooltip.Content\n leadingElement={\n axisNames?.x ??\n encodedDimensionLabel(refs.x, point.dimensionNames, 'x')\n }\n trailingElement={valueFormatter(xValue, point.dataIndex, {\n axis: 'x',\n })}\n />\n )}\n {yValue !== undefined && (\n <ChartTooltip.Content\n leadingElement={\n axisNames?.y ??\n encodedDimensionLabel(refs.y, point.dimensionNames, 'y')\n }\n trailingElement={valueFormatter(yValue, point.dataIndex, {\n axis: 'y',\n })}\n />\n )}\n </div>\n );\n };\n\n return function scatterTooltipFormatter(params: unknown) {\n const hovered = (\n Array.isArray(params) ? params[0] : params\n ) as ScatterTooltipPoint;\n\n let points = [hovered];\n\n // A tooltip that throws leaves the chart without any tooltip at all, so a\n // failed neighbor lookup falls back to the hovered point.\n try {\n points = findNearbyScatterPoints({\n chart: getChartInstance?.(),\n dataset,\n hovered,\n legendSelected: getLegendSelected?.(),\n maxPoints: MAX_TOOLTIP_POINTS,\n radius,\n series,\n });\n } catch {\n points = [hovered];\n }\n\n return `${renderToString(\n <span className=\"ndl-charts-chart-tooltip\">\n {points.map((point, index) =>\n renderPoint(\n point,\n `${point.seriesIndex}-${point.dataIndex ?? index}`,\n ),\n )}\n </span>,\n )}`;\n };\n}\n"]}
|
|
@@ -21,6 +21,21 @@
|
|
|
21
21
|
const defaultThresholdLineSeriesOption = {
|
|
22
22
|
condition: 'greater',
|
|
23
23
|
};
|
|
24
|
+
const tooltipMaxWidth = 400;
|
|
25
|
+
/**
|
|
26
|
+
* ECharts writes `white-space: nowrap` inline on the tooltip container, so a
|
|
27
|
+
* long series name or category label stretches the tooltip across the chart
|
|
28
|
+
* until the max width and normal wrapping override it. `overflow-wrap` is
|
|
29
|
+
* needed on top of that: the tooltip rows are flex items, and only `anywhere`
|
|
30
|
+
* lets their min-content size drop below the longest word.
|
|
31
|
+
*/
|
|
32
|
+
const tooltipExtraCssText = [
|
|
33
|
+
'box-shadow: none',
|
|
34
|
+
'background-color: transparent',
|
|
35
|
+
`max-width: ${tooltipMaxWidth}px`,
|
|
36
|
+
'white-space: normal',
|
|
37
|
+
'overflow-wrap: anywhere',
|
|
38
|
+
].join('; ');
|
|
24
39
|
/**
|
|
25
40
|
* ECharts component main types that `buildChartOption` always writes in full,
|
|
26
41
|
* so replacing them gives the same "drop what disappeared" behavior as
|
|
@@ -54,5 +69,5 @@ const defaultChartSettings = {
|
|
|
54
69
|
replaceMerge: needleOwnedComponents,
|
|
55
70
|
silent: false,
|
|
56
71
|
};
|
|
57
|
-
export { defaultChartSettings, defaultThresholdLineSeriesOption, needleOwnedComponents, };
|
|
72
|
+
export { defaultChartSettings, defaultThresholdLineSeriesOption, needleOwnedComponents, tooltipExtraCssText, tooltipMaxWidth, };
|
|
58
73
|
//# sourceMappingURL=defaults.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../src/charts/utils/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,gCAAgC,GAElC;IACF,SAAS,EAAE,SAAS;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,qBAAqB,GAAG;IAC5B,UAAU;IACV,SAAS;IACT,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,OAAO;CACR,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,oBAAoB,GAAwC;IAChE,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,qBAAqB;IACnC,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,OAAO,EACL,oBAAoB,EACpB,gCAAgC,EAChC,qBAAqB,
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../src/charts/utils/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,MAAM,gCAAgC,GAElC;IACF,SAAS,EAAE,SAAS;CACrB,CAAC;AAEF,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;;;GAMG;AACH,MAAM,mBAAmB,GAAG;IAC1B,kBAAkB;IAClB,+BAA+B;IAC/B,cAAc,eAAe,IAAI;IACjC,qBAAqB;IACrB,yBAAyB;CAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;;;;;;;GAQG;AACH,MAAM,qBAAqB,GAAG;IAC5B,UAAU;IACV,SAAS;IACT,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,OAAO;CACR,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,oBAAoB,GAAwC;IAChE,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE,qBAAqB;IACnC,MAAM,EAAE,KAAK;CACd,CAAC;AAEF,OAAO,EACL,oBAAoB,EACpB,gCAAgC,EAChC,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,GAChB,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 { ChartProps, Condition } from './chart-types';\n\nconst defaultThresholdLineSeriesOption: {\n condition: Condition;\n} = {\n condition: 'greater',\n};\n\nconst tooltipMaxWidth = 400;\n\n/**\n * ECharts writes `white-space: nowrap` inline on the tooltip container, so a\n * long series name or category label stretches the tooltip across the chart\n * until the max width and normal wrapping override it. `overflow-wrap` is\n * needed on top of that: the tooltip rows are flex items, and only `anywhere`\n * lets their min-content size drop below the longest word.\n */\nconst tooltipExtraCssText = [\n 'box-shadow: none',\n 'background-color: transparent',\n `max-width: ${tooltipMaxWidth}px`,\n 'white-space: normal',\n 'overflow-wrap: anywhere',\n].join('; ');\n\n/**\n * ECharts component main types that `buildChartOption` always writes in full,\n * so replacing them gives the same \"drop what disappeared\" behavior as\n * `notMerge`. Every entry has to be a registered component main type, which is\n * only asserted by ECharts in development builds.\n *\n * `toolbox` is deliberately absent: it has to keep its view instance across\n * updates, see `defaultChartSettings`.\n */\nconst needleOwnedComponents = [\n 'dataZoom',\n 'dataset',\n 'grid',\n 'legend',\n 'series',\n 'tooltip',\n 'xAxis',\n 'yAxis',\n];\n\n/**\n * `notMerge` rebuilds every component view on each `setOption`. That makes\n * ECharts mount a fresh toolbox brush controller while the previous one stays\n * attached to the renderer, because `ToolboxView.dispose` iterates its feature\n * map with `zrUtil.each` and so never disposes anything. Every leftover\n * controller then re-applies the same drag, each time against an axis the\n * previous one already zoomed, which shrinks the selected range.\n */\nconst defaultChartSettings: NonNullable<ChartProps['settings']> = {\n lazyUpdate: false,\n notMerge: false,\n replaceMerge: needleOwnedComponents,\n silent: false,\n};\n\nexport {\n defaultChartSettings,\n defaultThresholdLineSeriesOption,\n needleOwnedComponents,\n tooltipExtraCssText,\n tooltipMaxWidth,\n};\n"]}
|
|
@@ -34,9 +34,14 @@ const highlightOrDownplayLineAndBarSeries = (chart, currentSeriesToDispatch, act
|
|
|
34
34
|
const isDownplay = action === 'downplay';
|
|
35
35
|
const allChartOptionSeries = (currentChartOptions === null || currentChartOptions === void 0 ? void 0 : currentChartOptions.series) ||
|
|
36
36
|
[];
|
|
37
|
-
// Change emphasis state to add opacity on the non highlighted items
|
|
37
|
+
// Change emphasis state to add opacity on the non highlighted items.
|
|
38
|
+
// Scatter keeps emphasis enabled: that state is what fills the circle when
|
|
39
|
+
// a point is hovered, and disabling it on legend mouse-leave would turn the
|
|
40
|
+
// fill off too.
|
|
38
41
|
chart === null || chart === void 0 ? void 0 : chart.setOption({
|
|
39
|
-
series: allChartOptionSeries === null || allChartOptionSeries === void 0 ? void 0 : allChartOptionSeries.map((seriesItem) =>
|
|
42
|
+
series: allChartOptionSeries === null || allChartOptionSeries === void 0 ? void 0 : allChartOptionSeries.map((seriesItem) => seriesItem.type === 'scatter'
|
|
43
|
+
? seriesItem
|
|
44
|
+
: Object.assign(Object.assign({}, seriesItem), { emphasis: Object.assign(Object.assign({}, seriesItem.emphasis), { disabled: isDownplay }) })),
|
|
40
45
|
});
|
|
41
46
|
const seriesWithSeriesIndex = (_a = allChartOptionSeries === null || allChartOptionSeries === void 0 ? void 0 : allChartOptionSeries
|
|
42
47
|
// Since the series index does not exist in the data we extract it from the series index
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"legend-utils.js","sourceRoot":"","sources":["../../../../src/charts/utils/legend-utils.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 {\n type EChartsOption,\n type EChartsType,\n getInstanceByDom,\n} from 'echarts';\n\nexport const resetAllSeriesHighlight = (chart: EChartsType) => {\n const option = chart.getOption();\n const seriesList = (option.series as unknown[] | undefined) || [];\n\n seriesList.forEach((_series, seriesIndex: number) => {\n chart.dispatchAction({\n seriesIndex,\n type: 'downplay',\n });\n });\n};\n\nconst highlightOrDownplayLineAndBarSeries = (\n chart: EChartsType,\n currentSeriesToDispatch: { name: string; color: string }[],\n action: 'highlight' | 'downplay',\n currentChartOptions: ReturnType<EChartsType['getOption']>,\n) => {\n const isDownplay = action === 'downplay';\n const allChartOptionSeries =\n (currentChartOptions?.series as Record<string, unknown>[] | undefined) ||\n [];\n\n // Change emphasis state to add opacity on the non highlighted items\n chart?.setOption({\n series: allChartOptionSeries?.map(\n (seriesItem: Record<string, unknown>) => ({\n ...seriesItem,\n emphasis: {\n ...(seriesItem.emphasis as Record<string, unknown>),\n disabled: isDownplay,\n },\n }),\n ),\n });\n\n const seriesWithSeriesIndex = allChartOptionSeries\n // Since the series index does not exist in the data we extract it from the series index\n ?.map((seriesItem, index) => ({\n ...seriesItem,\n seriesIndex: index,\n }))\n // Select the series that are in the currentSeriesToDispatch array\n ?.filter((seriesItem: Record<string, unknown>) =>\n currentSeriesToDispatch.some((series) => series.name === seriesItem.name),\n );\n\n if (!seriesWithSeriesIndex.length) {\n return;\n }\n\n chart?.dispatchAction({\n seriesIndex: seriesWithSeriesIndex.map((series) => series.seriesIndex),\n type: action,\n });\n};\n\n/**\n * Highlight or downplay pie chart dataset item\n */\nconst highlightOrDownplayPieSlices = (\n chart: EChartsType,\n currentSeriesToDispatch: { name: string; color: string }[],\n action: 'highlight' | 'downplay',\n currentChartOptions: ReturnType<EChartsType['getOption']>,\n) => {\n const isDownplay = action === 'downplay';\n const allChartOptionSeries =\n (currentChartOptions?.series as Record<string, unknown>[] | undefined) ||\n [];\n\n // Change blur state to add opacity on the non highlighted items in the pie chart\n chart?.setOption({\n series: allChartOptionSeries?.map(\n (seriesItem: Record<string, unknown>) => ({\n ...seriesItem,\n blur: {\n itemStyle: {\n opacity: isDownplay ? 1 : 0.3,\n },\n label: {\n opacity: isDownplay ? 1 : 0.3,\n },\n },\n }),\n ),\n });\n\n // The dataIndex that we want to dispatch can be found in the dataset[0] source array, where the first item is the name of the series\n const chartOptionDataset =\n currentChartOptions?.dataset as EChartsOption['dataset'];\n const datasetArray = Array.isArray(chartOptionDataset)\n ? chartOptionDataset\n : [chartOptionDataset];\n const sourceArray = datasetArray?.[0]?.source as unknown[][];\n\n // Find the dataIndexes that we want to dispatch\n const currentDataSeriesIndexes = currentSeriesToDispatch.map((series) => {\n const index = sourceArray?.findIndex((item) => item[0] === series.name) - 1;\n return index;\n });\n\n if (action === 'highlight') {\n // Downplay other data indexes to make sure the other slices are not highlighted\n const otherSeriesIndexes = sourceArray\n .map((_row, index) => index)\n .filter((dataIndex) => !currentDataSeriesIndexes.includes(dataIndex));\n\n chart?.dispatchAction({\n dataIndex: otherSeriesIndexes,\n seriesIndex: [0], // pie charts only has one series so seriesIndex is always 0\n type: 'downplay',\n });\n }\n\n chart?.dispatchAction({\n dataIndex: currentDataSeriesIndexes,\n seriesIndex: [0], // pie charts only has one series so otherSeriesIndexes is always 0\n type: action,\n });\n};\n\n/**\n * Highlight or downplay the series in the chart to toggle between emphasized and non-emphasized state\n */\nconst highlightOrDownplaySeries = (\n chartRef: React.RefObject<HTMLDivElement | null>,\n series: { name: string; color: string }[],\n currentSelectedSeries: Record<string, boolean>,\n currentSeriesToDispatch: { name: string; color: string }[],\n action: 'highlight' | 'downplay',\n) => {\n const hasOnlyOneSeries = series.length === 1;\n\n const isOnlyOneSeriesSelected =\n Object.values(currentSelectedSeries).filter(Boolean).length === 1;\n\n if (\n isOnlyOneSeriesSelected ||\n currentSeriesToDispatch.length === 0 ||\n chartRef.current === null ||\n hasOnlyOneSeries\n ) {\n return;\n }\n\n const chart = getInstanceByDom(chartRef.current);\n\n if (!chart) {\n return;\n }\n const currentChartOptions = chart.getOption();\n\n const seriesType = (\n currentChartOptions?.series as Record<string, unknown>[]\n )?.[0]?.type;\n\n if (seriesType === 'pie') {\n highlightOrDownplayPieSlices(\n chart,\n currentSeriesToDispatch,\n action,\n currentChartOptions,\n );\n } else {\n highlightOrDownplayLineAndBarSeries(\n chart,\n currentSeriesToDispatch,\n action,\n currentChartOptions,\n );\n }\n};\n\nexport { highlightOrDownplaySeries };\n"]}
|
|
1
|
+
{"version":3,"file":"legend-utils.js","sourceRoot":"","sources":["../../../../src/charts/utils/legend-utils.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 {\n type EChartsOption,\n type EChartsType,\n getInstanceByDom,\n} from 'echarts';\n\nexport const resetAllSeriesHighlight = (chart: EChartsType) => {\n const option = chart.getOption();\n const seriesList = (option.series as unknown[] | undefined) || [];\n\n seriesList.forEach((_series, seriesIndex: number) => {\n chart.dispatchAction({\n seriesIndex,\n type: 'downplay',\n });\n });\n};\n\nconst highlightOrDownplayLineAndBarSeries = (\n chart: EChartsType,\n currentSeriesToDispatch: { name: string; color: string }[],\n action: 'highlight' | 'downplay',\n currentChartOptions: ReturnType<EChartsType['getOption']>,\n) => {\n const isDownplay = action === 'downplay';\n const allChartOptionSeries =\n (currentChartOptions?.series as Record<string, unknown>[] | undefined) ||\n [];\n\n // Change emphasis state to add opacity on the non highlighted items.\n // Scatter keeps emphasis enabled: that state is what fills the circle when\n // a point is hovered, and disabling it on legend mouse-leave would turn the\n // fill off too.\n chart?.setOption({\n series: allChartOptionSeries?.map((seriesItem: Record<string, unknown>) =>\n seriesItem.type === 'scatter'\n ? seriesItem\n : {\n ...seriesItem,\n emphasis: {\n ...(seriesItem.emphasis as Record<string, unknown>),\n disabled: isDownplay,\n },\n },\n ),\n });\n\n const seriesWithSeriesIndex = allChartOptionSeries\n // Since the series index does not exist in the data we extract it from the series index\n ?.map((seriesItem, index) => ({\n ...seriesItem,\n seriesIndex: index,\n }))\n // Select the series that are in the currentSeriesToDispatch array\n ?.filter((seriesItem: Record<string, unknown>) =>\n currentSeriesToDispatch.some((series) => series.name === seriesItem.name),\n );\n\n if (!seriesWithSeriesIndex.length) {\n return;\n }\n\n chart?.dispatchAction({\n seriesIndex: seriesWithSeriesIndex.map((series) => series.seriesIndex),\n type: action,\n });\n};\n\n/**\n * Highlight or downplay pie chart dataset item\n */\nconst highlightOrDownplayPieSlices = (\n chart: EChartsType,\n currentSeriesToDispatch: { name: string; color: string }[],\n action: 'highlight' | 'downplay',\n currentChartOptions: ReturnType<EChartsType['getOption']>,\n) => {\n const isDownplay = action === 'downplay';\n const allChartOptionSeries =\n (currentChartOptions?.series as Record<string, unknown>[] | undefined) ||\n [];\n\n // Change blur state to add opacity on the non highlighted items in the pie chart\n chart?.setOption({\n series: allChartOptionSeries?.map(\n (seriesItem: Record<string, unknown>) => ({\n ...seriesItem,\n blur: {\n itemStyle: {\n opacity: isDownplay ? 1 : 0.3,\n },\n label: {\n opacity: isDownplay ? 1 : 0.3,\n },\n },\n }),\n ),\n });\n\n // The dataIndex that we want to dispatch can be found in the dataset[0] source array, where the first item is the name of the series\n const chartOptionDataset =\n currentChartOptions?.dataset as EChartsOption['dataset'];\n const datasetArray = Array.isArray(chartOptionDataset)\n ? chartOptionDataset\n : [chartOptionDataset];\n const sourceArray = datasetArray?.[0]?.source as unknown[][];\n\n // Find the dataIndexes that we want to dispatch\n const currentDataSeriesIndexes = currentSeriesToDispatch.map((series) => {\n const index = sourceArray?.findIndex((item) => item[0] === series.name) - 1;\n return index;\n });\n\n if (action === 'highlight') {\n // Downplay other data indexes to make sure the other slices are not highlighted\n const otherSeriesIndexes = sourceArray\n .map((_row, index) => index)\n .filter((dataIndex) => !currentDataSeriesIndexes.includes(dataIndex));\n\n chart?.dispatchAction({\n dataIndex: otherSeriesIndexes,\n seriesIndex: [0], // pie charts only has one series so seriesIndex is always 0\n type: 'downplay',\n });\n }\n\n chart?.dispatchAction({\n dataIndex: currentDataSeriesIndexes,\n seriesIndex: [0], // pie charts only has one series so otherSeriesIndexes is always 0\n type: action,\n });\n};\n\n/**\n * Highlight or downplay the series in the chart to toggle between emphasized and non-emphasized state\n */\nconst highlightOrDownplaySeries = (\n chartRef: React.RefObject<HTMLDivElement | null>,\n series: { name: string; color: string }[],\n currentSelectedSeries: Record<string, boolean>,\n currentSeriesToDispatch: { name: string; color: string }[],\n action: 'highlight' | 'downplay',\n) => {\n const hasOnlyOneSeries = series.length === 1;\n\n const isOnlyOneSeriesSelected =\n Object.values(currentSelectedSeries).filter(Boolean).length === 1;\n\n if (\n isOnlyOneSeriesSelected ||\n currentSeriesToDispatch.length === 0 ||\n chartRef.current === null ||\n hasOnlyOneSeries\n ) {\n return;\n }\n\n const chart = getInstanceByDom(chartRef.current);\n\n if (!chart) {\n return;\n }\n const currentChartOptions = chart.getOption();\n\n const seriesType = (\n currentChartOptions?.series as Record<string, unknown>[]\n )?.[0]?.type;\n\n if (seriesType === 'pie') {\n highlightOrDownplayPieSlices(\n chart,\n currentSeriesToDispatch,\n action,\n currentChartOptions,\n );\n } else {\n highlightOrDownplayLineAndBarSeries(\n chart,\n currentSeriesToDispatch,\n action,\n currentChartOptions,\n );\n }\n};\n\nexport { highlightOrDownplaySeries };\n"]}
|