@neo4j-ndl/react 3.0.27 → 3.0.29

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.
Files changed (76) hide show
  1. package/lib/cjs/index.js +0 -1
  2. package/lib/cjs/index.js.map +1 -1
  3. package/lib/esm/index.js +0 -1
  4. package/lib/esm/index.js.map +1 -1
  5. package/lib/types/index.d.ts +0 -1
  6. package/package.json +2 -6
  7. package/lib/cjs/charts/CartesianGrid.js +0 -107
  8. package/lib/cjs/charts/CartesianGrid.js.map +0 -1
  9. package/lib/cjs/charts/Chart.js +0 -761
  10. package/lib/cjs/charts/Chart.js.map +0 -1
  11. package/lib/cjs/charts/ChartTooltip.js +0 -60
  12. package/lib/cjs/charts/ChartTooltip.js.map +0 -1
  13. package/lib/cjs/charts/Charts.js +0 -124
  14. package/lib/cjs/charts/Charts.js.map +0 -1
  15. package/lib/cjs/charts/Dot.js +0 -31
  16. package/lib/cjs/charts/Dot.js.map +0 -1
  17. package/lib/cjs/charts/HollowDot.js +0 -54
  18. package/lib/cjs/charts/HollowDot.js.map +0 -1
  19. package/lib/cjs/charts/Legend.js +0 -180
  20. package/lib/cjs/charts/Legend.js.map +0 -1
  21. package/lib/cjs/charts/Line.js +0 -132
  22. package/lib/cjs/charts/Line.js.map +0 -1
  23. package/lib/cjs/charts/axis/XAxis.js +0 -205
  24. package/lib/cjs/charts/axis/XAxis.js.map +0 -1
  25. package/lib/cjs/charts/axis/YAxis.js +0 -170
  26. package/lib/cjs/charts/axis/YAxis.js.map +0 -1
  27. package/lib/cjs/charts/axis/chart-axis-utils.js +0 -42
  28. package/lib/cjs/charts/axis/chart-axis-utils.js.map +0 -1
  29. package/lib/cjs/charts/axis/chart-tick-generation.js +0 -245
  30. package/lib/cjs/charts/axis/chart-tick-generation.js.map +0 -1
  31. package/lib/cjs/charts/index.js +0 -38
  32. package/lib/cjs/charts/index.js.map +0 -1
  33. package/lib/cjs/charts/utils.js +0 -40
  34. package/lib/cjs/charts/utils.js.map +0 -1
  35. package/lib/esm/charts/CartesianGrid.js +0 -100
  36. package/lib/esm/charts/CartesianGrid.js.map +0 -1
  37. package/lib/esm/charts/Chart.js +0 -734
  38. package/lib/esm/charts/Chart.js.map +0 -1
  39. package/lib/esm/charts/ChartTooltip.js +0 -54
  40. package/lib/esm/charts/ChartTooltip.js.map +0 -1
  41. package/lib/esm/charts/Charts.js +0 -121
  42. package/lib/esm/charts/Charts.js.map +0 -1
  43. package/lib/esm/charts/Dot.js +0 -28
  44. package/lib/esm/charts/Dot.js.map +0 -1
  45. package/lib/esm/charts/HollowDot.js +0 -28
  46. package/lib/esm/charts/HollowDot.js.map +0 -1
  47. package/lib/esm/charts/Legend.js +0 -174
  48. package/lib/esm/charts/Legend.js.map +0 -1
  49. package/lib/esm/charts/Line.js +0 -106
  50. package/lib/esm/charts/Line.js.map +0 -1
  51. package/lib/esm/charts/axis/XAxis.js +0 -176
  52. package/lib/esm/charts/axis/XAxis.js.map +0 -1
  53. package/lib/esm/charts/axis/YAxis.js +0 -164
  54. package/lib/esm/charts/axis/YAxis.js.map +0 -1
  55. package/lib/esm/charts/axis/chart-axis-utils.js +0 -38
  56. package/lib/esm/charts/axis/chart-axis-utils.js.map +0 -1
  57. package/lib/esm/charts/axis/chart-tick-generation.js +0 -217
  58. package/lib/esm/charts/axis/chart-tick-generation.js.map +0 -1
  59. package/lib/esm/charts/index.js +0 -22
  60. package/lib/esm/charts/index.js.map +0 -1
  61. package/lib/esm/charts/utils.js +0 -37
  62. package/lib/esm/charts/utils.js.map +0 -1
  63. package/lib/types/charts/CartesianGrid.d.ts +0 -32
  64. package/lib/types/charts/Chart.d.ts +0 -109
  65. package/lib/types/charts/ChartTooltip.d.ts +0 -69
  66. package/lib/types/charts/Charts.d.ts +0 -104
  67. package/lib/types/charts/Dot.d.ts +0 -27
  68. package/lib/types/charts/HollowDot.d.ts +0 -28
  69. package/lib/types/charts/Legend.d.ts +0 -25
  70. package/lib/types/charts/Line.d.ts +0 -44
  71. package/lib/types/charts/axis/XAxis.d.ts +0 -28
  72. package/lib/types/charts/axis/YAxis.d.ts +0 -28
  73. package/lib/types/charts/axis/chart-axis-utils.d.ts +0 -33
  74. package/lib/types/charts/axis/chart-tick-generation.d.ts +0 -33
  75. package/lib/types/charts/index.d.ts +0 -21
  76. package/lib/types/charts/utils.d.ts +0 -23
