@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.
Files changed (63) hide show
  1. package/lib/cjs/charts/ChartTooltip.js +6 -2
  2. package/lib/cjs/charts/ChartTooltip.js.map +1 -1
  3. package/lib/cjs/charts/hooks/use-chart-option.js +6 -0
  4. package/lib/cjs/charts/hooks/use-chart-option.js.map +1 -1
  5. package/lib/cjs/charts/hooks/use-legend-series.js +7 -1
  6. package/lib/cjs/charts/hooks/use-legend-series.js.map +1 -1
  7. package/lib/cjs/charts/index.js.map +1 -1
  8. package/lib/cjs/charts/tests/chart-test-utils.js +121 -1
  9. package/lib/cjs/charts/tests/chart-test-utils.js.map +1 -1
  10. package/lib/cjs/charts/utils/build-chart-option.js +39 -4
  11. package/lib/cjs/charts/utils/build-chart-option.js.map +1 -1
  12. package/lib/cjs/charts/utils/chart-tooltip-formatter.js +93 -0
  13. package/lib/cjs/charts/utils/chart-tooltip-formatter.js.map +1 -1
  14. package/lib/cjs/charts/utils/defaults.js +18 -1
  15. package/lib/cjs/charts/utils/defaults.js.map +1 -1
  16. package/lib/cjs/charts/utils/legend-utils.js +7 -2
  17. package/lib/cjs/charts/utils/legend-utils.js.map +1 -1
  18. package/lib/cjs/charts/utils/scatter-tooltip-points.js +301 -0
  19. package/lib/cjs/charts/utils/scatter-tooltip-points.js.map +1 -0
  20. package/lib/cjs/charts/utils/user-option-utils.js +16 -6
  21. package/lib/cjs/charts/utils/user-option-utils.js.map +1 -1
  22. package/lib/esm/charts/ChartTooltip.js +6 -2
  23. package/lib/esm/charts/ChartTooltip.js.map +1 -1
  24. package/lib/esm/charts/hooks/use-chart-option.js +6 -0
  25. package/lib/esm/charts/hooks/use-chart-option.js.map +1 -1
  26. package/lib/esm/charts/hooks/use-legend-series.js +7 -1
  27. package/lib/esm/charts/hooks/use-legend-series.js.map +1 -1
  28. package/lib/esm/charts/index.js.map +1 -1
  29. package/lib/esm/charts/tests/chart-test-utils.js +115 -0
  30. package/lib/esm/charts/tests/chart-test-utils.js.map +1 -1
  31. package/lib/esm/charts/utils/build-chart-option.js +40 -5
  32. package/lib/esm/charts/utils/build-chart-option.js.map +1 -1
  33. package/lib/esm/charts/utils/chart-tooltip-formatter.js +92 -0
  34. package/lib/esm/charts/utils/chart-tooltip-formatter.js.map +1 -1
  35. package/lib/esm/charts/utils/defaults.js +16 -1
  36. package/lib/esm/charts/utils/defaults.js.map +1 -1
  37. package/lib/esm/charts/utils/legend-utils.js +7 -2
  38. package/lib/esm/charts/utils/legend-utils.js.map +1 -1
  39. package/lib/esm/charts/utils/scatter-tooltip-points.js +291 -0
  40. package/lib/esm/charts/utils/scatter-tooltip-points.js.map +1 -0
  41. package/lib/esm/charts/utils/user-option-utils.js +17 -7
  42. package/lib/esm/charts/utils/user-option-utils.js.map +1 -1
  43. package/lib/types/charts/ChartTooltip.d.ts +6 -1
  44. package/lib/types/charts/ChartTooltip.d.ts.map +1 -1
  45. package/lib/types/charts/hooks/use-chart-option.d.ts.map +1 -1
  46. package/lib/types/charts/hooks/use-legend-series.d.ts.map +1 -1
  47. package/lib/types/charts/index.d.ts +1 -0
  48. package/lib/types/charts/index.d.ts.map +1 -1
  49. package/lib/types/charts/tests/chart-test-utils.d.ts +78 -0
  50. package/lib/types/charts/tests/chart-test-utils.d.ts.map +1 -1
  51. package/lib/types/charts/utils/build-chart-option.d.ts +4 -1
  52. package/lib/types/charts/utils/build-chart-option.d.ts.map +1 -1
  53. package/lib/types/charts/utils/chart-tooltip-formatter.d.ts +45 -2
  54. package/lib/types/charts/utils/chart-tooltip-formatter.d.ts.map +1 -1
  55. package/lib/types/charts/utils/defaults.d.ts +10 -1
  56. package/lib/types/charts/utils/defaults.d.ts.map +1 -1
  57. package/lib/types/charts/utils/legend-utils.d.ts.map +1 -1
  58. package/lib/types/charts/utils/scatter-tooltip-points.d.ts +84 -0
  59. package/lib/types/charts/utils/scatter-tooltip-points.d.ts.map +1 -0
  60. package/lib/types/charts/utils/user-option-utils.d.ts.map +1 -1
  61. package/package.json +3 -3
  62. package/skills/ndl-react-charts/SKILL.md +3 -3
  63. package/skills/ndl-react-charts/components/charts.md +279 -0
