@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":"ChartTooltip.js","sourceRoot":"","sources":["../../../src/charts/ChartTooltip.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,OAAO,EACP,eAAe,EACf,QAAQ,EACR,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,UAAU,MAAM,YAAY,CAAC;AAQpC,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,qBAAqB,CAAC,EAClE,QAAQ,EACR,MAAM,EACN,KAAK,EACL,cAAc,EACd,GAAG,GACe;IAClB,OAAO,CACL,KAAC,OAAO,IACN,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAC,yBAAyB,YAEnC,KAAC,OAAO,CAAC,OAAO,IAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,YACpC,QAAQ,GACO,GACV,CACX,CAAC;AACJ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ChartTooltip.js","sourceRoot":"","sources":["../../../src/charts/ChartTooltip.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 */\nimport {\n Popover,\n StatusIndicator,\n TextLink,\n Typography,\n} from '@neo4j-ndl/react';\nimport classNames from 'classnames';\nimport type React from 'react';\n\nimport {\n type ChartTooltipContentProps,\n type ChartTooltipProps,\n} from './utils/chart-types';\n\nexport const ChartTooltipComponent = function ChartTooltipComponent({\n children,\n isOpen,\n style,\n anchorPosition,\n ref,\n}: ChartTooltipProps) {\n return (\n <Popover\n isOpen={isOpen}\n anchorPosition={anchorPosition}\n placement=\"middle-end-middle-start\"\n >\n <Popover.Content ref={ref} style={style}>\n {children}\n </Popover.Content>\n </Popover>\n );\n};\n\ntype ChartTooltipTitleProps = {\n children: React.ReactNode;\n /**\n * Color swatch shown before the title, for tooltips where every row below\n * the title belongs to the same series and the rows carry no swatch.\n */\n indentSquareColor?: string;\n ref?: React.Ref<HTMLSpanElement>;\n};\n\nconst ChartTooltipTitle = function ChartTooltipTitle({\n children,\n indentSquareColor,\n ref,\n}: ChartTooltipTitleProps) {\n const classes = classNames(`ndl-charts-chart-tooltip-title`);\n\n const title = (\n <Typography ref={ref} variant=\"body-small\" className={classes}>\n {children}\n </Typography>\n );\n\n if (indentSquareColor === undefined) {\n return title;\n }\n\n return (\n <div className=\"ndl-charts-chart-tooltip-title-line\">\n <div\n className=\"ndl-charts-chart-tooltip-title-indent-square\"\n style={{ backgroundColor: indentSquareColor }}\n />\n {title}\n </div>\n );\n};\n\nconst ChartTooltipContent = function ChartTooltipContent({\n leadingElement,\n trailingElement,\n indentSquareColor,\n notifications,\n ref,\n}: ChartTooltipContentProps) {\n const classes = classNames(`ndl-charts-chart-tooltip-content`);\n\n return (\n <div ref={ref} className={classes}>\n <div className=\"ndl-charts-chart-tooltip-content-line\">\n {indentSquareColor && (\n <div\n className=\"ndl-charts-chart-tooltip-content-indent-square\"\n style={{ backgroundColor: indentSquareColor }}\n />\n )}\n {leadingElement && (\n <Typography\n variant={trailingElement ? 'body-medium' : 'label'}\n className=\"ndl-charts-chart-tooltip-content-left-element\"\n >\n {leadingElement}\n </Typography>\n )}\n {trailingElement && (\n <Typography\n variant=\"label\"\n className=\"ndl-charts-chart-tooltip-content-trailing-element\"\n >\n {trailingElement}\n </Typography>\n )}\n </div>\n\n {notifications &&\n notifications.map((notification) => {\n const { id, notificationType, leadingElement, trailingElement } =\n notification;\n\n return (\n <div\n key={`notification-${id}`}\n className={`ndl-charts-chart-tooltip-content-notification ndl-notification-${notificationType}`}\n >\n <StatusIndicator variant={notificationType} />\n <Typography\n variant=\"body-medium\"\n className=\"ndl-charts-chart-tooltip-content-notification-left-element\"\n >\n {leadingElement}\n </Typography>\n <Typography\n variant=\"label\"\n className=\"ndl-charts-chart-tooltip-content-notification-trailing-element\"\n >\n {trailingElement}\n </Typography>\n </div>\n );\n })}\n </div>\n );\n};\n\nconst ChartTooltipLink = function ChartTooltipAction({\n ref,\n ...restProps\n}: React.ComponentProps<typeof TextLink>) {\n return <TextLink ref={ref} {...restProps} />;\n};\n\nconst ChartTooltip = Object.assign(ChartTooltipComponent, {\n Content: ChartTooltipContent,\n Link: ChartTooltipLink,\n Title: ChartTooltipTitle,\n});\n\nexport { ChartTooltip };\n"]}
|
|
@@ -42,6 +42,12 @@ export function useChartOption({ dataZoom, dataset, hasCategoryXAxis, propsSerie
|
|
|
42
42
|
const option = buildChartOption({
|
|
43
43
|
dataZoom,
|
|
44
44
|
dataset,
|
|
45
|
+
// Resolved on each tooltip hover: the scatter tooltip measures distances
|
|
46
|
+
// against the live chart, and legend toggles bypass this option rebuild.
|
|
47
|
+
getChartInstance: () => chartEchartRef.current === null
|
|
48
|
+
? undefined
|
|
49
|
+
: getInstanceByDom(chartEchartRef.current),
|
|
50
|
+
getLegendSelected: () => legendSelectedRef.current,
|
|
45
51
|
hasCategoryXAxis,
|
|
46
52
|
hasMarkArea,
|
|
47
53
|
legendSelected: legendSelectedRef.current || {},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-chart-option.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-chart-option.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAiBvD;;;;;;;;GAQG;AACH,MAAM,UAAU,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,mBAAmB,EAAE,CAAC;IACpE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,EAAiB,CAAC;IAEhE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,gBAAgB,CAAC;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"]}
|
|
1
|
+
{"version":3,"file":"use-chart-option.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-chart-option.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAiBvD;;;;;;;;GAQG;AACH,MAAM,UAAU,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,mBAAmB,EAAE,CAAC;IACpE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,EAAiB,CAAC;IAEhE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,cAAc,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,QAAQ;YACR,OAAO;YACP,yEAAyE;YACzE,yEAAyE;YACzE,gBAAgB,EAAE,GAAG,EAAE,CACrB,cAAc,CAAC,OAAO,KAAK,IAAI;gBAC7B,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,gBAAgB,CAAC,cAAc,CAAC,OAAO,CAAC;YAC9C,iBAAiB,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO;YAClD,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 // Resolved on each tooltip hover: the scatter tooltip measures distances\n // against the live chart, and legend toggles bypass this option rebuild.\n getChartInstance: () =>\n chartEchartRef.current === null\n ? undefined\n : getInstanceByDom(chartEchartRef.current),\n getLegendSelected: () => legendSelectedRef.current,\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"]}
|
|
@@ -158,7 +158,13 @@ export function useLegendSeries({ chartOption, isWaitingForFirstResize, }) {
|
|
|
158
158
|
if (name === undefined) {
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
|
-
|
|
161
|
+
// A scatter point's fill is the theme surface color, so the visual
|
|
162
|
+
// color is not the series color. The series color is the ring.
|
|
163
|
+
const visualColor = chart === null || chart === void 0 ? void 0 : chart.getVisual({ seriesIndex: index }, 'color');
|
|
164
|
+
const seriesColor = currentSeries.color;
|
|
165
|
+
const color = currentSeries.type === 'scatter' && typeof seriesColor === 'string'
|
|
166
|
+
? seriesColor
|
|
167
|
+
: visualColor;
|
|
162
168
|
legendSeries.push({
|
|
163
169
|
color: typeof color === 'string' ? color : '#000000',
|
|
164
170
|
name: String(name),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-legend-series.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-series.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n DatasetComponentOption,\n EChartsOption,\n EChartsType,\n} from 'echarts';\nimport { getInstanceByDom } from 'echarts';\nimport { useMemo } from 'react';\n\nimport type {\n LegendProps,\n NeedleSeries,\n SeriesOption,\n} from '../utils/chart-types';\nimport { isThresholdLine } from '../utils/threshold';\nimport { type ChartRefs, useChartRefsContext } from './use-chart-refs';\n\ntype UseLegendSeriesParams = {\n chartOption: EChartsOption | undefined;\n isWaitingForFirstResize: boolean;\n};\n\ntype LegendSeries = LegendProps['series'];\ntype NeedleSeriesItem = NeedleSeries[number];\ntype SeriesWithDataset = SeriesOption & {\n datasetId?: string;\n datasetIndex?: number;\n};\n\ntype PieLegendSeriesParams = {\n chart: EChartsType | undefined;\n dataset: DatasetComponentOption | undefined;\n encodedItemName: unknown;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n seriesIndex: number;\n};\n\ntype GetCachedLegendColorParams = {\n chart: EChartsType | undefined;\n dataIndexInside: number;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n name: string;\n seriesIndex: number;\n};\n\nconst isThresholdLineSeries = (series: NeedleSeriesItem) =>\n series.type === 'line' &&\n typeof series.name === 'string' &&\n isThresholdLine(series.name);\n\nconst getDatasetForSeries = (\n optionDataset: EChartsOption['dataset'],\n series: SeriesWithDataset,\n) => {\n const datasetList = Array.isArray(optionDataset)\n ? optionDataset\n : [optionDataset];\n\n if (series.datasetId && Array.isArray(optionDataset)) {\n return datasetList.find((dataset) => dataset?.id === series.datasetId);\n }\n\n if (series.datasetIndex !== undefined) {\n return datasetList[series.datasetIndex];\n }\n\n return datasetList[0];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst getCachedLegendColor = ({\n chart,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n dataIndexInside,\n}: GetCachedLegendColorParams) => {\n const freshColor = chart?.getVisual(\n { dataIndexInside, seriesIndex },\n 'color',\n );\n\n if (isAllVisible && typeof freshColor === 'string') {\n legendColorCacheRef.current.set(name, freshColor);\n }\n\n return (\n legendColorCacheRef.current.get(name) ??\n (typeof freshColor === 'string' ? freshColor : '#000000')\n );\n};\n\nconst createPieLegendSeriesItem = ({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n}: GetCachedLegendColorParams) => ({\n color: getCachedLegendColor({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n }),\n name,\n});\n\nconst getPieLegendSeriesFromArrayRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || !Array.isArray(source[0])) {\n return [];\n }\n\n const itemNameIndex = source[0].findIndex((item) => item === encodedItemName);\n if (itemNameIndex === -1) {\n return [];\n }\n\n return source.slice(1).flatMap((row, rowIndex) => {\n if (!Array.isArray(row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[itemNameIndex]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeriesFromObjectRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || typeof encodedItemName !== 'string') {\n return [];\n }\n\n return source.flatMap((row, rowIndex) => {\n if (!isRecord(row) || !(encodedItemName in row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[encodedItemName]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeries = (params: PieLegendSeriesParams): LegendSeries => {\n const source = params.dataset?.source;\n if (!Array.isArray(source) || source.length === 0) {\n return [];\n }\n\n return Array.isArray(source[0])\n ? getPieLegendSeriesFromArrayRows(params)\n : getPieLegendSeriesFromObjectRows(params);\n};\n\n/**\n * Derives Needle legend rows from ECharts' normalized option and visual state.\n *\n * Standard series map one-to-one with legend items. Pie charts instead create a\n * legend item for each data row, so the hook reads the encoded item-name column\n * from the dataset and asks ECharts for each slice color. Fresh colors are\n * cached while all slices are visible because ECharts reports dimmed colors for\n * deselected slices.\n *\n * The hook waits until the first chart resize has completed so color lookups run\n * against an initialized ECharts instance.\n */\nexport function useLegendSeries({\n chartOption,\n isWaitingForFirstResize,\n}: UseLegendSeriesParams): LegendSeries | undefined {\n const { chartEchartRef, legendColorCacheRef, legendSelectedRef } =\n useChartRefsContext();\n\n return useMemo(() => {\n if (chartEchartRef.current === null || isWaitingForFirstResize) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n const optionSeries = (chartOption?.series as NeedleSeries) ?? [];\n const optionDataset = chartOption?.dataset;\n const isAllLegendSeriesVisible = Object.values(\n legendSelectedRef.current,\n ).every((isVisible) => isVisible);\n\n const legendSeries: LegendSeries = [];\n if (Array.isArray(optionSeries)) {\n optionSeries.forEach((currentSeries, index) => {\n if (currentSeries === null) {\n return;\n } else if (isThresholdLineSeries(currentSeries)) {\n return;\n } else if (currentSeries.type === 'pie') {\n legendSeries.push(\n ...getPieLegendSeries({\n chart,\n dataset: getDatasetForSeries(\n optionDataset,\n currentSeries as SeriesWithDataset,\n ),\n encodedItemName: currentSeries.encode?.itemName,\n isAllVisible: isAllLegendSeriesVisible,\n legendColorCacheRef,\n seriesIndex: index,\n }),\n );\n return;\n } else {\n const name = currentSeries.name;\n\n if (name === undefined) {\n return;\n }\n\n const color = chart?.getVisual({ seriesIndex: index }, 'color');\n legendSeries.push({\n color: typeof color === 'string' ? color : '#000000',\n name: String(name),\n });\n }\n });\n }\n return legendSeries;\n }, [\n chartEchartRef,\n chartOption,\n isWaitingForFirstResize,\n legendColorCacheRef,\n legendSelectedRef,\n ]);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"use-legend-series.js","sourceRoot":"","sources":["../../../../src/charts/hooks/use-legend-series.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n DatasetComponentOption,\n EChartsOption,\n EChartsType,\n} from 'echarts';\nimport { getInstanceByDom } from 'echarts';\nimport { useMemo } from 'react';\n\nimport type {\n LegendProps,\n NeedleSeries,\n SeriesOption,\n} from '../utils/chart-types';\nimport { isThresholdLine } from '../utils/threshold';\nimport { type ChartRefs, useChartRefsContext } from './use-chart-refs';\n\ntype UseLegendSeriesParams = {\n chartOption: EChartsOption | undefined;\n isWaitingForFirstResize: boolean;\n};\n\ntype LegendSeries = LegendProps['series'];\ntype NeedleSeriesItem = NeedleSeries[number];\ntype SeriesWithDataset = SeriesOption & {\n datasetId?: string;\n datasetIndex?: number;\n};\n\ntype PieLegendSeriesParams = {\n chart: EChartsType | undefined;\n dataset: DatasetComponentOption | undefined;\n encodedItemName: unknown;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n seriesIndex: number;\n};\n\ntype GetCachedLegendColorParams = {\n chart: EChartsType | undefined;\n dataIndexInside: number;\n isAllVisible: boolean;\n legendColorCacheRef: ChartRefs['legendColorCacheRef'];\n name: string;\n seriesIndex: number;\n};\n\nconst isThresholdLineSeries = (series: NeedleSeriesItem) =>\n series.type === 'line' &&\n typeof series.name === 'string' &&\n isThresholdLine(series.name);\n\nconst getDatasetForSeries = (\n optionDataset: EChartsOption['dataset'],\n series: SeriesWithDataset,\n) => {\n const datasetList = Array.isArray(optionDataset)\n ? optionDataset\n : [optionDataset];\n\n if (series.datasetId && Array.isArray(optionDataset)) {\n return datasetList.find((dataset) => dataset?.id === series.datasetId);\n }\n\n if (series.datasetIndex !== undefined) {\n return datasetList[series.datasetIndex];\n }\n\n return datasetList[0];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst getCachedLegendColor = ({\n chart,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n dataIndexInside,\n}: GetCachedLegendColorParams) => {\n const freshColor = chart?.getVisual(\n { dataIndexInside, seriesIndex },\n 'color',\n );\n\n if (isAllVisible && typeof freshColor === 'string') {\n legendColorCacheRef.current.set(name, freshColor);\n }\n\n return (\n legendColorCacheRef.current.get(name) ??\n (typeof freshColor === 'string' ? freshColor : '#000000')\n );\n};\n\nconst createPieLegendSeriesItem = ({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n}: GetCachedLegendColorParams) => ({\n color: getCachedLegendColor({\n chart,\n dataIndexInside,\n isAllVisible,\n legendColorCacheRef,\n name,\n seriesIndex,\n }),\n name,\n});\n\nconst getPieLegendSeriesFromArrayRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || !Array.isArray(source[0])) {\n return [];\n }\n\n const itemNameIndex = source[0].findIndex((item) => item === encodedItemName);\n if (itemNameIndex === -1) {\n return [];\n }\n\n return source.slice(1).flatMap((row, rowIndex) => {\n if (!Array.isArray(row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[itemNameIndex]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeriesFromObjectRows = ({\n chart,\n dataset,\n encodedItemName,\n isAllVisible,\n legendColorCacheRef,\n seriesIndex,\n}: PieLegendSeriesParams): LegendSeries => {\n const source = dataset?.source;\n if (!Array.isArray(source) || typeof encodedItemName !== 'string') {\n return [];\n }\n\n return source.flatMap((row, rowIndex) => {\n if (!isRecord(row) || !(encodedItemName in row)) {\n return [];\n }\n\n return createPieLegendSeriesItem({\n chart,\n dataIndexInside: rowIndex,\n isAllVisible,\n legendColorCacheRef,\n name: String(row[encodedItemName]),\n seriesIndex,\n });\n });\n};\n\nconst getPieLegendSeries = (params: PieLegendSeriesParams): LegendSeries => {\n const source = params.dataset?.source;\n if (!Array.isArray(source) || source.length === 0) {\n return [];\n }\n\n return Array.isArray(source[0])\n ? getPieLegendSeriesFromArrayRows(params)\n : getPieLegendSeriesFromObjectRows(params);\n};\n\n/**\n * Derives Needle legend rows from ECharts' normalized option and visual state.\n *\n * Standard series map one-to-one with legend items. Pie charts instead create a\n * legend item for each data row, so the hook reads the encoded item-name column\n * from the dataset and asks ECharts for each slice color. Fresh colors are\n * cached while all slices are visible because ECharts reports dimmed colors for\n * deselected slices.\n *\n * The hook waits until the first chart resize has completed so color lookups run\n * against an initialized ECharts instance.\n */\nexport function useLegendSeries({\n chartOption,\n isWaitingForFirstResize,\n}: UseLegendSeriesParams): LegendSeries | undefined {\n const { chartEchartRef, legendColorCacheRef, legendSelectedRef } =\n useChartRefsContext();\n\n return useMemo(() => {\n if (chartEchartRef.current === null || isWaitingForFirstResize) {\n return;\n }\n\n const chart = getInstanceByDom(chartEchartRef.current);\n const optionSeries = (chartOption?.series as NeedleSeries) ?? [];\n const optionDataset = chartOption?.dataset;\n const isAllLegendSeriesVisible = Object.values(\n legendSelectedRef.current,\n ).every((isVisible) => isVisible);\n\n const legendSeries: LegendSeries = [];\n if (Array.isArray(optionSeries)) {\n optionSeries.forEach((currentSeries, index) => {\n if (currentSeries === null) {\n return;\n } else if (isThresholdLineSeries(currentSeries)) {\n return;\n } else if (currentSeries.type === 'pie') {\n legendSeries.push(\n ...getPieLegendSeries({\n chart,\n dataset: getDatasetForSeries(\n optionDataset,\n currentSeries as SeriesWithDataset,\n ),\n encodedItemName: currentSeries.encode?.itemName,\n isAllVisible: isAllLegendSeriesVisible,\n legendColorCacheRef,\n seriesIndex: index,\n }),\n );\n return;\n } else {\n const name = currentSeries.name;\n\n if (name === undefined) {\n return;\n }\n\n // A scatter point's fill is the theme surface color, so the visual\n // color is not the series color. The series color is the ring.\n const visualColor = chart?.getVisual({ seriesIndex: index }, 'color');\n const seriesColor = currentSeries.color;\n const color =\n currentSeries.type === 'scatter' && typeof seriesColor === 'string'\n ? seriesColor\n : visualColor;\n legendSeries.push({\n color: typeof color === 'string' ? color : '#000000',\n name: String(name),\n });\n }\n });\n }\n return legendSeries;\n }, [\n chartEchartRef,\n chartOption,\n isWaitingForFirstResize,\n legendColorCacheRef,\n legendSelectedRef,\n ]);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/charts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,2IAA2I;AAC3I,OAAO,EAAE,gCAAgC,EAAE,MAAM,kBAAkB,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\nexport * from './Chart';\nexport * from './ChartEmpty';\n// Export utils and types that were previously exported from Chart.tsx. Not sure that they are needed, but keeping them to not be breaking.\nexport { defaultThresholdLineSeriesOption } from './utils/defaults';\nexport {\n type ChartEmptyProps,\n type ThresholdLineSeriesOption,\n type Values,\n type SeriesOption,\n type EchartsSeries,\n type NeedleSeries,\n} from './utils/chart-types';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/charts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,2IAA2I;AAC3I,OAAO,EAAE,gCAAgC,EAAE,MAAM,kBAAkB,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\nexport * from './Chart';\nexport * from './ChartEmpty';\n// Export utils and types that were previously exported from Chart.tsx. Not sure that they are needed, but keeping them to not be breaking.\nexport { defaultThresholdLineSeriesOption } from './utils/defaults';\nexport { type TooltipValueContext } from './utils/chart-tooltip-formatter';\nexport {\n type ChartEmptyProps,\n type ThresholdLineSeriesOption,\n type Values,\n type SeriesOption,\n type EchartsSeries,\n type NeedleSeries,\n} from './utils/chart-types';\n"]}
|
|
@@ -113,6 +113,84 @@ export const barChartProps = (seriesName, value, rgbSeriesColor) => ({
|
|
|
113
113
|
type: 'value',
|
|
114
114
|
},
|
|
115
115
|
});
|
|
116
|
+
export const scatterChartProps = (seriesName,
|
|
117
|
+
// oxlint-disable-next-line id-length
|
|
118
|
+
x,
|
|
119
|
+
// oxlint-disable-next-line id-length
|
|
120
|
+
y, rgbSeriesColor, tooltipTitle = 'point-a') => ({
|
|
121
|
+
dataset: {
|
|
122
|
+
dimensions: ['id', 'x', 'y', 'label'],
|
|
123
|
+
source: [['row-id', x, y, tooltipTitle]],
|
|
124
|
+
},
|
|
125
|
+
legend: {
|
|
126
|
+
show: true,
|
|
127
|
+
},
|
|
128
|
+
series: [
|
|
129
|
+
{
|
|
130
|
+
color: rgbSeriesColor,
|
|
131
|
+
encode: {
|
|
132
|
+
tooltip: 'label',
|
|
133
|
+
// oxlint-disable-next-line id-length
|
|
134
|
+
x: 'x',
|
|
135
|
+
// oxlint-disable-next-line id-length
|
|
136
|
+
y: 'y',
|
|
137
|
+
},
|
|
138
|
+
name: seriesName,
|
|
139
|
+
type: 'scatter',
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
xAxis: {
|
|
143
|
+
name: 'Duration',
|
|
144
|
+
type: 'value',
|
|
145
|
+
},
|
|
146
|
+
yAxis: {
|
|
147
|
+
name: 'Latency',
|
|
148
|
+
type: 'value',
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
/**
|
|
152
|
+
* Two points sit a fraction of a unit apart and a third shares the coordinates
|
|
153
|
+
* of the first exactly, so their symbols overlap at any reasonable chart size,
|
|
154
|
+
* while the remaining points stay far away.
|
|
155
|
+
*/
|
|
156
|
+
export const overlappingScatterChartProps = {
|
|
157
|
+
dataset: {
|
|
158
|
+
source: [
|
|
159
|
+
['id', 'x', 'y', 'label'],
|
|
160
|
+
['id-near-one', 50, 50, 'near-one'],
|
|
161
|
+
['id-near-two', 50.2, 50.1, 'near-two'],
|
|
162
|
+
['id-same-spot', 50, 50, 'same-spot'],
|
|
163
|
+
['id-far-away', 95, 95, 'far-away'],
|
|
164
|
+
['id-origin', 5, 5, 'origin'],
|
|
165
|
+
],
|
|
166
|
+
},
|
|
167
|
+
legend: {
|
|
168
|
+
show: true,
|
|
169
|
+
},
|
|
170
|
+
series: [
|
|
171
|
+
{
|
|
172
|
+
color: 'rgb(93,207,216)',
|
|
173
|
+
encode: {
|
|
174
|
+
tooltip: 'label',
|
|
175
|
+
// oxlint-disable-next-line id-length
|
|
176
|
+
x: 'x',
|
|
177
|
+
// oxlint-disable-next-line id-length
|
|
178
|
+
y: 'y',
|
|
179
|
+
},
|
|
180
|
+
name: 'Measurements',
|
|
181
|
+
type: 'scatter',
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
xAxis: {
|
|
185
|
+
name: 'Duration',
|
|
186
|
+
type: 'value',
|
|
187
|
+
},
|
|
188
|
+
yAxis: {
|
|
189
|
+
name: 'Latency',
|
|
190
|
+
type: 'value',
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
export const overlappingScatterChart = ({ width = '100%', height = '400px', } = {}) => (_jsx("div", { style: { height, width }, children: _jsx(Chart, Object.assign({}, overlappingScatterChartProps)) }));
|
|
116
194
|
export const multiSeriesChartProps = {
|
|
117
195
|
dataset: {
|
|
118
196
|
dimensions: ['day', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth'],
|
|
@@ -182,6 +260,11 @@ export const multiSeriesChartProps = {
|
|
|
182
260
|
export const multiSeriesChart = ({ chartProps, width = '100%', height = '400px', }) => (_jsx("div", { style: { height, width }, className: "ndl-chart", children: _jsx(Chart, Object.assign({}, multiSeriesChartProps, chartProps)) }));
|
|
183
261
|
export const pieChartWithTooltipFormatter = ({ seriesName, value, rgbSeriesColor, chartProps, width = '100%', height = '400px', }) => (_jsx("div", { style: { height, width }, children: _jsx(ChartWrapperWithTooltipFormatter, Object.assign({}, pieChartProps(seriesName, value, rgbSeriesColor), chartProps)) }));
|
|
184
262
|
export const barChartWithTooltipFormatter = ({ seriesName, value, rgbSeriesColor, chartProps, width = '100%', height = '400px', }) => (_jsx("div", { style: { height, width }, children: _jsx(ChartWrapperWithTooltipFormatter, Object.assign({}, barChartProps(seriesName, value, rgbSeriesColor), chartProps)) }));
|
|
263
|
+
export const scatterChartWithTooltipFormatter = ({ seriesName,
|
|
264
|
+
// oxlint-disable-next-line id-length
|
|
265
|
+
x,
|
|
266
|
+
// oxlint-disable-next-line id-length
|
|
267
|
+
y, rgbSeriesColor, tooltipTitle = 'point-a', chartProps, width = '100%', height = '400px', }) => (_jsx("div", { style: { height, width }, children: _jsx(ChartWrapperWithTooltipFormatter, Object.assign({}, scatterChartProps(seriesName, x, y, rgbSeriesColor, tooltipTitle), chartProps)) }));
|
|
185
268
|
export const barChart = ({ seriesName, value, rgbSeriesColor, chartProps, width = '100%', height = '400px', }) => (_jsx("div", { style: { height, width }, children: _jsx(Chart, Object.assign({}, barChartProps(seriesName, value, rgbSeriesColor), chartProps)) }));
|
|
186
269
|
export const expectChartElementVisible = (page) => __awaiter(void 0, void 0, void 0, function* () {
|
|
187
270
|
yield expect(page.locator('svg').first()).toBeVisible();
|
|
@@ -366,6 +449,38 @@ export const expectFormattedTooltipToBeVisible = (page, seriesName, value, rgbSe
|
|
|
366
449
|
const tooltip = page.getByText(`${seriesName}formatted ${value}`);
|
|
367
450
|
yield expect(tooltip).toBeVisible();
|
|
368
451
|
});
|
|
452
|
+
/**
|
|
453
|
+
* Scatter points are rings, so the series color is the stroke. The fill is the
|
|
454
|
+
* theme surface color until hover paints it.
|
|
455
|
+
*/
|
|
456
|
+
export const scatterPointLocator = (page, rgbSeriesColor) => {
|
|
457
|
+
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
|
|
458
|
+
return page
|
|
459
|
+
.locator(`path[stroke="${rgbSeriesColor}"]`)
|
|
460
|
+
.or(page.locator(`path[stroke="${rgbWithSpaces}"]`));
|
|
461
|
+
};
|
|
462
|
+
export const expectScatterTooltipToBeVisible = (page, tooltipTitle,
|
|
463
|
+
// oxlint-disable-next-line id-length
|
|
464
|
+
x,
|
|
465
|
+
// oxlint-disable-next-line id-length
|
|
466
|
+
y, rgbSeriesColor) => __awaiter(void 0, void 0, void 0, function* () {
|
|
467
|
+
const chartElement = scatterPointLocator(page, rgbSeriesColor);
|
|
468
|
+
yield expect(chartElement).toBeVisible();
|
|
469
|
+
yield chartElement.hover();
|
|
470
|
+
// Scatter uses an item tooltip: encode.tooltip titles it, then the axis-named
|
|
471
|
+
// x and y rows follow.
|
|
472
|
+
const tooltip = page.locator('.ndl-charts-chart-tooltip');
|
|
473
|
+
yield expect(tooltip).toContainText(tooltipTitle);
|
|
474
|
+
yield expect(tooltip).not.toContainText('row-id');
|
|
475
|
+
yield expect(tooltip).toContainText(`Duration`);
|
|
476
|
+
yield expect(tooltip).toContainText(`formatted ${x}`);
|
|
477
|
+
yield expect(tooltip).toContainText(`Latency`);
|
|
478
|
+
yield expect(tooltip).toContainText(`formatted ${y}`);
|
|
479
|
+
// The point color belongs to the title row only, so the rows below it do not
|
|
480
|
+
// repeat the swatch.
|
|
481
|
+
yield expect(tooltip.locator('.ndl-charts-chart-tooltip-title-indent-square')).toHaveCount(1);
|
|
482
|
+
yield expect(tooltip.locator('.ndl-charts-chart-tooltip-content-indent-square')).toHaveCount(0);
|
|
483
|
+
});
|
|
369
484
|
export const expectDefaultFormattedTooltipToBeVisible = (page, seriesName, value, rgbSeriesColor) => __awaiter(void 0, void 0, void 0, function* () {
|
|
370
485
|
const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');
|
|
371
486
|
const chartElement = page
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-test-utils.js","sourceRoot":"","sources":["../../../../src/charts/tests/chart-test-utils.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 { tokens } from '@neo4j-ndl/base';\nimport { Chart } from '@neo4j-ndl/react-charts';\nimport { expect } from '@playwright/experimental-ct-react';\nimport { type Page } from '@playwright/test';\nimport { type ComponentProps } from 'react';\n\nimport { ChartWrapperWithTooltipFormatter } from './ChartWrapperWithTooltipFormatter';\n\n/**\n * Convert hex color to rgb format\n *\n * @param hex - Color in hex code format\n * @returns color in rgb format rgb(_, _, _)\n */\nconst convertHexToRGB = (hex: string) => {\n const normalizedHex = hex.replace(/^#/, '');\n\n const red = parseInt(normalizedHex.substring(0, 2), 16);\n const green = parseInt(normalizedHex.substring(2, 4), 16);\n const blue = parseInt(normalizedHex.substring(4, 6), 16);\n\n return `rgb(${red}, ${green}, ${blue})`;\n};\n\nexport const chartColorsAfterHighlighting: Record<number, string> = {\n 1: 'rgb(93,207,216)',\n 2: 'rgb(84,80,223)',\n 3: 'rgb(242,152,62)',\n 4: 'rgb(221,75,155)',\n 5: 'rgb(156,154,255)',\n 6: 'rgb(132,244,136)',\n 7: 'rgb(69,140,249)',\n 8: 'rgb(113,69,188)',\n 9: 'rgb(240,210,70)',\n 10: 'rgb(210,126,49)',\n 11: 'rgb(78,151,121)',\n 12: 'rgb(190,255,117)',\n};\n\nexport const pieChartProps = (\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => ({\n dataset: [\n {\n source: [\n ['product', '2012'],\n [seriesName, value],\n ],\n },\n ],\n legend: {\n show: true,\n },\n series: [\n {\n center: ['50%', '50%'],\n encode: {\n itemName: 'product',\n value: '2012',\n },\n itemStyle: {\n color: rgbSeriesColor,\n },\n radius: '90%',\n type: 'pie' as const,\n },\n ],\n});\n\nexport const barChartProps = (\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => ({\n dataset: {\n dimensions: ['Country', 'Sales'],\n source: [['Finland', value]],\n },\n legend: {\n show: true,\n },\n series: [\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'Country', y: 'Sales' },\n itemStyle: {\n color: rgbSeriesColor,\n },\n name: seriesName,\n type: 'bar' as const,\n },\n ],\n xAxis: {\n type: 'category' as const,\n },\n yAxis: {\n type: 'value' as const,\n },\n});\n\nexport const multiSeriesChartProps = {\n dataset: {\n dimensions: ['day', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth'],\n source: [\n ['Monday', 20, 40, 60, 80, 100, 120],\n ['Tuesday', 30, 50, 70, 90, 110, 130],\n ['Wednesday', 25, 45, 65, 85, 105, 125],\n ['Thursday', 35, 55, 75, 95, 115, 135],\n ['Friday', 40, 60, 80, 100, 120, 140],\n ],\n },\n legend: {\n show: true,\n },\n option: {},\n series: [\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'first' },\n name: 'First Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'second' },\n name: 'Second Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'third' },\n name: 'Third Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'fourth' },\n name: 'Fourth Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'fifth' },\n name: 'Fifth Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'sixth' },\n name: 'Sixth Series',\n type: 'line' as const,\n },\n ],\n xAxis: {\n type: 'category' as const,\n },\n yAxis: {\n type: 'value' as const,\n },\n};\n\nexport const multiSeriesChart = ({\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n}) => (\n <div style={{ height, width }} className=\"ndl-chart\">\n <Chart {...multiSeriesChartProps} {...chartProps} />\n </div>\n);\n\nexport const pieChartWithTooltipFormatter = ({\n seriesName,\n value,\n rgbSeriesColor,\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n value: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <ChartWrapperWithTooltipFormatter\n {...pieChartProps(seriesName, value, rgbSeriesColor)}\n {...chartProps}\n />\n </div>\n);\n\nexport const barChartWithTooltipFormatter = ({\n seriesName,\n value,\n rgbSeriesColor,\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n value: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <ChartWrapperWithTooltipFormatter\n {...barChartProps(seriesName, value, rgbSeriesColor)}\n {...chartProps}\n />\n </div>\n);\n\nexport const barChart = ({\n seriesName,\n value,\n rgbSeriesColor,\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n value: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <Chart\n {...barChartProps(seriesName, value, rgbSeriesColor)}\n {...chartProps}\n />\n </div>\n);\n\nexport const expectChartElementVisible = async (page: Page) => {\n await expect(page.locator('svg').first()).toBeVisible();\n await expect(page.locator('.ndl-chart-legend')).toBeVisible();\n};\n\nexport const startLegendMeasuringObserver = async (\n page: Page,\n options: { chartLayoutSelector?: string } = {},\n) => {\n await page.evaluate(({ chartLayoutSelector }) => {\n const windowWithLegendObserver = window as Window & {\n __chartHeightDuringLegendMeasurement?: number;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __legendMeasuringClassWasAdded?: boolean;\n __legendMeasuringObserver?: MutationObserver;\n };\n const legendElement = document.querySelector('.ndl-chart-legend');\n const chartLayout = chartLayoutSelector\n ? document.querySelector(chartLayoutSelector)\n : undefined;\n\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement = undefined;\n windowWithLegendObserver.__legendMeasuringClassWasAdded = false;\n windowWithLegendObserver.__legendMeasuringObserver?.disconnect();\n\n if (!legendElement) {\n return;\n }\n\n const observer = new MutationObserver(() => {\n if (!legendElement.classList.contains('ndl-chart-legend-calculating')) {\n return;\n }\n\n windowWithLegendObserver.__legendMeasuringClassWasAdded = true;\n\n if (\n chartLayout &&\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement ===\n undefined\n ) {\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement =\n chartLayout.getBoundingClientRect().height;\n }\n });\n\n observer.observe(legendElement, {\n attributeFilter: ['class'],\n attributes: true,\n });\n windowWithLegendObserver.__legendMeasuringObserver = observer;\n }, options);\n};\n\nexport const getLegendMeasuringObserverResult = async (page: Page) =>\n page.evaluate(() => {\n const windowWithLegendObserver = window as Window & {\n __chartHeightDuringLegendMeasurement?: number;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __legendMeasuringClassWasAdded?: boolean;\n __legendMeasuringObserver?: MutationObserver;\n };\n\n windowWithLegendObserver.__legendMeasuringObserver?.disconnect();\n\n return {\n chartHeightDuringMeasurement:\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement,\n didAddMeasuringClass:\n windowWithLegendObserver.__legendMeasuringClassWasAdded ?? false,\n };\n });\n\nconst SELECTORS = {\n CHECKMARK:\n '.ndl-chart-legend > .ndl-chart-legend-item .ndl-chart-legend-item-square-checkmark',\n DESELECTED: '.ndl-chart-legend > .ndl-chart-legend-item-deselected',\n seriesCheckmark: (name: string) =>\n `.ndl-chart-legend > [data-labelname=\"${name}\"] .ndl-chart-legend-item-square-checkmark`,\n seriesDeselected: (name: string) =>\n `.ndl-chart-legend > [data-labelname=\"${name}\"].ndl-chart-legend-item-deselected`,\n} as const;\n\nconst getGraphPaletteColorFromSeriesIndex = (index: string): string => {\n const hexColor = tokens.categorical[index as keyof typeof tokens.categorical];\n if (!hexColor) {\n throw new Error(`Categorical palette index ${index} not found`);\n }\n\n return hexColor;\n};\n\n/**\n * Checks so a single series is not blurred.\n */\nexport const expectSingleSeriesNotToBeBlurred = async (\n page: Page,\n seriesName: string,\n) => {\n const allChartSeries = multiSeriesChartProps.series;\n\n const seriesIndex =\n allChartSeries.findIndex((seriesItem) => seriesItem.name === seriesName) +\n 1;\n\n const rgbSeriesColor = chartColorsAfterHighlighting[seriesIndex];\n const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(\n seriesIndex.toString(),\n );\n\n // More flexible color matching - try both with and without spaces\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n const hexRgb = convertHexToRGB(hexSeriesColor);\n const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');\n\n const pathLocator = page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`))\n .or(page.locator(`path[stroke=\"${hexSeriesColor}\"]`))\n .or(page.locator(`path[stroke=\"${convertHexToRGB(hexSeriesColor)}\"]`))\n .or(page.locator(`path[stroke=\"${rgbWithoutSpaces}\"]`));\n\n // Wait for the element to be attached to the DOM before checking its attributes\n await expect(pathLocator).toBeAttached({ timeout: 10000 });\n await expect(pathLocator).not.toHaveAttribute('stroke-opacity');\n};\n\n/**\n * Checks so that the seriesNamesToBeHighlighted are visible in the chart and that other series are blurred.\n */\nexport const expectLegendSeriesToBeHighlightedInChart = async (\n page: Page,\n seriesNamesToBeHighlighted: string[],\n) => {\n const allChartSeries = multiSeriesChartProps.series;\n\n for (const name of seriesNamesToBeHighlighted) {\n const highlightedSeriesIndex =\n allChartSeries.findIndex((seriesItem) => seriesItem.name === name) + 1;\n\n const rgbSeriesColor = chartColorsAfterHighlighting[highlightedSeriesIndex];\n const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(\n highlightedSeriesIndex.toString(),\n );\n\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n const hexRgb = convertHexToRGB(hexSeriesColor);\n const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');\n\n const pathLocator = page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`))\n .or(page.locator(`path[stroke=\"${hexSeriesColor}\"]`))\n .or(page.locator(`path[stroke=\"${convertHexToRGB(hexSeriesColor)}\"]`))\n .or(page.locator(`path[stroke=\"${rgbWithoutSpaces}\"]`));\n\n await expect(pathLocator).not.toHaveAttribute('stroke-opacity');\n }\n\n const seriesToBeBlurred = allChartSeries.filter(\n (series) => !seriesNamesToBeHighlighted.includes(series.name),\n );\n\n for (const series of seriesToBeBlurred) {\n const blurredSeriesIndex =\n allChartSeries.findIndex(\n (seriesItem) => seriesItem.name === series.name,\n ) + 1;\n\n const rgbSeriesColor = chartColorsAfterHighlighting[blurredSeriesIndex];\n const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(\n blurredSeriesIndex.toString(),\n );\n\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n const hexRgb = convertHexToRGB(hexSeriesColor);\n const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');\n\n const pathLocator = page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`))\n .or(page.locator(`path[stroke=\"${hexSeriesColor}\"]`))\n .or(page.locator(`path[stroke=\"${convertHexToRGB(hexSeriesColor)}\"]`))\n .or(page.locator(`path[stroke=\"${rgbWithoutSpaces}\"]`));\n\n await expect(pathLocator).toHaveAttribute('stroke-opacity');\n }\n};\n\n/**\n * Identifies if the series are visible / not visible in the chart by checking\n * component-owned legend state. ECharts rewrites generated SVG paths during\n * legend updates, which makes exact path color selectors flaky in Firefox.\n */\nexport const expectLegendSeriesToBeVisibleInChart = async (\n page: Page,\n seriesNamesToBeVisible: string[],\n) => {\n await expect(page.locator('svg path').first()).toBeAttached();\n\n for (const name of seriesNamesToBeVisible) {\n const visibleLegendItem = page.locator(\n `.ndl-chart-legend > [data-labelname=\"${name}\"]`,\n );\n\n if ((await visibleLegendItem.count()) > 0) {\n await expect(visibleLegendItem).not.toHaveClass(\n /ndl-chart-legend-item-deselected/,\n );\n }\n }\n\n const hiddenSeries = multiSeriesChartProps.series.filter(\n (series) => !seriesNamesToBeVisible.includes(series.name),\n );\n\n for (const hiddenSeriesItem of hiddenSeries) {\n const hiddenLegendItem = page.locator(\n SELECTORS.seriesDeselected(hiddenSeriesItem.name),\n );\n\n if ((await hiddenLegendItem.count()) > 0) {\n await expect(hiddenLegendItem).toBeVisible();\n }\n }\n};\n\n// Check so legends are selected -> has checkmark and no strike-through classes\nexport const expectLegendsSelected = async (\n page: Page,\n seriesNames: string[],\n) => {\n for (const name of seriesNames) {\n await expect(page.locator(SELECTORS.seriesCheckmark(name))).toBeVisible();\n await expect(\n page.locator(SELECTORS.seriesDeselected(name)),\n ).not.toBeVisible();\n }\n};\n\n// Check so legends are deselected -> has strike-through and no checkmark classes\nexport const expectLegendsDeselected = async (\n page: Page,\n seriesNames: string[],\n) => {\n for (const name of seriesNames) {\n await expect(page.locator(SELECTORS.seriesDeselected(name))).toBeVisible();\n await expect(\n page.locator(SELECTORS.seriesCheckmark(name)),\n ).not.toBeVisible();\n }\n};\n\n// Check so all legends are neutral -> no checkmark and no strike-through classes\nexport const expectAllLegendsNeutral = async (page: Page) => {\n await expect(page.locator(SELECTORS.CHECKMARK)).not.toBeVisible();\n await expect(page.locator(SELECTORS.DESELECTED)).not.toBeVisible();\n};\n\n/**\n * Clicks the series legend item and hover the chart to make sure no blur effect exists on other series in the chart.\n * This is needed to make sure the series has the correct color when looking for them in the chart in later steps.\n */\nexport const clickSeries = async (page: Page, seriesName: string) => {\n await page\n .locator(`.ndl-chart-legend > [data-labelname=\"${seriesName}\"]`)\n .click();\n await page.hover('.ndl-chart');\n};\n\nexport const expectFormattedTooltipToBeVisible = async (\n page: Page,\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => {\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n\n await expect(\n page\n .locator(`path[fill=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`fill[stroke=\"${rgbWithSpaces}\"]`)),\n ).toBeVisible();\n await page\n .locator(`path[fill=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`fill[stroke=\"${rgbWithSpaces}\"]`))\n .hover();\n const tooltip = page.getByText(`${seriesName}formatted ${value}`);\n await expect(tooltip).toBeVisible();\n};\n\nexport const expectDefaultFormattedTooltipToBeVisible = async (\n page: Page,\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => {\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n\n const chartElement = page\n .locator(`path[fill=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[fill=\"${rgbWithSpaces}\"]`));\n\n await expect(chartElement).toBeVisible();\n await chartElement.hover();\n\n const tooltip = page.locator('.ndl-charts-chart-tooltip');\n await expect(tooltip).toContainText(seriesName);\n await expect(tooltip).toContainText(\n new Intl.NumberFormat('en-US').format(value),\n );\n};\n\nexport const waitForAnimationEnd = (page: Page, selector: string) => {\n return page\n .locator(selector)\n .evaluate((element) =>\n Promise.all(\n element.getAnimations().map((animation) => animation.finished),\n ),\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"chart-test-utils.js","sourceRoot":"","sources":["../../../../src/charts/tests/chart-test-utils.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 { tokens } from '@neo4j-ndl/base';\nimport { Chart } from '@neo4j-ndl/react-charts';\nimport { expect } from '@playwright/experimental-ct-react';\nimport { type Page } from '@playwright/test';\nimport { type ComponentProps } from 'react';\n\nimport { ChartWrapperWithTooltipFormatter } from './ChartWrapperWithTooltipFormatter';\n\n/**\n * Convert hex color to rgb format\n *\n * @param hex - Color in hex code format\n * @returns color in rgb format rgb(_, _, _)\n */\nconst convertHexToRGB = (hex: string) => {\n const normalizedHex = hex.replace(/^#/, '');\n\n const red = parseInt(normalizedHex.substring(0, 2), 16);\n const green = parseInt(normalizedHex.substring(2, 4), 16);\n const blue = parseInt(normalizedHex.substring(4, 6), 16);\n\n return `rgb(${red}, ${green}, ${blue})`;\n};\n\nexport const chartColorsAfterHighlighting: Record<number, string> = {\n 1: 'rgb(93,207,216)',\n 2: 'rgb(84,80,223)',\n 3: 'rgb(242,152,62)',\n 4: 'rgb(221,75,155)',\n 5: 'rgb(156,154,255)',\n 6: 'rgb(132,244,136)',\n 7: 'rgb(69,140,249)',\n 8: 'rgb(113,69,188)',\n 9: 'rgb(240,210,70)',\n 10: 'rgb(210,126,49)',\n 11: 'rgb(78,151,121)',\n 12: 'rgb(190,255,117)',\n};\n\nexport const pieChartProps = (\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => ({\n dataset: [\n {\n source: [\n ['product', '2012'],\n [seriesName, value],\n ],\n },\n ],\n legend: {\n show: true,\n },\n series: [\n {\n center: ['50%', '50%'],\n encode: {\n itemName: 'product',\n value: '2012',\n },\n itemStyle: {\n color: rgbSeriesColor,\n },\n radius: '90%',\n type: 'pie' as const,\n },\n ],\n});\n\nexport const barChartProps = (\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => ({\n dataset: {\n dimensions: ['Country', 'Sales'],\n source: [['Finland', value]],\n },\n legend: {\n show: true,\n },\n series: [\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'Country', y: 'Sales' },\n itemStyle: {\n color: rgbSeriesColor,\n },\n name: seriesName,\n type: 'bar' as const,\n },\n ],\n xAxis: {\n type: 'category' as const,\n },\n yAxis: {\n type: 'value' as const,\n },\n});\n\nexport const scatterChartProps = (\n seriesName: string,\n // oxlint-disable-next-line id-length\n x: number,\n // oxlint-disable-next-line id-length\n y: number,\n rgbSeriesColor: string,\n tooltipTitle = 'point-a',\n) => ({\n dataset: {\n dimensions: ['id', 'x', 'y', 'label'],\n source: [['row-id', x, y, tooltipTitle]],\n },\n legend: {\n show: true,\n },\n series: [\n {\n color: rgbSeriesColor,\n encode: {\n tooltip: 'label',\n // oxlint-disable-next-line id-length\n x: 'x',\n // oxlint-disable-next-line id-length\n y: 'y',\n },\n name: seriesName,\n type: 'scatter' as const,\n },\n ],\n xAxis: {\n name: 'Duration',\n type: 'value' as const,\n },\n yAxis: {\n name: 'Latency',\n type: 'value' as const,\n },\n});\n\n/**\n * Two points sit a fraction of a unit apart and a third shares the coordinates\n * of the first exactly, so their symbols overlap at any reasonable chart size,\n * while the remaining points stay far away.\n */\nexport const overlappingScatterChartProps = {\n dataset: {\n source: [\n ['id', 'x', 'y', 'label'],\n ['id-near-one', 50, 50, 'near-one'],\n ['id-near-two', 50.2, 50.1, 'near-two'],\n ['id-same-spot', 50, 50, 'same-spot'],\n ['id-far-away', 95, 95, 'far-away'],\n ['id-origin', 5, 5, 'origin'],\n ],\n },\n legend: {\n show: true,\n },\n series: [\n {\n color: 'rgb(93,207,216)',\n encode: {\n tooltip: 'label',\n // oxlint-disable-next-line id-length\n x: 'x',\n // oxlint-disable-next-line id-length\n y: 'y',\n },\n name: 'Measurements',\n type: 'scatter' as const,\n },\n ],\n xAxis: {\n name: 'Duration',\n type: 'value' as const,\n },\n yAxis: {\n name: 'Latency',\n type: 'value' as const,\n },\n};\n\nexport const overlappingScatterChart = ({\n width = '100%',\n height = '400px',\n}: {\n width?: string;\n height?: string;\n} = {}) => (\n <div style={{ height, width }}>\n <Chart {...overlappingScatterChartProps} />\n </div>\n);\n\nexport const multiSeriesChartProps = {\n dataset: {\n dimensions: ['day', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth'],\n source: [\n ['Monday', 20, 40, 60, 80, 100, 120],\n ['Tuesday', 30, 50, 70, 90, 110, 130],\n ['Wednesday', 25, 45, 65, 85, 105, 125],\n ['Thursday', 35, 55, 75, 95, 115, 135],\n ['Friday', 40, 60, 80, 100, 120, 140],\n ],\n },\n legend: {\n show: true,\n },\n option: {},\n series: [\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'first' },\n name: 'First Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'second' },\n name: 'Second Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'third' },\n name: 'Third Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'fourth' },\n name: 'Fourth Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'fifth' },\n name: 'Fifth Series',\n type: 'line' as const,\n },\n {\n // E-Charts uses encode.x and encode.y - https://echarts.apache.org/en/option.html#series-line.encode\n // oxlint-disable-next-line id-length\n encode: { x: 'day', y: 'sixth' },\n name: 'Sixth Series',\n type: 'line' as const,\n },\n ],\n xAxis: {\n type: 'category' as const,\n },\n yAxis: {\n type: 'value' as const,\n },\n};\n\nexport const multiSeriesChart = ({\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n}) => (\n <div style={{ height, width }} className=\"ndl-chart\">\n <Chart {...multiSeriesChartProps} {...chartProps} />\n </div>\n);\n\nexport const pieChartWithTooltipFormatter = ({\n seriesName,\n value,\n rgbSeriesColor,\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n value: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <ChartWrapperWithTooltipFormatter\n {...pieChartProps(seriesName, value, rgbSeriesColor)}\n {...chartProps}\n />\n </div>\n);\n\nexport const barChartWithTooltipFormatter = ({\n seriesName,\n value,\n rgbSeriesColor,\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n value: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <ChartWrapperWithTooltipFormatter\n {...barChartProps(seriesName, value, rgbSeriesColor)}\n {...chartProps}\n />\n </div>\n);\n\nexport const scatterChartWithTooltipFormatter = ({\n seriesName,\n // oxlint-disable-next-line id-length\n x,\n // oxlint-disable-next-line id-length\n y,\n rgbSeriesColor,\n tooltipTitle = 'point-a',\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n tooltipTitle?: string;\n // oxlint-disable-next-line id-length\n x: number;\n // oxlint-disable-next-line id-length\n y: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <ChartWrapperWithTooltipFormatter\n {...scatterChartProps(seriesName, x, y, rgbSeriesColor, tooltipTitle)}\n {...chartProps}\n />\n </div>\n);\n\nexport const barChart = ({\n seriesName,\n value,\n rgbSeriesColor,\n chartProps,\n width = '100%',\n height = '400px',\n}: {\n chartProps?: Partial<ComponentProps<typeof Chart>>;\n width?: string;\n height?: string;\n seriesName: string;\n value: number;\n rgbSeriesColor: string;\n}) => (\n <div style={{ height, width }}>\n <Chart\n {...barChartProps(seriesName, value, rgbSeriesColor)}\n {...chartProps}\n />\n </div>\n);\n\nexport const expectChartElementVisible = async (page: Page) => {\n await expect(page.locator('svg').first()).toBeVisible();\n await expect(page.locator('.ndl-chart-legend')).toBeVisible();\n};\n\nexport const startLegendMeasuringObserver = async (\n page: Page,\n options: { chartLayoutSelector?: string } = {},\n) => {\n await page.evaluate(({ chartLayoutSelector }) => {\n const windowWithLegendObserver = window as Window & {\n __chartHeightDuringLegendMeasurement?: number;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __legendMeasuringClassWasAdded?: boolean;\n __legendMeasuringObserver?: MutationObserver;\n };\n const legendElement = document.querySelector('.ndl-chart-legend');\n const chartLayout = chartLayoutSelector\n ? document.querySelector(chartLayoutSelector)\n : undefined;\n\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement = undefined;\n windowWithLegendObserver.__legendMeasuringClassWasAdded = false;\n windowWithLegendObserver.__legendMeasuringObserver?.disconnect();\n\n if (!legendElement) {\n return;\n }\n\n const observer = new MutationObserver(() => {\n if (!legendElement.classList.contains('ndl-chart-legend-calculating')) {\n return;\n }\n\n windowWithLegendObserver.__legendMeasuringClassWasAdded = true;\n\n if (\n chartLayout &&\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement ===\n undefined\n ) {\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement =\n chartLayout.getBoundingClientRect().height;\n }\n });\n\n observer.observe(legendElement, {\n attributeFilter: ['class'],\n attributes: true,\n });\n windowWithLegendObserver.__legendMeasuringObserver = observer;\n }, options);\n};\n\nexport const getLegendMeasuringObserverResult = async (page: Page) =>\n page.evaluate(() => {\n const windowWithLegendObserver = window as Window & {\n __chartHeightDuringLegendMeasurement?: number;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __legendMeasuringClassWasAdded?: boolean;\n __legendMeasuringObserver?: MutationObserver;\n };\n\n windowWithLegendObserver.__legendMeasuringObserver?.disconnect();\n\n return {\n chartHeightDuringMeasurement:\n windowWithLegendObserver.__chartHeightDuringLegendMeasurement,\n didAddMeasuringClass:\n windowWithLegendObserver.__legendMeasuringClassWasAdded ?? false,\n };\n });\n\nconst SELECTORS = {\n CHECKMARK:\n '.ndl-chart-legend > .ndl-chart-legend-item .ndl-chart-legend-item-square-checkmark',\n DESELECTED: '.ndl-chart-legend > .ndl-chart-legend-item-deselected',\n seriesCheckmark: (name: string) =>\n `.ndl-chart-legend > [data-labelname=\"${name}\"] .ndl-chart-legend-item-square-checkmark`,\n seriesDeselected: (name: string) =>\n `.ndl-chart-legend > [data-labelname=\"${name}\"].ndl-chart-legend-item-deselected`,\n} as const;\n\nconst getGraphPaletteColorFromSeriesIndex = (index: string): string => {\n const hexColor = tokens.categorical[index as keyof typeof tokens.categorical];\n if (!hexColor) {\n throw new Error(`Categorical palette index ${index} not found`);\n }\n\n return hexColor;\n};\n\n/**\n * Checks so a single series is not blurred.\n */\nexport const expectSingleSeriesNotToBeBlurred = async (\n page: Page,\n seriesName: string,\n) => {\n const allChartSeries = multiSeriesChartProps.series;\n\n const seriesIndex =\n allChartSeries.findIndex((seriesItem) => seriesItem.name === seriesName) +\n 1;\n\n const rgbSeriesColor = chartColorsAfterHighlighting[seriesIndex];\n const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(\n seriesIndex.toString(),\n );\n\n // More flexible color matching - try both with and without spaces\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n const hexRgb = convertHexToRGB(hexSeriesColor);\n const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');\n\n const pathLocator = page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`))\n .or(page.locator(`path[stroke=\"${hexSeriesColor}\"]`))\n .or(page.locator(`path[stroke=\"${convertHexToRGB(hexSeriesColor)}\"]`))\n .or(page.locator(`path[stroke=\"${rgbWithoutSpaces}\"]`));\n\n // Wait for the element to be attached to the DOM before checking its attributes\n await expect(pathLocator).toBeAttached({ timeout: 10000 });\n await expect(pathLocator).not.toHaveAttribute('stroke-opacity');\n};\n\n/**\n * Checks so that the seriesNamesToBeHighlighted are visible in the chart and that other series are blurred.\n */\nexport const expectLegendSeriesToBeHighlightedInChart = async (\n page: Page,\n seriesNamesToBeHighlighted: string[],\n) => {\n const allChartSeries = multiSeriesChartProps.series;\n\n for (const name of seriesNamesToBeHighlighted) {\n const highlightedSeriesIndex =\n allChartSeries.findIndex((seriesItem) => seriesItem.name === name) + 1;\n\n const rgbSeriesColor = chartColorsAfterHighlighting[highlightedSeriesIndex];\n const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(\n highlightedSeriesIndex.toString(),\n );\n\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n const hexRgb = convertHexToRGB(hexSeriesColor);\n const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');\n\n const pathLocator = page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`))\n .or(page.locator(`path[stroke=\"${hexSeriesColor}\"]`))\n .or(page.locator(`path[stroke=\"${convertHexToRGB(hexSeriesColor)}\"]`))\n .or(page.locator(`path[stroke=\"${rgbWithoutSpaces}\"]`));\n\n await expect(pathLocator).not.toHaveAttribute('stroke-opacity');\n }\n\n const seriesToBeBlurred = allChartSeries.filter(\n (series) => !seriesNamesToBeHighlighted.includes(series.name),\n );\n\n for (const series of seriesToBeBlurred) {\n const blurredSeriesIndex =\n allChartSeries.findIndex(\n (seriesItem) => seriesItem.name === series.name,\n ) + 1;\n\n const rgbSeriesColor = chartColorsAfterHighlighting[blurredSeriesIndex];\n const hexSeriesColor = getGraphPaletteColorFromSeriesIndex(\n blurredSeriesIndex.toString(),\n );\n\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n const hexRgb = convertHexToRGB(hexSeriesColor);\n const rgbWithoutSpaces = hexRgb.replace(/, /g, ',');\n\n const pathLocator = page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`))\n .or(page.locator(`path[stroke=\"${hexSeriesColor}\"]`))\n .or(page.locator(`path[stroke=\"${convertHexToRGB(hexSeriesColor)}\"]`))\n .or(page.locator(`path[stroke=\"${rgbWithoutSpaces}\"]`));\n\n await expect(pathLocator).toHaveAttribute('stroke-opacity');\n }\n};\n\n/**\n * Identifies if the series are visible / not visible in the chart by checking\n * component-owned legend state. ECharts rewrites generated SVG paths during\n * legend updates, which makes exact path color selectors flaky in Firefox.\n */\nexport const expectLegendSeriesToBeVisibleInChart = async (\n page: Page,\n seriesNamesToBeVisible: string[],\n) => {\n await expect(page.locator('svg path').first()).toBeAttached();\n\n for (const name of seriesNamesToBeVisible) {\n const visibleLegendItem = page.locator(\n `.ndl-chart-legend > [data-labelname=\"${name}\"]`,\n );\n\n if ((await visibleLegendItem.count()) > 0) {\n await expect(visibleLegendItem).not.toHaveClass(\n /ndl-chart-legend-item-deselected/,\n );\n }\n }\n\n const hiddenSeries = multiSeriesChartProps.series.filter(\n (series) => !seriesNamesToBeVisible.includes(series.name),\n );\n\n for (const hiddenSeriesItem of hiddenSeries) {\n const hiddenLegendItem = page.locator(\n SELECTORS.seriesDeselected(hiddenSeriesItem.name),\n );\n\n if ((await hiddenLegendItem.count()) > 0) {\n await expect(hiddenLegendItem).toBeVisible();\n }\n }\n};\n\n// Check so legends are selected -> has checkmark and no strike-through classes\nexport const expectLegendsSelected = async (\n page: Page,\n seriesNames: string[],\n) => {\n for (const name of seriesNames) {\n await expect(page.locator(SELECTORS.seriesCheckmark(name))).toBeVisible();\n await expect(\n page.locator(SELECTORS.seriesDeselected(name)),\n ).not.toBeVisible();\n }\n};\n\n// Check so legends are deselected -> has strike-through and no checkmark classes\nexport const expectLegendsDeselected = async (\n page: Page,\n seriesNames: string[],\n) => {\n for (const name of seriesNames) {\n await expect(page.locator(SELECTORS.seriesDeselected(name))).toBeVisible();\n await expect(\n page.locator(SELECTORS.seriesCheckmark(name)),\n ).not.toBeVisible();\n }\n};\n\n// Check so all legends are neutral -> no checkmark and no strike-through classes\nexport const expectAllLegendsNeutral = async (page: Page) => {\n await expect(page.locator(SELECTORS.CHECKMARK)).not.toBeVisible();\n await expect(page.locator(SELECTORS.DESELECTED)).not.toBeVisible();\n};\n\n/**\n * Clicks the series legend item and hover the chart to make sure no blur effect exists on other series in the chart.\n * This is needed to make sure the series has the correct color when looking for them in the chart in later steps.\n */\nexport const clickSeries = async (page: Page, seriesName: string) => {\n await page\n .locator(`.ndl-chart-legend > [data-labelname=\"${seriesName}\"]`)\n .click();\n await page.hover('.ndl-chart');\n};\n\nexport const expectFormattedTooltipToBeVisible = async (\n page: Page,\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => {\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n\n await expect(\n page\n .locator(`path[fill=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`fill[stroke=\"${rgbWithSpaces}\"]`)),\n ).toBeVisible();\n await page\n .locator(`path[fill=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`fill[stroke=\"${rgbWithSpaces}\"]`))\n .hover();\n const tooltip = page.getByText(`${seriesName}formatted ${value}`);\n await expect(tooltip).toBeVisible();\n};\n\n/**\n * Scatter points are rings, so the series color is the stroke. The fill is the\n * theme surface color until hover paints it.\n */\nexport const scatterPointLocator = (page: Page, rgbSeriesColor: string) => {\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n\n return page\n .locator(`path[stroke=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[stroke=\"${rgbWithSpaces}\"]`));\n};\n\nexport const expectScatterTooltipToBeVisible = async (\n page: Page,\n tooltipTitle: string,\n // oxlint-disable-next-line id-length\n x: number,\n // oxlint-disable-next-line id-length\n y: number,\n rgbSeriesColor: string,\n) => {\n const chartElement = scatterPointLocator(page, rgbSeriesColor);\n\n await expect(chartElement).toBeVisible();\n await chartElement.hover();\n\n // Scatter uses an item tooltip: encode.tooltip titles it, then the axis-named\n // x and y rows follow.\n const tooltip = page.locator('.ndl-charts-chart-tooltip');\n await expect(tooltip).toContainText(tooltipTitle);\n await expect(tooltip).not.toContainText('row-id');\n await expect(tooltip).toContainText(`Duration`);\n await expect(tooltip).toContainText(`formatted ${x}`);\n await expect(tooltip).toContainText(`Latency`);\n await expect(tooltip).toContainText(`formatted ${y}`);\n\n // The point color belongs to the title row only, so the rows below it do not\n // repeat the swatch.\n await expect(\n tooltip.locator('.ndl-charts-chart-tooltip-title-indent-square'),\n ).toHaveCount(1);\n await expect(\n tooltip.locator('.ndl-charts-chart-tooltip-content-indent-square'),\n ).toHaveCount(0);\n};\n\nexport const expectDefaultFormattedTooltipToBeVisible = async (\n page: Page,\n seriesName: string,\n value: number,\n rgbSeriesColor: string,\n) => {\n const rgbWithSpaces = rgbSeriesColor.replace(/,/g, ', ');\n\n const chartElement = page\n .locator(`path[fill=\"${rgbSeriesColor}\"]`)\n .or(page.locator(`path[fill=\"${rgbWithSpaces}\"]`));\n\n await expect(chartElement).toBeVisible();\n await chartElement.hover();\n\n const tooltip = page.locator('.ndl-charts-chart-tooltip');\n await expect(tooltip).toContainText(seriesName);\n await expect(tooltip).toContainText(\n new Intl.NumberFormat('en-US').format(value),\n );\n};\n\nexport const waitForAnimationEnd = (page: Page, selector: string) => {\n return page\n .locator(selector)\n .evaluate((element) =>\n Promise.all(\n element.getAnimations().map((animation) => animation.finished),\n ),\n );\n};\n"]}
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
20
|
*/
|
|
21
21
|
import { generateThresholdAriaDescription } from './aria-description';
|
|
22
|
-
import { createAxisTooltipFormatter } from './chart-tooltip-formatter';
|
|
22
|
+
import { createAxisTooltipFormatter, createScatterTooltipFormatter, } from './chart-tooltip-formatter';
|
|
23
|
+
import { tooltipExtraCssText } from './defaults';
|
|
23
24
|
import { isVerticalSlider, mergeToolbox } from './user-option-utils';
|
|
24
25
|
const SLIDER_OUTER_BOUND_GAP = 8;
|
|
25
26
|
const SLIDER_OUTER_BOUND_FALLBACK = 60;
|
|
@@ -102,6 +103,16 @@ export function getSliderRightOuterBound(dataZoom) {
|
|
|
102
103
|
export const hasMarkAreaInSeries = (series) => Array.isArray(series)
|
|
103
104
|
? series.some((option) => !!option.markArea)
|
|
104
105
|
: !!series.markArea;
|
|
106
|
+
/**
|
|
107
|
+
* Reads the `name` of the axis at `axisIndex`, which scatter tooltips use to
|
|
108
|
+
* label their x and y rows.
|
|
109
|
+
*/
|
|
110
|
+
function getAxisName(axis, axisIndex = 0) {
|
|
111
|
+
const axisOption = (Array.isArray(axis) ? axis[axisIndex] : axisIndex === 0 ? axis : undefined);
|
|
112
|
+
return typeof (axisOption === null || axisOption === void 0 ? void 0 : axisOption.name) === 'string' && axisOption.name.length > 0
|
|
113
|
+
? axisOption.name
|
|
114
|
+
: undefined;
|
|
115
|
+
}
|
|
105
116
|
/**
|
|
106
117
|
* Category x-axes use slightly wider grid padding to avoid clipped labels.
|
|
107
118
|
*/
|
|
@@ -114,7 +125,7 @@ export function hasCategoryXAxis(xAxis) {
|
|
|
114
125
|
* Builds the ECharts option object from Needle chart props and derived values.
|
|
115
126
|
* Applying the option to an ECharts instance happens in `useChartOption`.
|
|
116
127
|
*/
|
|
117
|
-
export function buildChartOption({ dataZoom, dataset, hasCategoryXAxis, legendSelected, propsSeries, series, thresholdLines, toolboxOptions, userOption, xAxis, yAxis, hasMarkArea, }) {
|
|
128
|
+
export function buildChartOption({ dataZoom, dataset, getChartInstance, getLegendSelected, hasCategoryXAxis, legendSelected, propsSeries, series, thresholdLines, toolboxOptions, userOption, xAxis, yAxis, hasMarkArea, }) {
|
|
118
129
|
const customAriaDescription = generateThresholdAriaDescription(propsSeries, dataset);
|
|
119
130
|
const sliderBottomOuterBound = getSliderBottomOuterBound(dataZoom);
|
|
120
131
|
const sliderRightOuterBound = getSliderRightOuterBound(dataZoom);
|
|
@@ -122,6 +133,18 @@ export function buildChartOption({ dataZoom, dataset, hasCategoryXAxis, legendSe
|
|
|
122
133
|
const gridHorizontalInset = hasCategoryXAxis ? 15 : 10;
|
|
123
134
|
const gridRight = hasVerticalSliderZoom(dataZoom) ? 60 : gridHorizontalInset;
|
|
124
135
|
const gridTop = hasMarkArea ? 20 : 10;
|
|
136
|
+
const seriesList = Array.isArray(series) ? series : [series];
|
|
137
|
+
const isScatterChart = seriesList.length > 0 &&
|
|
138
|
+
seriesList.every((seriesOption) => seriesOption.type === 'scatter');
|
|
139
|
+
const seriesAxisNames = seriesList.map((seriesOption) => {
|
|
140
|
+
const { xAxisIndex, yAxisIndex } = seriesOption;
|
|
141
|
+
return {
|
|
142
|
+
// oxlint-disable-next-line id-length
|
|
143
|
+
x: getAxisName(xAxis, xAxisIndex),
|
|
144
|
+
// oxlint-disable-next-line id-length
|
|
145
|
+
y: getAxisName(yAxis, yAxisIndex),
|
|
146
|
+
};
|
|
147
|
+
});
|
|
125
148
|
return Object.assign(Object.assign({}, userOption), { aria: Object.assign(Object.assign({ decal: {
|
|
126
149
|
show: false,
|
|
127
150
|
}, enabled: true }, (customAriaDescription !== undefined && {
|
|
@@ -141,10 +164,22 @@ export function buildChartOption({ dataZoom, dataset, hasCategoryXAxis, legendSe
|
|
|
141
164
|
borderRadius: 0,
|
|
142
165
|
borderWidth: 0,
|
|
143
166
|
confine: true,
|
|
144
|
-
extraCssText:
|
|
145
|
-
formatter:
|
|
167
|
+
extraCssText: tooltipExtraCssText,
|
|
168
|
+
formatter: isScatterChart
|
|
169
|
+
? createScatterTooltipFormatter({
|
|
170
|
+
dataset,
|
|
171
|
+
getChartInstance,
|
|
172
|
+
getLegendSelected,
|
|
173
|
+
series,
|
|
174
|
+
seriesAxisNames,
|
|
175
|
+
userOption,
|
|
176
|
+
})
|
|
177
|
+
: createAxisTooltipFormatter({ thresholdLines, userOption }),
|
|
146
178
|
padding: 0,
|
|
147
|
-
trigger
|
|
179
|
+
// Scatter needs item trigger so the unique per-point `encode.tooltip`
|
|
180
|
+
// value can title the tooltip. Axis trigger would group every point
|
|
181
|
+
// that shares an x (or y) value.
|
|
182
|
+
trigger: isScatterChart ? 'item' : 'axis',
|
|
148
183
|
}, xAxis,
|
|
149
184
|
yAxis });
|
|
150
185
|
}
|