@@ -1,734 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- /**
3
- *
4
- * Copyright (c) "Neo4j"
5
- * Neo4j Sweden AB [http://neo4j.com]
6
- *
7
- * This file is part of Neo4j.
8
- *
9
- * Neo4j is free software: you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation, either version 3 of the License, or
12
- * (at your option) any later version.
13
- *
14
- * This program is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
21
- */
22
- import React, { forwardRef, useEffect, useState, useContext, createContext, useImperativeHandle, useRef, Children, isValidElement, useMemo, } from 'react';
23
- import * as d3 from 'd3';
24
- import { ChartsContext, } from './Charts';
25
- import { classNames } from '../_common/defaultImports';
26
- import { Line } from './Line';
27
- import { Dot } from './Dot';
28
- import { line } from 'd3-shape';
29
- import { ChartTooltip } from './ChartTooltip';
30
- import { useDebounceCallback, useResizeObserver } from 'usehooks-ts';
31
- import { useThrottle } from './utils';
32
- // Used to visualize the voronoi polygons.
33
- const SHOULD_SHOW_VORONOI_DEBUG = false;
34
- // Used to throttle calls to on mouse move over the polygons.
35
- const THROTTLE_MOUSE_MOVE_MILLISECONDS = 100;
36
- const defaultChartProps = {
37
- scales: {},
38
- pointSelectionType: 'single',
39
- };
40
- export const canvasLeftPadding = 0;
41
- export const canvasRightPadding = 0;
42
- // eslint-disable-next-line no-redeclare
43
- export const ChartsChartContext = createContext({
44
- chartRef: null,
45
- contentRef: null,
46
- contentSize: undefined,
47
- scales: {},
48
- linePointArray: [],
49
- mousePositionRef: undefined,
50
- });
51
- export function getPointPixels(linePoint, scales) {
52
- const { accessorXAxis, scaleXAxisId } = linePoint;
53
- const { accessorYAxis, scaleYAxisId } = linePoint;
54
- const valueX = linePoint[accessorXAxis];
55
- const valueY = linePoint[accessorYAxis];
56
- const scaleXAxisObject = scales[scaleXAxisId];
57
- const scaleYAxisObject = scales[scaleYAxisId];
58
- const scaleXAxis = scaleXAxisObject.functionWithContentWidthAsRange;
59
- const scaleYAxis = scaleYAxisObject.functionWithContentHeightAsRange;
60
- const pointPixelX = scaleXAxis(valueX);
61
- const pointPixelY = scaleYAxis(valueY);
62
- return { pointPixelX, pointPixelY };
63
- }
64
- function dotsPropsAreEqual(prevProps, nextProps) {
65
- const isEqual = JSON.stringify(prevProps.selectedPoints) ==
66
- JSON.stringify(nextProps.selectedPoints) &&
67
- JSON.stringify(prevProps.metadata) == JSON.stringify(nextProps.metadata);
68
- return isEqual;
69
- }
70
- const DotsMemoized = React.memo(function Dots({ selectedPoints, metadata, scales, }) {
71
- console.info('DotsMemoized >> render');
72
- return (_jsx(_Fragment, { children: selectedPoints.map((linePoint) => {
73
- const { key, dataId } = linePoint;
74
- const { pointPixelX, pointPixelY } = getPointPixels(linePoint, scales);
75
- const { isVisible, color } = metadata[dataId];
76
- if (!isVisible)
77
- return null;
78
- return (_jsx(Dot, { x: pointPixelX, y: pointPixelY, color: color }, `chart-dot-${key}`));
79
- }) }));
80
- }, dotsPropsAreEqual);
81
- function tooltipPropsAreEqual(prevProps, nextProps) {
82
- var _a, _b, _c, _d;
83
- console.info(prevProps, nextProps);
84
- if (prevProps.isOpen !== nextProps.isOpen)
85
- return false;
86
- if (((_a = prevProps.anchorPosition) === null || _a === void 0 ? void 0 : _a.x) !== ((_b = nextProps.anchorPosition) === null || _b === void 0 ? void 0 : _b.x))
87
- return false;
88
- if (((_c = prevProps.anchorPosition) === null || _c === void 0 ? void 0 : _c.y) !== ((_d = nextProps.anchorPosition) === null || _d === void 0 ? void 0 : _d.y))
89
- return false;
90
- const isEqual = JSON.stringify(prevProps.selectedPoints) ==
91
- JSON.stringify(nextProps.selectedPoints) &&
92
- JSON.stringify(prevProps.metadata) == JSON.stringify(nextProps.metadata);
93
- return isEqual;
94
- }
95
- const TooltipMemoized = React.memo(function Tooltip({ selectedPoints, metadata, anchorPosition, isOpen, }) {
96
- var _a, _b, _c;
97
- return (_jsxs(ChartTooltip, { anchorPosition: anchorPosition, isOpen: isOpen, children: [_jsx(ChartTooltip.Title, { children: String((_c = (_a = selectedPoints === null || selectedPoints === void 0 ? void 0 : selectedPoints[0]) === null || _a === void 0 ? void 0 : _a[(_b = selectedPoints === null || selectedPoints === void 0 ? void 0 : selectedPoints[0]) === null || _b === void 0 ? void 0 : _b.accessorXAxis]) !== null && _c !== void 0 ? _c : '') }), selectedPoints.map((linePoint) => {
98
- var _a;
99
- if (linePoint === undefined)
100
- return null;
101
- if (metadata[linePoint.dataId].isVisible === false)
102
- return null;
103
- const { key, dataId, accessorYAxis } = linePoint;
104
- const contentKey = `chart-tooltip-content-${key}`;
105
- console.info(contentKey);
106
- return (_jsx(ChartTooltip.Content, { leftElement: metadata[dataId].label, rightElement: ((_a = linePoint[accessorYAxis]) === null || _a === void 0 ? void 0 : _a.toString()) || '', indentSquareColor: metadata[dataId].color }, contentKey));
107
- })] }));
108
- }, tooltipPropsAreEqual);
109
- const ChartComponent = forwardRef(function ChartComponent({ children, className, scales: scalesProp = defaultChartProps.scales, pointSelectionType = defaultChartProps.pointSelectionType, }, ref) {
110
- ////////////////////////////////////////////////////////////////////////////////////////////////////
111
- ////////////////////////////////////////////////////////////////////////////////////////////////////
112
- ////////////////////////////////////////////////////////////////////////////////////////////////////
113
- console.info('ChartComponent');
114
- const chartsContextValue = useContext(ChartsContext);
115
- const { data, metadata } = chartsContextValue;
116
- const chartRef = useRef(null);
117
- const contentRef = useRef(null);
118
- const horizontalIntersectionLineRef = useRef(null);
119
- const mousePositionRef = useRef({ x: 0, y: 0 });
120
- const [draggingPosition, setDraggingPosition] = useState(undefined);
121
- const [isMouseDown, setIsMouseDown] = useState(false);
122
- const [hasLines, setHasLines] = useState(false);
123
- const [contentSize, setContentSize] = useState(undefined);
124
- // The svg paths calculated for the voronoi polygons, includes
125
- // the assigned line point for the section for the onHover event.
126
- const [voronoiPolygons, setVoronoiPolygons] = useState();
127
- const [tooltipAnchorPosition, setTooltipAnchorPosition] = useState({
128
- x: 0,
129
- y: 0,
130
- });
131
- // The points that will display a thumb and be included in the tooltip.
132
- const [selectedPoints, setSelectedPoints] = useState(null);
133
- ////////////////////////////////////////////////////////////////////////////////////////////////////
134
- ////////////////////////////////////////////////////////////////////////////////////////////////////
135
- ////////////////////////////////////////////////////////////////////////////////////////////////////
136
- const initialScales = useMemo(() => {
137
- // Map the string scales to actual d3 function scales.
138
- // Will only re-run if the scalesProp changes.
139
- const initialScales = {};
140
- Object.entries(scalesProp).forEach(([key, value]) => {
141
- switch (value.type) {
142
- case 'linear':
143
- initialScales[key] = {
144
- originalDomain: null,
145
- functionWithContentWidthAsRange: d3.scaleLinear(),
146
- functionWithContentHeightAsRange: d3.scaleLinear(),
147
- function: d3.scaleLinear(),
148
- };
149
- break;
150
- case 'log':
151
- initialScales[key] = {
152
- originalDomain: null,
153
- functionWithContentWidthAsRange: d3.scaleLog(),
154
- functionWithContentHeightAsRange: d3.scaleLog(),
155
- function: d3.scaleLog(),
156
- };
157
- break;
158
- case 'time':
159
- initialScales[key] = {
160
- originalDomain: null,
161
- functionWithContentWidthAsRange: d3.scaleTime(),
162
- functionWithContentHeightAsRange: d3.scaleTime(),
163
- function: d3.scaleTime(),
164
- };
165
- break;
166
- case 'utc':
167
- initialScales[key] = {
168
- originalDomain: null,
169
- functionWithContentWidthAsRange: d3.scaleUtc(),
170
- functionWithContentHeightAsRange: d3.scaleUtc(),
171
- function: d3.scaleUtc(),
172
- };
173
- break;
174
- default:
175
- console.error('Invalid scale type');
176
- break;
177
- }
178
- });
179
- return initialScales;
180
- }, [scalesProp]);
181
- const [scales, setScales] = useState(initialScales);
182
- const voronoiScale = useMemo(() => {
183
- const initialVoronoiScale = {
184
- originalDomain: null,
185
- functionWithContentWidthAsRange: d3.scaleLinear(),
186
- functionWithContentHeightAsRange: d3.scaleLinear(),
187
- function: d3.scaleLinear(),
188
- };
189
- return initialVoronoiScale;
190
- }, []);
191
- useEffect(() => {
192
- // Needs to run after first render to determine size of content container.
193
- if (!contentRef.current)
194
- return;
195
- const contentElement = contentRef.current;
196
- requestAnimationFrame(() => {
197
- if (contentElement && contentElement.getBoundingClientRect) {
198
- const newContentSize = {
199
- width: contentElement.getBoundingClientRect().width,
200
- height: contentElement.getBoundingClientRect().height,
201
- };
202
- // Will force a re-render, calculations require
203
- // width and height of the content container.
204
- setContentSize(newContentSize);
205
- }
206
- });
207
- }, [contentRef]);
208
- const onResize = useDebounceCallback(() => {
209
- requestAnimationFrame(() => {
210
- const contentElement = contentRef.current;
211
- if (!contentElement)
212
- return;
213
- const rect = contentElement.getBoundingClientRect();
214
- if (!rect)
215
- return;
216
- const newContentSize = {
217
- width: rect.width - canvasLeftPadding - canvasRightPadding,
218
- height: rect.height,
219
- };
220
- setContentSize(newContentSize);
221
- });
222
- }, 100);
223
- useResizeObserver({
224
- ref: chartRef,
225
- onResize: onResize,
226
- });
227
- useImperativeHandle(ref, () => {
228
- const svgChart = chartRef.current;
229
- if (!svgChart) {
230
- return null;
231
- }
232
- return svgChart;
233
- });
234
- // The initial line point array is the representation of the full data
235
- // that came into the component via the prop.
236
- // useMemo:initialLinePointArray
237
- const { initialLinePointArray, lineMap } = useMemo(() => {
238
- if (!data)
239
- return { initialLinePointArray: [], lineMap: {} };
240
- // This use effect is specific for Line components.
241
- // If there are no line components then we don't need to do anything.
242
- const arrayChildren = Children.toArray(children);
243
- const hasLines = arrayChildren.some((child) => isValidElement(child) && child.type === Line);
244
- if (!hasLines)
245
- return;
246
- setHasLines(true);
247
- const lineMap = {};
248
- // Used by react for the key properties.
249
- let key = 0;
250
- // Here we are figuring out the min and max values for all the scales.
251
- // To do this we need to iterate through all of the lines and assign
252
- // each lines designated scale to a min max object specific for that scale.
253
- const newInitialLinePointArray = [];
254
- arrayChildren.forEach((child) => {
255
- // Per line.
256
- if (!isValidElement(child) || child.type !== Line)
257
- return;
258
- const { scaleXAxis: scaleXAxisId, scaleYAxis: scaleYAxisId, accessorXAxis: initialAccessorXAxis, accessorYAxis: initialAccessorYAxis, accessorHollowDot, dataId, seriesInterval, seriesIntervalStartValue, } = child.props;
259
- // Need to set these values for series type data.
260
- const accessorXAxis = seriesInterval
261
- ? 'xAxisValue'
262
- : initialAccessorXAxis;
263
- const accessorYAxis = seriesInterval
264
- ? 'yAxisValue'
265
- : initialAccessorYAxis;
266
- const lineDataIndex = data.findIndex((data) => data.id === dataId);
267
- const lineData = data[lineDataIndex];
268
- if (!lineData)
269
- return; // Id given does not exist in the data array.
270
- // Convert line data to d3 line data.
271
- let singleLinePointArray = [];
272
- if (seriesInterval && seriesIntervalStartValue) {
273
- // Series interval.
274
- const seriesLineData = lineData;
275
- singleLinePointArray = seriesLineData.data.map((dataPoint, index) => {
276
- const newLinePoint = {
277
- key,
278
- dataId,
279
- pointIndex: index,
280
- dataIndex: lineDataIndex,
281
- accessorXAxis,
282
- accessorYAxis,
283
- accessorHollowDot,
284
- xAxisValue: dataPoint !== undefined && dataPoint !== null
285
- ? seriesIntervalStartValue + seriesInterval * index
286
- : null,
287
- yAxisValue: dataPoint,
288
- scaleXAxisId,
289
- scaleYAxisId,
290
- selectionGroup: null,
291
- };
292
- return newLinePoint;
293
- });
294
- }
295
- else {
296
- // At least two dimensions are required for the line data.
297
- const nonSeriesData = lineData;
298
- singleLinePointArray = nonSeriesData.data.map((dataPointArray, index) => {
299
- const newLinePoint = {
300
- key,
301
- dataId,
302
- pointIndex: index,
303
- dataIndex: lineDataIndex,
304
- accessorXAxis,
305
- accessorYAxis,
306
- accessorHollowDot,
307
- scaleXAxisId,
308
- scaleYAxisId,
309
- selectionGroup: null,
310
- };
311
- dataPointArray.forEach((dataPoint, index) => {
312
- newLinePoint[nonSeriesData.metadata[index]] = dataPoint;
313
- });
314
- return newLinePoint;
315
- });
316
- }
317
- key += 1;
318
- // Add this single line to the array that holds all of the lines.
319
- newInitialLinePointArray.push(...singleLinePointArray);
320
- // Line map for easier access to points from the same line. No need
321
- // to iterate through the line point array.
322
- // console.info('setting lineMap', lineMap);
323
- lineMap[dataId] = singleLinePointArray;
324
- });
325
- const initialLinePointArray = newInitialLinePointArray;
326
- return { initialLinePointArray, lineMap };
327
- }, [data, children]) || {};
328
- useEffect(() => {
329
- var _a, _b;
330
- if (!contentRef.current)
331
- return;
332
- // Round the width and height to avoid floating point precision issues.
333
- const width = Math.round((_a = contentSize === null || contentSize === void 0 ? void 0 : contentSize.width) !== null && _a !== void 0 ? _a : 0);
334
- const height = Math.round((_b = contentSize === null || contentSize === void 0 ? void 0 : contentSize.height) !== null && _b !== void 0 ? _b : 0);
335
- if (width === 0 || height === 0)
336
- return;
337
- if (initialLinePointArray === undefined)
338
- return;
339
- // Need to reset the originalDomain for each scale.
340
- let newScales = {};
341
- Object.entries(scales).forEach(([key, scale]) => {
342
- newScales[key] = Object.assign(Object.assign({}, scale), { originalDomain: null });
343
- });
344
- initialLinePointArray.forEach((linePoint) => {
345
- var _a, _b;
346
- const { accessorXAxis, accessorYAxis, scaleXAxisId, scaleYAxisId } = linePoint;
347
- // Get min and max values for both x and y axis from the data point array.
348
- const minValueXAxis = d3.min(initialLinePointArray,
349
- // @ts-expect-error d3 types are not correct
350
- (linePoint) => linePoint[accessorXAxis]);
351
- const maxValueXAxis = d3.max(initialLinePointArray,
352
- // @ts-expect-error d3 types are not correct
353
- (linePoint) => linePoint[accessorXAxis]);
354
- const minValueYAxis = d3.min(initialLinePointArray,
355
- // @ts-expect-error d3 types are not correct
356
- (linePoint) => linePoint[accessorYAxis]);
357
- const maxValueYAxis = d3.max(initialLinePointArray,
358
- // @ts-expect-error d3 types are not correct
359
- (linePoint) => linePoint[accessorYAxis]);
360
- const scaleXAxis = newScales[scaleXAxisId];
361
- const scaleYAxis = newScales[scaleYAxisId];
362
- // Here we figure out the min and max values for the specific scale,
363
- // this compares previous lines min max values to the current lines
364
- // min max values on the same scale.
365
- let scaleXAxisMin = undefined;
366
- let scaleXAxisMax = undefined;
367
- let scaleYAxisMin = undefined;
368
- let scaleYAxisMax = undefined;
369
- if (scalesProp[scaleXAxisId].domain !== undefined) {
370
- // The domain value is set manually.
371
- scaleXAxisMin = scalesProp[scaleXAxisId].domain[0];
372
- scaleXAxisMax = scalesProp[scaleXAxisId].domain[1];
373
- }
374
- else if (scaleXAxis !== undefined &&
375
- (scaleXAxis === null || scaleXAxis === void 0 ? void 0 : scaleXAxis.originalDomain) !== null) {
376
- //@ts-expect-error d3 types are not correct - it can handle undefined
377
- scaleXAxisMin = d3.min([scaleXAxis.originalDomain[0], minValueXAxis]);
378
- //@ts-expect-error d3 types are not correct - it can handle undefined
379
- scaleXAxisMax = d3.max([scaleXAxis.originalDomain[1], maxValueXAxis]);
380
- }
381
- else {
382
- scaleXAxisMin = minValueXAxis;
383
- scaleXAxisMax = maxValueXAxis;
384
- }
385
- if (scalesProp[scaleYAxisId].domain !== undefined) {
386
- // The domain value is set manually.
387
- scaleYAxisMin = scalesProp[scaleYAxisId].domain[0];
388
- scaleYAxisMax = scalesProp[scaleYAxisId].domain[1];
389
- }
390
- else if (scaleYAxis !== undefined &&
391
- scaleXAxis.originalDomain !== null) {
392
- //@ts-expect-error d3 types are not correct - it can handle undefined
393
- scaleYAxisMin = d3.min([(_a = scaleYAxis.originalDomain) === null || _a === void 0 ? void 0 : _a[0], minValueYAxis]);
394
- //@ts-expect-error d3 types are not correct - it can handle undefined
395
- scaleYAxisMax = d3.max([(_b = scaleYAxis.originalDomain) === null || _b === void 0 ? void 0 : _b[1], maxValueYAxis]);
396
- }
397
- else {
398
- scaleYAxisMin = minValueYAxis;
399
- scaleYAxisMax = maxValueYAxis;
400
- }
401
- // D3 types are not correct it will be the same type as the original domain.
402
- // casting it to [number, number] to avoid type errors.
403
- const xValuesDomain = [scaleXAxisMin, scaleXAxisMax];
404
- // D3 types are not correct it will be the same type as the original domain.
405
- // casting it to [number, number] to avoid type errors.
406
- const yValuesDomain = [scaleYAxisMin, scaleYAxisMax];
407
- scaleXAxis.function.domain(xValuesDomain);
408
- scaleXAxis.originalDomain = xValuesDomain;
409
- scaleXAxis.functionWithContentWidthAsRange.domain(xValuesDomain);
410
- scaleXAxis.functionWithContentWidthAsRange.range([0, width !== null && width !== void 0 ? width : 0]);
411
- scaleXAxis.functionWithContentHeightAsRange.domain(xValuesDomain);
412
- scaleXAxis.functionWithContentHeightAsRange.range([height !== null && height !== void 0 ? height : 0, 0]);
413
- scaleYAxis.function.domain(yValuesDomain);
414
- scaleYAxis.originalDomain = yValuesDomain;
415
- scaleYAxis.functionWithContentWidthAsRange.domain(yValuesDomain);
416
- scaleYAxis.functionWithContentWidthAsRange.range([0, width !== null && width !== void 0 ? width : 0]);
417
- scaleYAxis.functionWithContentHeightAsRange.domain(yValuesDomain);
418
- scaleYAxis.functionWithContentHeightAsRange.range([height !== null && height !== void 0 ? height : 0, 0]); // inverting vertical scale since SVG has 0,0 at top left.
419
- // Update the specific scale.
420
- newScales = Object.assign(Object.assign({}, newScales), { [scaleXAxisId]: scaleXAxis, [scaleYAxisId]: scaleYAxis });
421
- });
422
- voronoiScale.function.domain([0, width !== null && width !== void 0 ? width : 0]);
423
- voronoiScale.originalDomain = [0, width !== null && width !== void 0 ? width : 0];
424
- voronoiScale.functionWithContentWidthAsRange.domain([0, width !== null && width !== void 0 ? width : 0]);
425
- voronoiScale.functionWithContentWidthAsRange.range([0, width !== null && width !== void 0 ? width : 0]);
426
- setScales(newScales);
427
- }, [contentSize, scalesProp, children, initialLinePointArray]);
428
- const { linePointArray, pointSelectionGroups } = useMemo(() => {
429
- if (initialLinePointArray === undefined)
430
- return {};
431
- // The following is only used for pointSelectionType x-axis and y-axis
432
- const pointSelectionGroups = {};
433
- const linePointArray = initialLinePointArray.map((linePoint) => {
434
- const { pointPixelX, pointPixelY } = getPointPixels(linePoint, scales);
435
- const pointPixelAxis = pointSelectionType === 'x-axis' || pointSelectionType === 'single'
436
- ? pointPixelX
437
- : pointPixelY;
438
- if (pointPixelAxis === undefined)
439
- return linePoint;
440
- linePoint.selectionGroup = pointPixelAxis;
441
- if (!pointSelectionGroups[pointPixelAxis]) {
442
- pointSelectionGroups[pointPixelAxis] = [];
443
- pointSelectionGroups[pointPixelAxis].push(linePoint);
444
- }
445
- else {
446
- // Pixel point already exists.
447
- pointSelectionGroups[pointPixelAxis].push(linePoint);
448
- }
449
- return linePoint;
450
- });
451
- return { linePointArray, pointSelectionGroups };
452
- }, [pointSelectionType, initialLinePointArray, scales]);
453
- const voronoiPolygonPointsArray = useMemo(() => {
454
- const width = contentSize === null || contentSize === void 0 ? void 0 : contentSize.width;
455
- const height = contentSize === null || contentSize === void 0 ? void 0 : contentSize.height;
456
- if (!width || !height)
457
- return;
458
- if (lineMap === undefined)
459
- return;
460
- if (linePointArray === undefined)
461
- return;
462
- const visibleLinePointArray = linePointArray.filter((linePoint) => {
463
- return metadata[linePoint.dataId].isVisible;
464
- });
465
- const delaunay = d3.Delaunay.from(visibleLinePointArray,
466
- // @ts-expect-error - d3 types are not correct, it can handle null being returned.
467
- (linePoint) => {
468
- const { accessorXAxis, scaleXAxisId } = linePoint;
469
- const valueX = linePoint[accessorXAxis];
470
- const scaleXAxisObject = scales[scaleXAxisId];
471
- const scaleXAxis = scaleXAxisObject.functionWithContentWidthAsRange;
472
- const scaleXAxisCopy = scaleXAxis.copy();
473
- scaleXAxisCopy.domain(scaleXAxisObject.originalDomain);
474
- const pointPixelX = scaleXAxisCopy(valueX);
475
- // We must return null otherwise some points won't work with voronoi/tooltips.
476
- return pointPixelX === undefined ? null : pointPixelX;
477
- }, (linePoint) => {
478
- const { accessorYAxis, scaleYAxisId } = linePoint;
479
- const valueY = linePoint[accessorYAxis];
480
- const scaleYAxisObject = scales[scaleYAxisId];
481
- const scaleYAxis = scaleYAxisObject.functionWithContentHeightAsRange;
482
- const scaleYAxisCopy = scaleYAxis.copy();
483
- scaleYAxisCopy.domain(scaleYAxisObject.originalDomain);
484
- const pointPixelY = scaleYAxis(valueY);
485
- // We must return null otherwise some points won't work with voronoi/tooltips.
486
- return pointPixelY === undefined ? null : pointPixelY;
487
- });
488
- const voronoi = delaunay.voronoi([0, 0, width, height]);
489
- const voronoiPolygons = voronoi.cellPolygons();
490
- const voronoiPolygonPointsArray = Array.from(voronoiPolygons);
491
- return voronoiPolygonPointsArray;
492
- }, [metadata, linePointArray]);
493
- useEffect(() => {
494
- if (isMouseDown)
495
- return;
496
- if (voronoiPolygonPointsArray === undefined)
497
- return;
498
- if (linePointArray === undefined)
499
- return;
500
- const visibleLinePointArray = linePointArray.filter((linePoint) => {
501
- return metadata[linePoint.dataId].isVisible;
502
- });
503
- const delaunayLineFn = line();
504
- const newVoronoiPolygons = voronoiPolygonPointsArray.map((voronoiPolygonPoints) => {
505
- const newVoronoiPolygonPoints = voronoiPolygonPoints.map((voronoiPolygonPoint) => {
506
- const [x, y] = voronoiPolygonPoint;
507
- const scale = voronoiScale.functionWithContentWidthAsRange;
508
- const newX = scale(x);
509
- const newVoronoiPolygonPoint = [newX, y];
510
- return newVoronoiPolygonPoint;
511
- });
512
- newVoronoiPolygonPoints.index = voronoiPolygonPoints.index;
513
- const { index } = newVoronoiPolygonPoints;
514
- const path = delaunayLineFn(newVoronoiPolygonPoints);
515
- const linePoint = visibleLinePointArray[index];
516
- const voronoiIndex = index;
517
- return {
518
- path,
519
- linePoint,
520
- voronoiIndex,
521
- };
522
- });
523
- setVoronoiPolygons(newVoronoiPolygons);
524
- }, [voronoiPolygonPointsArray, linePointArray, scales, isMouseDown]);
525
- const handleMouseMove = (event, voronoiPolygon) => {
526
- var _a;
527
- const { linePoint } = voronoiPolygon;
528
- const [xm, ym] = d3.pointer(event, contentRef.current);
529
- const mousePixelX = xm;
530
- const mousePixelY = ym;
531
- mousePositionRef.current.x = mousePixelX;
532
- mousePositionRef.current.y = mousePixelY;
533
- // Zooming
534
- if (isMouseDown) {
535
- // We care about zooming when dragging because we want to fill space
536
- // showing what is being selected.
537
- const newDraggingPosition = Object.assign(Object.assign({}, draggingPosition), { endX: mousePixelX });
538
- setDraggingPosition(newDraggingPosition);
539
- return;
540
- }
541
- const { pointPixelX, pointPixelY } = getPointPixels(linePoint, scales);
542
- if (pointPixelX === undefined || pointPixelY === undefined)
543
- return;
544
- const distance = Math.hypot(pointPixelX - mousePixelX, pointPixelY - mousePixelY);
545
- const radius = 32;
546
- const shouldTrigger = distance < radius && pointSelectionGroups !== undefined;
547
- if (shouldTrigger) {
548
- const selectionGroup = linePoint.selectionGroup;
549
- const hasSelectionGroup = selectionGroup !== null;
550
- if (!hasSelectionGroup) {
551
- console.warn('No selection group for point');
552
- return;
553
- }
554
- const newSelectedPoints = pointSelectionGroups[selectionGroup];
555
- const isNewSelectedPoints = newSelectedPoints !== selectedPoints;
556
- if (isNewSelectedPoints) {
557
- //selectedPointRef.current = { dataId, pointIndex };
558
- const svgRect = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
559
- if (svgRect) {
560
- setTooltipAnchorPosition({
561
- x: svgRect.left + pointPixelX,
562
- y: svgRect.top + pointPixelY,
563
- });
564
- }
565
- setSelectedPoints(newSelectedPoints);
566
- }
567
- }
568
- else if (selectedPoints !== null && selectedPoints.length > 0) {
569
- setSelectedPoints(null);
570
- }
571
- };
572
- const throttledHandleMouseMove = useThrottle(handleMouseMove, THROTTLE_MOUSE_MOVE_MILLISECONDS);
573
- const handleMouseLeave = () => {
574
- if (isMouseDown) {
575
- return;
576
- }
577
- setIsMouseDown(false);
578
- setDraggingPosition(undefined);
579
- // Mouse moves outside of the content area.
580
- if (selectedPoints !== null && selectedPoints.length > 0)
581
- setSelectedPoints(null);
582
- };
583
- const handleMouseDown = (event) => {
584
- const amountOfMouseClicks = event.detail;
585
- const isDoubleClick = amountOfMouseClicks === 2;
586
- if (isDoubleClick &&
587
- contentSize !== undefined &&
588
- contentSize.width !== undefined) {
589
- // If zoomed in, return to the original view.
590
- Object.entries(scales).forEach(([scaleId, scale]) => {
591
- if (scale.originalDomain === null)
592
- return;
593
- const newScale = Object.assign({}, scale);
594
- newScale.function.domain(scale.originalDomain);
595
- newScale.functionWithContentWidthAsRange.domain(scale.originalDomain);
596
- scales[scaleId] = newScale;
597
- });
598
- voronoiScale.function.domain([0, contentSize.width]);
599
- voronoiScale.functionWithContentWidthAsRange.domain([
600
- 0,
601
- contentSize.width,
602
- ]);
603
- }
604
- // Set start position for dragging.
605
- const [xm, ym] = d3.pointer(event, contentRef.current);
606
- const mousePixelX = xm;
607
- const mousePixelY = ym;
608
- mousePositionRef.current.x = mousePixelX;
609
- mousePositionRef.current.y = mousePixelY;
610
- // Initial dragging position.
611
- const newDraggingPosition = {
612
- startX: mousePixelX,
613
- endX: undefined,
614
- };
615
- // Needed for the dragging motion.
616
- setIsMouseDown(true);
617
- setDraggingPosition(newDraggingPosition);
618
- };
619
- // must attach mouse listener to window
620
- const handleMouseUp = () => {
621
- const [xm] = d3.pointer(event, contentRef.current);
622
- const mousePixelX = xm;
623
- if ((draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX) === mousePixelX) {
624
- // The user clicked on the same place, no zooming.
625
- setIsMouseDown(false);
626
- setDraggingPosition(undefined);
627
- return;
628
- }
629
- const leftX = (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX) > (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX)
630
- ? draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX
631
- : draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX;
632
- const rightX = (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX) > (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX)
633
- ? draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX
634
- : draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX;
635
- Object.entries(scales).forEach(([scaleId, scale]) => {
636
- const newScale = Object.assign({}, scale);
637
- newScale.function.domain([
638
- newScale.function.invert(leftX),
639
- newScale.function.invert(rightX),
640
- ]);
641
- newScale.functionWithContentWidthAsRange.domain([
642
- newScale.functionWithContentWidthAsRange.invert(leftX),
643
- newScale.functionWithContentWidthAsRange.invert(rightX),
644
- ]);
645
- scales[scaleId] = newScale;
646
- });
647
- // update voronoi scale
648
- voronoiScale.function.domain([
649
- voronoiScale.function.invert(leftX),
650
- voronoiScale.function.invert(rightX),
651
- ]);
652
- voronoiScale.functionWithContentWidthAsRange.domain([
653
- voronoiScale.functionWithContentWidthAsRange.invert(leftX),
654
- voronoiScale.functionWithContentWidthAsRange.invert(rightX),
655
- ]);
656
- setIsMouseDown(false);
657
- setDraggingPosition(undefined);
658
- };
659
- const isCanvasComponent = (child) => {
660
- return isValidElement(child) && child.type === Line;
661
- };
662
- const width = (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX) && (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX)
663
- ? draggingPosition.endX > draggingPosition.startX
664
- ? draggingPosition.endX - draggingPosition.startX
665
- : draggingPosition.startX - draggingPosition.endX
666
- : 1;
667
- const leftX = (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX) && (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX)
668
- ? (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX) > (draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX)
669
- ? draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.endX
670
- : draggingPosition === null || draggingPosition === void 0 ? void 0 : draggingPosition.startX
671
- : undefined;
672
- const shouldRenderDots = hasLines &&
673
- contentSize !== undefined &&
674
- selectedPoints !== null &&
675
- selectedPoints.length > 0 &&
676
- metadata !== undefined;
677
- const shouldRenderTooltip = hasLines &&
678
- contentSize !== undefined &&
679
- selectedPoints !== null &&
680
- selectedPoints.length > 0 &&
681
- metadata !== undefined;
682
- if (linePointArray === undefined)
683
- return null;
684
- const chartContextValue = {
685
- chartRef,
686
- contentRef,
687
- contentSize,
688
- scales,
689
- linePointArray,
690
- mousePositionRef,
691
- };
692
- const chartClasses = classNames(`ndl-charts-chart`, className);
693
- const contentClasses = classNames(`ndl-charts-chart-content`);
694
- const zoomingClasses = classNames(`ndl-charts-chart-zoom`);
695
- return (_jsx(ChartsChartContext.Provider, { value: chartContextValue, children: _jsxs("div", { ref: chartRef, className: chartClasses, onMouseLeave: handleMouseLeave, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, children: [_jsxs("svg", { ref: contentRef, className: contentClasses, children: [_jsxs("g", { children: [draggingPosition && contentSize && (
696
- // The zooming rectangle visualizing the selected area.
697
- _jsx("g", { children: _jsx("rect", { className: zoomingClasses, x: leftX, width: width, height: contentSize.height }) })), Children.toArray(children).map((child) => {
698
- return isCanvasComponent(child) ? child : null;
699
- }), hasLines &&
700
- contentSize &&
701
- selectedPoints &&
702
- selectedPoints.length > 0 && (
703
- // Dotted line for x-axis selection.
704
- _jsx("line", { ref: horizontalIntersectionLineRef, x1: getPointPixels(selectedPoints[0], scales).pointPixelX, x2: getPointPixels(selectedPoints[0], scales).pointPixelX, y1: "0", y2: contentSize.height, style: {
705
- strokeDasharray: '5,7',
706
- stroke: 'rgb(111, 117, 126)',
707
- } })), shouldRenderDots && (_jsx(DotsMemoized
708
- // Dots together with tooltip to be rendered
709
- , {
710
- // Dots together with tooltip to be rendered
711
- selectedPoints: selectedPoints, metadata: metadata, scales: scales }))] }), _jsx("g", { children: hasLines &&
712
- voronoiPolygons &&
713
- voronoiPolygons.map((voronoiPolygon, index) => {
714
- // Hover area for each line point.
715
- const { path } = voronoiPolygon;
716
- return (_jsx("path", { d: path, onMouseMove: (event) => {
717
- throttledHandleMouseMove(event, voronoiPolygon);
718
- }, style: {
719
- strokeWidth: 1,
720
- stroke: 'black',
721
- strokeOpacity: 0.5,
722
- fill: '#fff',
723
- opacity: SHOULD_SHOW_VORONOI_DEBUG ? 0.5 : 0,
724
- } }, index));
725
- }) })] }), _jsx(TooltipMemoized, { isOpen: shouldRenderTooltip, selectedPoints: selectedPoints !== null && selectedPoints !== void 0 ? selectedPoints : [], metadata: metadata, anchorPosition: tooltipAnchorPosition }), Children.toArray(children).map((child) => {
726
- return !isCanvasComponent(child) ? child : null;
727
- })] }) }));
728
- });
729
- // Issue with TypeScript forwardRef and subcomponents: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/34757#issuecomment-894053907
730
- const Chart = Object.assign(ChartComponent, {
731
- Line,
732
- });
733
- export { Chart };
734
- //# sourceMappingURL=Chart.js.map