@@ -1853,6 +1853,285 @@ const Component = () => {
1853
1853
  export default Component;
1854
1854
  ```
1855
1855
 
1856
+ ### Scatter
1857
+
1858
+ ```tsx
1859
+ import { Chart, type TooltipValueContext } from '@neo4j-ndl/react-charts';
1860
+
1861
+ const Component = () => {
1862
+ return (
1863
+ // The Chart component requires its parent to have an explicit height.
1864
+ // Without one the chart canvas collapses to 0px and nothing renders.
1865
+ // You can also check the components documentation by hovering over it.
1866
+ <div
1867
+ style={{
1868
+ border: '1px solid silver',
1869
+ borderRadius: '10px',
1870
+ height: '350px',
1871
+ padding: '20px',
1872
+ width: '100%',
1873
+ }}
1874
+ >
1875
+ <Chart
1876
+ legend={{
1877
+ show: true,
1878
+ }}
1879
+ dataset={[
1880
+ {
1881
+ source: [
1882
+ ['x', 'y', 'label', 'id'],
1883
+ [10, 8.04, 'Checkout', 'A-1'],
1884
+ [8, 6.95, 'Search', 'A-2'],
1885
+ [13, 7.58, 'Catalog', 'A-3'],
1886
+ [9, 8.81, 'Cart', 'A-4'],
1887
+ [11, 8.33, 'Profile', 'A-5'],
1888
+ [14, 9.96, 'Recommendations', 'A-6'],
1889
+ [6, 7.24, 'Login', 'A-7'],
1890
+ [4, 4.26, 'Signup', 'A-8'],
1891
+ [12, 10.84, 'Billing', 'A-9'],
1892
+ [7, 4.82, 'Settings', 'A-10'],
1893
+ [5, 5.68, 'Support', 'A-11'],
1894
+ // Sits on top of A-9, so hovering there lists both points.
1895
+ [12.05, 10.8, 'Invoices', 'A-12'],
1896
+ // Shares A-2's coordinates exactly, which the tooltip lists as
1897
+ // two separate points.
1898
+ [8, 6.95, 'Search retry', 'A-13'],
1899
+ ],
1900
+ },
1901
+ {
1902
+ source: [
1903
+ ['x', 'y', 'label', 'id'],
1904
+ [12, 3.1, 'Cache miss', 'B-1'],
1905
+ [5, 9.13, 'Index scan', 'B-2'],
1906
+ [7, 7.26, 'Planner', 'B-3'],
1907
+ [11, 4.74, 'Page fault', 'B-4'],
1908
+ [3, 7.46, 'Lock wait', 'B-5'],
1909
+ [8, 6.77, 'Commit', 'B-6'],
1910
+ [14, 5.13, 'Replication', 'B-7'],
1911
+ [9, 8.14, 'Compaction', 'B-8'],
1912
+ [6, 6.08, 'Flush', 'B-9'],
1913
+ [10, 5.39, 'Checkpoint', 'B-10'],
1914
+ [4, 8.1, 'Recovery', 'B-11'],
1915
+ ],
1916
+ },
1917
+ ]}
1918
+ series={[
1919
+ {
1920
+ datasetIndex: 0,
1921
+ // encode.tooltip picks the column that titles the tooltip. `id`
1922
+ // comes after `label` here, so the title only shows the id when
1923
+ // encode.tooltip is honored.
1924
+ // https://echarts.apache.org/en/option.html#series-scatter.encode
1925
+ encode: {
1926
+ tooltip: 'id',
1927
+ // oxlint-disable-next-line id-length
1928
+ x: 'x',
1929
+ // oxlint-disable-next-line id-length
1930
+ y: 'y',
1931
+ },
1932
+ name: 'Group A',
1933
+ type: 'scatter',
1934
+ },
1935
+ {
1936
+ datasetIndex: 1,
1937
+ encode: {
1938
+ tooltip: 'id',
1939
+ // oxlint-disable-next-line id-length
1940
+ x: 'x',
1941
+ // oxlint-disable-next-line id-length
1942
+ y: 'y',
1943
+ },
1944
+ name: 'Group B',
1945
+ type: 'scatter',
1946
+ },
1947
+ {
1948
+ data: [
1949
+ [1, 10],
1950
+ [2, 20],
1951
+ [3, 30],
1952
+ [4, 40],
1953
+ [5, 50],
1954
+ [6, 60],
1955
+ ],
1956
+ // No point identifier, so the tooltip is titled with the series name.
1957
+ name: 'Group C',
1958
+ type: 'scatter',
1959
+ },
1960
+ ]}
1961
+ xAxis={{
1962
+ // The axis name labels the matching row in the scatter tooltip.
1963
+ name: 'Concurrent queries',
1964
+ type: 'value',
1965
+ }}
1966
+ yAxis={{
1967
+ name: 'Latency',
1968
+ type: 'value',
1969
+ }}
1970
+ option={{
1971
+ tooltip: {
1972
+ // `valueFormatter` formats the x and y values only. The third
1973
+ // argument is the axis, so this one adds the unit to latency. The
1974
+ // point id in the title is shown unchanged.
1975
+ valueFormatter: (
1976
+ value: number,
1977
+ _dataIndex?: number,
1978
+ context?: TooltipValueContext,
1979
+ ) => (context?.axis === 'y' ? `${value} ms` : `${value}`),
1980
+ },
1981
+ }}
1982
+ />
1983
+ </div>
1984
+ );
1985
+ };
1986
+
1987
+ export default Component;
1988
+ ```
1989
+
1990
+ ### Scatter Large
1991
+
1992
+ ```tsx
1993
+ import { Chart, type TooltipValueContext } from '@neo4j-ndl/react-charts';
1994
+
1995
+ const POINT_COUNT = 20_000;
1996
+ const SERIES_COUNT = 2;
1997
+ const POINTS_PER_SERIES = POINT_COUNT / SERIES_COUNT;
1998
+
1999
+ /**
2000
+ * Deterministic 0–1 values so the chart looks the same on every Storybook
2001
+ * load, without shipping twenty thousand hardcoded rows.
2002
+ */
2003
+ const createSeededRandom = (seed: number) => {
2004
+ let next = seed;
2005
+
2006
+ return () => {
2007
+ next = (Math.imul(next, 1664525) + 1013904223) >>> 0;
2008
+
2009
+ return next / 4_294_967_296;
2010
+ };
2011
+ };
2012
+
2013
+ const roundToTwo = (value: number) => Math.round(value * 100) / 100;
2014
+
2015
+ /**
2016
+ * Standard normal sample from a uniform generator (Box–Muller), so y can sit
2017
+ * on a bell instead of filling the plot evenly.
2018
+ */
2019
+ const nextStandardNormal = (random: () => number) => {
2020
+ const uniform = Math.max(random(), Number.EPSILON);
2021
+ const angle = random();
2022
+
2023
+ return Math.sqrt(-2 * Math.log(uniform)) * Math.cos(2 * Math.PI * angle);
2024
+ };
2025
+
2026
+ const scatterEncode = {
2027
+ tooltip: 'id',
2028
+ // oxlint-disable-next-line id-length
2029
+ x: 'x',
2030
+ // oxlint-disable-next-line id-length
2031
+ y: 'y',
2032
+ };
2033
+
2034
+ const BELL_BASELINE = 8;
2035
+ const BELL_HEIGHT = 72;
2036
+ const BELL_WIDTH = 16;
2037
+
2038
+ const datasets = [
2039
+ { center: 42, group: 'A' },
2040
+ { center: 58, group: 'B' },
2041
+ ].map(({ center, group }, seriesIndex) => {
2042
+ const random = createSeededRandom(seriesIndex + 1);
2043
+ const source: Array<[string, number, number] | ['id', 'x', 'y']> = [
2044
+ ['id', 'x', 'y'],
2045
+ ];
2046
+
2047
+ for (let index = 0; index < POINTS_PER_SERIES - 3; index += 1) {
2048
+ const xValue = random() * 100;
2049
+ const bell =
2050
+ BELL_BASELINE +
2051
+ BELL_HEIGHT * Math.exp(-((xValue - center) ** 2) / (2 * BELL_WIDTH ** 2));
2052
+ const yValue = Math.max(0, bell + nextStandardNormal(random) * 4);
2053
+
2054
+ source.push([
2055
+ `${group}-${index + 1}`,
2056
+ roundToTwo(xValue),
2057
+ roundToTwo(yValue),
2058
+ ]);
2059
+ }
2060
+
2061
+ const peak = roundToTwo(BELL_BASELINE + BELL_HEIGHT);
2062
+
2063
+ // A known cluster on the crest so hovering there lists several points,
2064
+ // including an exact duplicate.
2065
+ source.push(
2066
+ [`${group}-overlap-1`, center, peak],
2067
+ [`${group}-overlap-2`, roundToTwo(center + 0.08), roundToTwo(peak - 0.05)],
2068
+ [`${group}-overlap-3`, center, peak],
2069
+ );
2070
+
2071
+ return { source };
2072
+ });
2073
+
2074
+ const Component = () => {
2075
+ return (
2076
+ // The Chart component requires its parent to have an explicit height.
2077
+ // Without one the chart canvas collapses to 0px and nothing renders.
2078
+ // You can also check the components documentation by hovering over it.
2079
+ <div
2080
+ style={{
2081
+ border: '1px solid silver',
2082
+ borderRadius: '10px',
2083
+ height: '350px',
2084
+ padding: '20px',
2085
+ width: '100%',
2086
+ }}
2087
+ >
2088
+ <Chart
2089
+ legend={{
2090
+ show: true,
2091
+ }}
2092
+ dataset={datasets}
2093
+ series={[
2094
+ {
2095
+ datasetIndex: 0,
2096
+ encode: scatterEncode,
2097
+ name: 'Group A',
2098
+ type: 'scatter',
2099
+ },
2100
+ {
2101
+ datasetIndex: 1,
2102
+ encode: scatterEncode,
2103
+ name: 'Group B',
2104
+ type: 'scatter',
2105
+ },
2106
+ ]}
2107
+ xAxis={{
2108
+ name: 'Concurrent queries',
2109
+ type: 'value',
2110
+ }}
2111
+ yAxis={{
2112
+ name: 'Latency',
2113
+ type: 'value',
2114
+ }}
2115
+ option={{
2116
+ tooltip: {
2117
+ // `valueFormatter` formats the x and y values only. The third
2118
+ // argument is the axis, so this one adds the unit to latency. The
2119
+ // point id in the title is shown unchanged.
2120
+ valueFormatter: (
2121
+ value: number,
2122
+ _dataIndex?: number,
2123
+ context?: TooltipValueContext,
2124
+ ) => (context?.axis === 'y' ? `${value} ms` : `${value}`),
2125
+ },
2126
+ }}
2127
+ />
2128
+ </div>
2129
+ );
2130
+ };
2131
+
2132
+ export default Component;
2133
+ ```
2134
+
1856
2135
  ### Slider
1857
2136
 
1858
2137
  ```tsx