@gravity-ui/charts 0.7.0 → 0.9.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 (168) hide show
  1. package/README.md +1 -4
  2. package/dist/cjs/components/Axis/AxisX.d.ts +1 -0
  3. package/dist/cjs/components/Axis/AxisX.js +43 -6
  4. package/dist/cjs/components/Axis/AxisY.d.ts +1 -0
  5. package/dist/cjs/components/Axis/AxisY.js +63 -17
  6. package/dist/cjs/components/Axis/styles.css +5 -5
  7. package/dist/cjs/components/ChartInner/index.js +8 -6
  8. package/dist/cjs/components/ChartInner/styles.css +4 -4
  9. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +1 -0
  10. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +7 -4
  11. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +3 -2
  12. package/dist/cjs/components/Legend/index.js +2 -3
  13. package/dist/cjs/components/Legend/styles.css +14 -14
  14. package/dist/cjs/components/PlotTitle/index.js +1 -1
  15. package/dist/cjs/components/PlotTitle/styles.css +1 -1
  16. package/dist/cjs/components/Title/index.js +1 -1
  17. package/dist/cjs/components/Title/styles.css +1 -1
  18. package/dist/cjs/components/Tooltip/DefaultContent.js +19 -3
  19. package/dist/cjs/constants/index.d.ts +1 -0
  20. package/dist/cjs/constants/index.js +1 -0
  21. package/dist/cjs/hooks/useChartOptions/tooltip.js +2 -1
  22. package/dist/cjs/hooks/useChartOptions/types.d.ts +13 -2
  23. package/dist/cjs/hooks/useChartOptions/x-axis.js +9 -1
  24. package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -1
  25. package/dist/cjs/hooks/useSeries/constants.js +1 -1
  26. package/dist/cjs/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  27. package/dist/cjs/hooks/useSeries/prepare-bar-x.js +2 -1
  28. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  29. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +3 -1
  30. package/dist/cjs/hooks/useSeries/prepare-pie.js +2 -2
  31. package/dist/cjs/hooks/useSeries/prepare-sankey.d.ts +11 -0
  32. package/dist/cjs/hooks/useSeries/prepare-sankey.js +38 -0
  33. package/dist/cjs/hooks/useSeries/prepareSeries.js +21 -2
  34. package/dist/cjs/hooks/useSeries/types.d.ts +12 -2
  35. package/dist/cjs/hooks/useSeries/utils.js +1 -1
  36. package/dist/cjs/hooks/useShapes/area/index.js +1 -1
  37. package/dist/cjs/hooks/useShapes/bar-x/index.js +16 -2
  38. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +2 -1
  39. package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +1 -0
  40. package/dist/cjs/hooks/useShapes/bar-y/index.js +16 -2
  41. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +2 -1
  42. package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +1 -0
  43. package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
  44. package/dist/cjs/hooks/useShapes/index.js +19 -0
  45. package/dist/cjs/hooks/useShapes/line/index.js +3 -3
  46. package/dist/cjs/hooks/useShapes/marker.js +1 -1
  47. package/dist/cjs/hooks/useShapes/pie/index.js +4 -4
  48. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +37 -35
  49. package/dist/cjs/hooks/useShapes/pie/types.d.ts +1 -1
  50. package/dist/cjs/hooks/useShapes/sankey/index.d.ts +12 -0
  51. package/dist/cjs/hooks/useShapes/sankey/index.js +67 -0
  52. package/dist/cjs/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  53. package/dist/cjs/hooks/useShapes/sankey/prepare-data.js +72 -0
  54. package/dist/cjs/hooks/useShapes/sankey/types.d.ts +33 -0
  55. package/dist/cjs/hooks/useShapes/sankey/types.js +1 -0
  56. package/dist/cjs/hooks/useShapes/scatter/index.js +1 -1
  57. package/dist/cjs/hooks/useShapes/styles.css +7 -7
  58. package/dist/cjs/hooks/useShapes/treemap/index.js +1 -1
  59. package/dist/cjs/hooks/useShapes/utils.d.ts +7 -2
  60. package/dist/cjs/hooks/useShapes/utils.js +22 -17
  61. package/dist/cjs/hooks/useShapes/waterfall/index.js +2 -3
  62. package/dist/cjs/index.d.ts +1 -1
  63. package/dist/cjs/index.js +1 -0
  64. package/dist/cjs/types/chart/axis.d.ts +24 -0
  65. package/dist/cjs/types/chart/bar-x.d.ts +5 -0
  66. package/dist/cjs/types/chart/bar-y.d.ts +5 -0
  67. package/dist/cjs/types/chart/pie.d.ts +2 -0
  68. package/dist/cjs/types/chart/sankey.d.ts +22 -0
  69. package/dist/cjs/types/chart/sankey.js +1 -0
  70. package/dist/cjs/types/chart/series.d.ts +13 -2
  71. package/dist/cjs/types/chart/tooltip.d.ts +9 -1
  72. package/dist/cjs/types/index.d.ts +1 -0
  73. package/dist/cjs/types/index.js +1 -0
  74. package/dist/cjs/utils/chart/get-closest-data.d.ts +2 -0
  75. package/dist/cjs/utils/chart/get-closest-data.js +39 -3
  76. package/dist/cjs/utils/chart/index.js +1 -1
  77. package/dist/cjs/utils/chart/series/index.d.ts +1 -0
  78. package/dist/cjs/utils/chart/series/index.js +1 -0
  79. package/dist/cjs/utils/chart/series/line.d.ts +2 -0
  80. package/dist/cjs/utils/chart/series/line.js +17 -0
  81. package/dist/cjs/utils/{d3-dispatcher.d.ts → dispatcher.d.ts} +1 -1
  82. package/dist/cjs/utils/{d3-dispatcher.js → dispatcher.js} +1 -1
  83. package/dist/cjs/utils/index.d.ts +1 -1
  84. package/dist/cjs/utils/index.js +1 -1
  85. package/dist/esm/components/Axis/AxisX.d.ts +1 -0
  86. package/dist/esm/components/Axis/AxisX.js +43 -6
  87. package/dist/esm/components/Axis/AxisY.d.ts +1 -0
  88. package/dist/esm/components/Axis/AxisY.js +63 -17
  89. package/dist/esm/components/Axis/styles.css +5 -5
  90. package/dist/esm/components/ChartInner/index.js +8 -6
  91. package/dist/esm/components/ChartInner/styles.css +4 -4
  92. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +1 -0
  93. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +7 -4
  94. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +3 -2
  95. package/dist/esm/components/Legend/index.js +2 -3
  96. package/dist/esm/components/Legend/styles.css +14 -14
  97. package/dist/esm/components/PlotTitle/index.js +1 -1
  98. package/dist/esm/components/PlotTitle/styles.css +1 -1
  99. package/dist/esm/components/Title/index.js +1 -1
  100. package/dist/esm/components/Title/styles.css +1 -1
  101. package/dist/esm/components/Tooltip/DefaultContent.js +19 -3
  102. package/dist/esm/constants/index.d.ts +1 -0
  103. package/dist/esm/constants/index.js +1 -0
  104. package/dist/esm/hooks/useChartOptions/tooltip.js +2 -1
  105. package/dist/esm/hooks/useChartOptions/types.d.ts +13 -2
  106. package/dist/esm/hooks/useChartOptions/x-axis.js +9 -1
  107. package/dist/esm/hooks/useChartOptions/y-axis.js +9 -1
  108. package/dist/esm/hooks/useSeries/constants.js +1 -1
  109. package/dist/esm/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  110. package/dist/esm/hooks/useSeries/prepare-bar-x.js +2 -1
  111. package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  112. package/dist/esm/hooks/useSeries/prepare-bar-y.js +3 -1
  113. package/dist/esm/hooks/useSeries/prepare-pie.js +2 -2
  114. package/dist/esm/hooks/useSeries/prepare-sankey.d.ts +11 -0
  115. package/dist/esm/hooks/useSeries/prepare-sankey.js +38 -0
  116. package/dist/esm/hooks/useSeries/prepareSeries.js +21 -2
  117. package/dist/esm/hooks/useSeries/types.d.ts +12 -2
  118. package/dist/esm/hooks/useSeries/utils.js +1 -1
  119. package/dist/esm/hooks/useShapes/area/index.js +1 -1
  120. package/dist/esm/hooks/useShapes/bar-x/index.js +16 -2
  121. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +2 -1
  122. package/dist/esm/hooks/useShapes/bar-x/types.d.ts +1 -0
  123. package/dist/esm/hooks/useShapes/bar-y/index.js +16 -2
  124. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +2 -1
  125. package/dist/esm/hooks/useShapes/bar-y/types.d.ts +1 -0
  126. package/dist/esm/hooks/useShapes/index.d.ts +2 -1
  127. package/dist/esm/hooks/useShapes/index.js +19 -0
  128. package/dist/esm/hooks/useShapes/line/index.js +3 -3
  129. package/dist/esm/hooks/useShapes/marker.js +1 -1
  130. package/dist/esm/hooks/useShapes/pie/index.js +4 -4
  131. package/dist/esm/hooks/useShapes/pie/prepare-data.js +37 -35
  132. package/dist/esm/hooks/useShapes/pie/types.d.ts +1 -1
  133. package/dist/esm/hooks/useShapes/sankey/index.d.ts +12 -0
  134. package/dist/esm/hooks/useShapes/sankey/index.js +67 -0
  135. package/dist/esm/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  136. package/dist/esm/hooks/useShapes/sankey/prepare-data.js +72 -0
  137. package/dist/esm/hooks/useShapes/sankey/types.d.ts +33 -0
  138. package/dist/esm/hooks/useShapes/sankey/types.js +1 -0
  139. package/dist/esm/hooks/useShapes/scatter/index.js +1 -1
  140. package/dist/esm/hooks/useShapes/styles.css +7 -7
  141. package/dist/esm/hooks/useShapes/treemap/index.js +1 -1
  142. package/dist/esm/hooks/useShapes/utils.d.ts +7 -2
  143. package/dist/esm/hooks/useShapes/utils.js +22 -17
  144. package/dist/esm/hooks/useShapes/waterfall/index.js +2 -3
  145. package/dist/esm/index.d.ts +1 -1
  146. package/dist/esm/index.js +1 -0
  147. package/dist/esm/types/chart/axis.d.ts +24 -0
  148. package/dist/esm/types/chart/bar-x.d.ts +5 -0
  149. package/dist/esm/types/chart/bar-y.d.ts +5 -0
  150. package/dist/esm/types/chart/pie.d.ts +2 -0
  151. package/dist/esm/types/chart/sankey.d.ts +22 -0
  152. package/dist/esm/types/chart/sankey.js +1 -0
  153. package/dist/esm/types/chart/series.d.ts +13 -2
  154. package/dist/esm/types/chart/tooltip.d.ts +9 -1
  155. package/dist/esm/types/index.d.ts +1 -0
  156. package/dist/esm/types/index.js +1 -0
  157. package/dist/esm/utils/chart/get-closest-data.d.ts +2 -0
  158. package/dist/esm/utils/chart/get-closest-data.js +39 -3
  159. package/dist/esm/utils/chart/index.js +1 -1
  160. package/dist/esm/utils/chart/series/index.d.ts +1 -0
  161. package/dist/esm/utils/chart/series/index.js +1 -0
  162. package/dist/esm/utils/chart/series/line.d.ts +2 -0
  163. package/dist/esm/utils/chart/series/line.js +17 -0
  164. package/dist/esm/utils/{d3-dispatcher.d.ts → dispatcher.d.ts} +1 -1
  165. package/dist/esm/utils/{d3-dispatcher.js → dispatcher.js} +1 -1
  166. package/dist/esm/utils/index.d.ts +1 -1
  167. package/dist/esm/utils/index.js +1 -1
  168. package/package.json +13 -2
@@ -9,6 +9,7 @@ export type SegmentData = {
9
9
  hovered: boolean;
10
10
  active: boolean;
11
11
  pie: PreparedPieData;
12
+ radius: number;
12
13
  };
13
14
  export type PieLabelData = LabelData & {
14
15
  segment: SegmentData;
@@ -25,7 +26,6 @@ export type PreparedPieData = {
25
26
  labels: PieLabelData[];
26
27
  connectors: PieConnectorData[];
27
28
  center: [number, number];
28
- radius: number;
29
29
  innerRadius: number;
30
30
  borderRadius: number;
31
31
  borderWidth: number;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3';
3
+ import type { PreparedSeriesOptions } from '../../useSeries/types';
4
+ import type { PreparedSankeyData } from './types';
5
+ type ShapeProps = {
6
+ dispatcher: Dispatch<object>;
7
+ preparedData: PreparedSankeyData;
8
+ seriesOptions: PreparedSeriesOptions;
9
+ htmlLayout: HTMLElement | null;
10
+ };
11
+ export declare const SankeySeriesShape: (props: ShapeProps) => React.JSX.Element;
12
+ export {};
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import { select } from 'd3';
3
+ import { block } from '../../../utils';
4
+ import { HtmlLayer } from '../HtmlLayer';
5
+ const b = block('sankey');
6
+ export const SankeySeriesShape = (props) => {
7
+ const { dispatcher, preparedData, seriesOptions, htmlLayout } = props;
8
+ const hoveredDataRef = React.useRef(null);
9
+ const ref = React.useRef(null);
10
+ React.useEffect(() => {
11
+ if (!ref.current) {
12
+ return () => { };
13
+ }
14
+ const svgElement = select(ref.current);
15
+ svgElement.selectAll('*').remove();
16
+ // nodes
17
+ svgElement
18
+ .append('g')
19
+ .selectAll()
20
+ .data(preparedData.nodes)
21
+ .join('rect')
22
+ .attr('x', (d) => d.x0)
23
+ .attr('y', (d) => d.y0)
24
+ .attr('height', (d) => d.y1 - d.y0)
25
+ .attr('width', (d) => d.x1 - d.x0)
26
+ .attr('fill', (d) => d.color);
27
+ // links
28
+ svgElement
29
+ .append('g')
30
+ .attr('fill', 'none')
31
+ .selectAll()
32
+ .data(preparedData.links)
33
+ .join('g')
34
+ .append('path')
35
+ .attr('stroke-opacity', (d) => d.opacity)
36
+ .attr('d', (d) => d.path)
37
+ .attr('stroke', (d) => d.color)
38
+ .attr('stroke-width', (d) => d.strokeWidth);
39
+ // dataLabels
40
+ svgElement
41
+ .append('g')
42
+ .selectAll()
43
+ .data(preparedData.labels)
44
+ .join('text')
45
+ .text((d) => d.text)
46
+ .attr('class', b('label'))
47
+ .attr('x', (d) => d.x)
48
+ .attr('y', (d) => d.y)
49
+ .attr('dy', '0.35em')
50
+ .attr('text-anchor', (d) => d.textAnchor)
51
+ .attr('fill', (d) => { var _a; return (_a = d.style.fontColor) !== null && _a !== void 0 ? _a : null; });
52
+ const eventName = `hover-shape.sankey`;
53
+ function handleShapeHover(data) {
54
+ hoveredDataRef.current = data;
55
+ }
56
+ if (hoveredDataRef.current !== null) {
57
+ handleShapeHover(hoveredDataRef.current);
58
+ }
59
+ dispatcher.on(eventName, handleShapeHover);
60
+ return () => {
61
+ dispatcher.on(eventName, null);
62
+ };
63
+ }, [dispatcher, preparedData, seriesOptions]);
64
+ return (React.createElement(React.Fragment, null,
65
+ React.createElement("g", { ref: ref, className: b() }),
66
+ React.createElement(HtmlLayer, { preparedData: preparedData, htmlLayout: htmlLayout })));
67
+ };
@@ -0,0 +1,7 @@
1
+ import type { PreparedSankeySeries } from '../../useSeries/types';
2
+ import type { PreparedSankeyData } from './types';
3
+ export declare function prepareSankeyData(args: {
4
+ series: PreparedSankeySeries;
5
+ width: number;
6
+ height: number;
7
+ }): PreparedSankeyData;
@@ -0,0 +1,72 @@
1
+ import { sankey, sankeyLinkHorizontal } from 'd3-sankey';
2
+ export function prepareSankeyData(args) {
3
+ const { series, width, height } = args;
4
+ const htmlElements = [];
5
+ const sankeyGenerator = sankey()
6
+ .nodeId((d) => d.name)
7
+ .nodeSort((d) => d.index)
8
+ .nodeWidth(15)
9
+ .nodePadding(10)
10
+ .extent([
11
+ [1, 5],
12
+ [width - 1, height - 5],
13
+ ]);
14
+ const { nodes, links } = sankeyGenerator({
15
+ nodes: series.data,
16
+ links: series.data.reduce((acc, item) => {
17
+ item.links.forEach((l) => {
18
+ const target = series.data.find((d) => d.name === l.name);
19
+ if (target) {
20
+ acc.push({
21
+ source: item,
22
+ target,
23
+ value: l.value,
24
+ });
25
+ }
26
+ });
27
+ return acc;
28
+ }, []),
29
+ });
30
+ const sankeyNodes = nodes.map((node) => {
31
+ var _a, _b, _c, _d, _e, _f;
32
+ return {
33
+ x0: (_a = node.x0) !== null && _a !== void 0 ? _a : 0,
34
+ x1: (_b = node.x1) !== null && _b !== void 0 ? _b : 0,
35
+ y0: (_c = node.y0) !== null && _c !== void 0 ? _c : 0,
36
+ y1: (_d = node.y1) !== null && _d !== void 0 ? _d : 0,
37
+ color: (_e = node.color) !== null && _e !== void 0 ? _e : '',
38
+ data: series.data[(_f = node.index) !== null && _f !== void 0 ? _f : 0],
39
+ };
40
+ });
41
+ const sankeyLinks = links.map((d) => {
42
+ var _a, _b;
43
+ return {
44
+ opacity: 0.75,
45
+ color: (_a = d.source.color) !== null && _a !== void 0 ? _a : '',
46
+ path: sankeyLinkHorizontal()(d),
47
+ strokeWidth: Math.max(1, (_b = d.width) !== null && _b !== void 0 ? _b : 0),
48
+ source: d.source,
49
+ target: d.target,
50
+ value: d.value,
51
+ };
52
+ });
53
+ const dataLabels = [];
54
+ if (series.dataLabels.enabled) {
55
+ const labels = nodes.map((d) => {
56
+ var _a, _b, _c, _d;
57
+ const x0 = (_a = d.x0) !== null && _a !== void 0 ? _a : 0;
58
+ const x1 = (_b = d.x1) !== null && _b !== void 0 ? _b : 0;
59
+ const y0 = (_c = d.y0) !== null && _c !== void 0 ? _c : 0;
60
+ const y1 = (_d = d.y1) !== null && _d !== void 0 ? _d : 0;
61
+ return {
62
+ text: d.name,
63
+ x: x0 < width / 2 ? x1 + 6 : x0 - 6,
64
+ y: (y1 + y0) / 2,
65
+ textAnchor: x0 < width / 2 ? 'start' : 'end',
66
+ style: series.dataLabels.style,
67
+ };
68
+ });
69
+ dataLabels.push(...labels);
70
+ }
71
+ return { series, nodes: sankeyNodes, links: sankeyLinks, htmlElements, labels: dataLabels };
72
+ }
@@ -0,0 +1,33 @@
1
+ import type { BaseTextStyle, HtmlItem, SankeySeriesData } from '../../../types';
2
+ import type { PreparedSankeySeries } from '../../useSeries/types';
3
+ export type SankeyDataLabel = {
4
+ text: string;
5
+ x: number;
6
+ y: number;
7
+ textAnchor: 'start' | 'end';
8
+ style: BaseTextStyle;
9
+ };
10
+ export type SankeyNode = {
11
+ x0: number;
12
+ x1: number;
13
+ y0: number;
14
+ y1: number;
15
+ color: string;
16
+ data: SankeySeriesData;
17
+ };
18
+ export type SankeyLink = {
19
+ opacity: number;
20
+ color: string;
21
+ path: string | null;
22
+ strokeWidth: number;
23
+ source: SankeySeriesData;
24
+ target: SankeySeriesData;
25
+ value: number;
26
+ };
27
+ export type PreparedSankeyData = {
28
+ series: PreparedSankeySeries;
29
+ htmlElements: HtmlItem[];
30
+ nodes: SankeyNode[];
31
+ links: SankeyLink[];
32
+ labels: SankeyDataLabel[];
33
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -6,7 +6,7 @@ import { HtmlLayer } from '../HtmlLayer';
6
6
  import { getMarkerHaloVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
7
7
  import { setActiveState, shapeKey } from '../utils';
8
8
  export { prepareScatterData } from './prepare-data';
9
- const b = block('d3-scatter');
9
+ const b = block('scatter');
10
10
  export function ScatterSeriesShape(props) {
11
11
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = props;
12
12
  const hoveredDataRef = React.useRef(null);
@@ -1,35 +1,35 @@
1
- .gcharts-d3-scatter__point {
1
+ .gcharts-scatter__point {
2
2
  stroke-width: 1px;
3
3
  }
4
4
 
5
- .gcharts-d3-pie__segment {
5
+ .gcharts-pie__segment {
6
6
  stroke: var(--g-color-base-background);
7
7
  }
8
- .gcharts-d3-pie__label {
8
+ .gcharts-pie__label {
9
9
  font-size: 11px;
10
10
  font-weight: bold;
11
11
  fill: var(--g-color-text-complementary);
12
12
  alignment-baseline: before-edge;
13
13
  }
14
14
 
15
- .gcharts-d3-bar-x__label {
15
+ .gcharts-bar-x__label {
16
16
  user-select: none;
17
17
  fill: var(--g-color-text-complementary);
18
18
  }
19
19
 
20
- .gcharts-d3-bar-y__label {
20
+ .gcharts-bar-y__label {
21
21
  user-select: none;
22
22
  fill: var(--g-color-text-complementary);
23
23
  alignment-baseline: after-edge;
24
24
  }
25
25
 
26
- .gcharts-d3-treemap__label {
26
+ .gcharts-treemap__label {
27
27
  user-select: none;
28
28
  pointer-events: none;
29
29
  fill: var(--g-color-text-complementary);
30
30
  alignment-baseline: text-before-edge;
31
31
  }
32
32
 
33
- .gcharts-d3-waterfall__connector {
33
+ .gcharts-waterfall__connector {
34
34
  stroke: var(--g-color-line-generic-active);
35
35
  }
@@ -3,7 +3,7 @@ import { color, select } from 'd3';
3
3
  import get from 'lodash/get';
4
4
  import { block, setEllipsisForOverflowTexts } from '../../../utils';
5
5
  import { HtmlLayer } from '../HtmlLayer';
6
- const b = block('d3-treemap');
6
+ const b = block('treemap');
7
7
  export const TreemapSeriesShape = (props) => {
8
8
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = props;
9
9
  const hoveredDataRef = React.useRef(null);
@@ -1,5 +1,4 @@
1
1
  import type { BaseType } from 'd3';
2
- import type { DashStyle } from '../../constants';
3
2
  import type { BasicInactiveState } from '../../types';
4
3
  import type { ChartScale } from '../useAxisScales';
5
4
  import type { PreparedAxis } from '../useChartOptions/types';
@@ -26,4 +25,10 @@ export declare function setActiveState<T extends {
26
25
  state: BasicInactiveState | undefined;
27
26
  active: boolean;
28
27
  }): T;
29
- export declare function getLineDashArray(dashStyle: DashStyle, strokeWidth?: number): string;
28
+ export declare function getRectPath(args: {
29
+ x: number;
30
+ y: number;
31
+ width: number;
32
+ height: number;
33
+ borderRadius?: number | number[];
34
+ }): import("d3-path").Path;
@@ -1,4 +1,4 @@
1
- import { select } from 'd3';
1
+ import { path, select } from 'd3';
2
2
  import get from 'lodash/get';
3
3
  import { getDataCategoryValue } from '../../utils';
4
4
  export function getXValue(args) {
@@ -36,20 +36,25 @@ export function setActiveState(args) {
36
36
  }
37
37
  return datum;
38
38
  }
39
- export function getLineDashArray(dashStyle, strokeWidth = 2) {
40
- const value = dashStyle.toLowerCase();
41
- const arrayValue = value
42
- .replace('shortdashdotdot', '3,1,1,1,1,1,')
43
- .replace('shortdashdot', '3,1,1,1')
44
- .replace('shortdot', '1,1,')
45
- .replace('shortdash', '3,1,')
46
- .replace('longdash', '8,3,')
47
- .replace(/dot/g, '1,3,')
48
- .replace('dash', '4,3,')
49
- .replace(/,$/, '')
50
- .split(',')
51
- .map((part) => {
52
- return `${parseInt(part, 10) * strokeWidth}`;
53
- });
54
- return arrayValue.join(',').replace(/NaN/g, 'none');
39
+ export function getRectPath(args) {
40
+ const { x, y, width, height, borderRadius = 0 } = args;
41
+ const borderRadiuses = typeof borderRadius === 'number' ? new Array(4).fill(borderRadius) : borderRadius;
42
+ const [borderRadiusTopLeft = 0, borderRadiusTopRight = 0, borderRadiusBottomRight = 0, borderRadiusBottomLeft = 0,] = borderRadiuses !== null && borderRadiuses !== void 0 ? borderRadiuses : [];
43
+ const p = path();
44
+ let startAngle = -Math.PI / 2;
45
+ const angle = Math.PI / 2;
46
+ p.moveTo(x + borderRadiusTopLeft, y);
47
+ p.lineTo(x + width - borderRadiusTopRight, y);
48
+ p.arc(x + width - borderRadiusTopRight, y + borderRadiusTopRight, borderRadiusTopRight, startAngle, startAngle + angle);
49
+ startAngle += angle;
50
+ p.lineTo(x + width, y + height - borderRadiusBottomRight);
51
+ p.arc(x + width - borderRadiusBottomRight, y + height - borderRadiusBottomRight, borderRadiusBottomRight, startAngle, startAngle + angle);
52
+ startAngle += angle;
53
+ p.lineTo(x + borderRadiusBottomLeft, y + height);
54
+ p.arc(x + borderRadiusBottomLeft, y + height - borderRadiusBottomLeft, borderRadiusBottomLeft, startAngle, startAngle + angle);
55
+ startAngle += angle;
56
+ p.lineTo(x, y + borderRadiusTopLeft);
57
+ p.arc(x + borderRadiusTopLeft, y + borderRadiusTopLeft, borderRadiusTopLeft, startAngle, startAngle + angle);
58
+ p.closePath();
59
+ return p;
55
60
  }
@@ -2,12 +2,11 @@ import React from 'react';
2
2
  import { color, line as lineGenerator, select } from 'd3';
3
3
  import get from 'lodash/get';
4
4
  import { DashStyle } from '../../../constants';
5
- import { block, filterOverlappingLabels, getWaterfallPointColor } from '../../../utils';
5
+ import { block, filterOverlappingLabels, getLineDashArray, getWaterfallPointColor, } from '../../../utils';
6
6
  import { HtmlLayer } from '../HtmlLayer';
7
- import { getLineDashArray } from '../utils';
8
7
  export { prepareWaterfallData } from './prepare-data';
9
8
  export * from './types';
10
- const b = block('d3-waterfall');
9
+ const b = block('waterfall');
11
10
  export const WaterfallSeriesShapes = (args) => {
12
11
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
13
12
  const hoveredDataRef = React.useRef(null);
@@ -1,3 +1,3 @@
1
1
  export { CustomShapeRenderer } from './utils';
2
2
  export * from './components';
3
- export type { ChartData } from './types';
3
+ export * from './types';
package/dist/cjs/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { CustomShapeRenderer } from './utils';
2
2
  export * from './components';
3
+ export * from './types';
@@ -1,3 +1,4 @@
1
+ import type { DashStyle } from 'src/constants';
1
2
  import type { FormatNumberOptions } from '../formatter';
2
3
  import type { BaseTextStyle } from './base';
3
4
  export type ChartAxisType = 'category' | 'datetime' | 'linear' | 'logarithmic';
@@ -72,9 +73,32 @@ export interface ChartAxis {
72
73
  * Defaults to 0.05 for Y axis and to 0.01 for X axis.
73
74
  * */
74
75
  maxPadding?: number;
76
+ /** An array of lines stretching across the plot area, marking a specific value */
77
+ plotLines?: AxisPlotLine[];
75
78
  }
76
79
  export interface ChartXAxis extends ChartAxis {
77
80
  }
81
+ export interface AxisPlotLine {
82
+ /** The position of the line in axis units. */
83
+ value?: number;
84
+ /** The color of the plot line (hex, rgba). */
85
+ color?: string;
86
+ /** Pixel width of the plot line.
87
+ *
88
+ * @default 1
89
+ * */
90
+ width?: number;
91
+ /** Option for line stroke style. */
92
+ dashStyle?: `${DashStyle}`;
93
+ /**
94
+ * Individual opacity for the line.
95
+ *
96
+ * @default 1
97
+ * */
98
+ opacity?: number;
99
+ /** Place the line behind or above the chart. */
100
+ layerPlacement?: 'before' | 'after';
101
+ }
78
102
  export interface ChartYAxis extends ChartAxis {
79
103
  /** Axis location.
80
104
  * Possible values - 'left' and 'right'.
@@ -36,6 +36,11 @@ export interface BarXSeries<T = MeaningfulAny> extends BaseSeries {
36
36
  name: string;
37
37
  /** The main color of the series (hex, rgba) */
38
38
  color?: string;
39
+ /**
40
+ * The corner radius of the border surrounding each bar.
41
+ * @default 0
42
+ */
43
+ borderRadius?: number;
39
44
  /** Whether to stack the values of each series on top of each other.
40
45
  * Possible values are undefined to disable, "normal" to stack by value or "percent"
41
46
  *
@@ -29,6 +29,11 @@ export interface BarYSeries<T = MeaningfulAny> extends BaseSeries {
29
29
  name: string;
30
30
  /** The main color of the series (hex, rgba) */
31
31
  color?: string;
32
+ /**
33
+ * The corner radius of the border surrounding each bar.
34
+ * @default 0
35
+ */
36
+ borderRadius?: number;
32
37
  /** Whether to stack the values of each series on top of each other.
33
38
  * Possible values are undefined to disable, "normal" to stack by value or "percent"
34
39
  *
@@ -14,6 +14,8 @@ export interface PieSeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
14
14
  label?: string;
15
15
  /** Individual opacity for the pie segment. */
16
16
  opacity?: number;
17
+ /** The individual radius of the pie segment. The default value is series.radius */
18
+ radius?: string | number;
17
19
  }
18
20
  export type ConnectorShape = 'straight-line' | 'polyline';
19
21
  export type ConnectorCurve = 'linear' | 'basic';
@@ -0,0 +1,22 @@
1
+ import type { SeriesType } from '../../constants';
2
+ import type { MeaningfulAny } from '../misc';
3
+ import type { BaseSeries, BaseSeriesData } from './base';
4
+ import type { ChartLegend, RectLegendSymbolOptions } from './legend';
5
+ export interface SankeySeriesData<T = MeaningfulAny> extends BaseSeriesData<T> {
6
+ name: string;
7
+ color?: string;
8
+ links: {
9
+ name: string;
10
+ value: number;
11
+ }[];
12
+ }
13
+ export interface SankeySeries<T = MeaningfulAny> extends BaseSeries {
14
+ type: typeof SeriesType.Sankey;
15
+ /** The name of the series (used in legend, tooltip etc). */
16
+ name: string;
17
+ data: SankeySeriesData<T>[];
18
+ /** Individual series legend options. Has higher priority than legend options in widget data. */
19
+ legend?: ChartLegend & {
20
+ symbol?: RectLegendSymbolOptions;
21
+ };
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -8,11 +8,12 @@ import type { Halo } from './halo';
8
8
  import type { LineSeries, LineSeriesData } from './line';
9
9
  import type { PointMarkerOptions } from './marker';
10
10
  import type { PieSeries, PieSeriesData } from './pie';
11
+ import type { SankeySeries, SankeySeriesData } from './sankey';
11
12
  import type { ScatterSeries, ScatterSeriesData } from './scatter';
12
13
  import type { TreemapSeries, TreemapSeriesData } from './treemap';
13
14
  import type { WaterfallSeries, WaterfallSeriesData } from './waterfall';
14
- export type ChartSeries<T = MeaningfulAny> = ScatterSeries<T> | PieSeries<T> | BarXSeries<T> | BarYSeries<T> | LineSeries<T> | AreaSeries<T> | TreemapSeries<T> | WaterfallSeries<T>;
15
- export type ChartSeriesData<T = MeaningfulAny> = ScatterSeriesData<T> | PieSeriesData<T> | BarXSeriesData<T> | BarYSeriesData<T> | LineSeriesData<T> | AreaSeriesData<T> | TreemapSeriesData<T> | WaterfallSeriesData<T>;
15
+ export type ChartSeries<T = MeaningfulAny> = ScatterSeries<T> | PieSeries<T> | BarXSeries<T> | BarYSeries<T> | LineSeries<T> | AreaSeries<T> | TreemapSeries<T> | WaterfallSeries<T> | SankeySeries<T>;
16
+ export type ChartSeriesData<T = MeaningfulAny> = ScatterSeriesData<T> | PieSeriesData<T> | BarXSeriesData<T> | BarYSeriesData<T> | LineSeriesData<T> | AreaSeriesData<T> | TreemapSeriesData<T> | WaterfallSeriesData<T> | SankeySeriesData<T>;
16
17
  export interface DataLabelRendererData<T = MeaningfulAny> {
17
18
  data: ChartSeriesData<T>;
18
19
  }
@@ -72,6 +73,11 @@ export interface ChartSeriesOptions {
72
73
  * @default 0.2
73
74
  */
74
75
  groupPadding?: number;
76
+ /**
77
+ * The corner radius of the border surrounding each bar.
78
+ * @default 0
79
+ */
80
+ borderRadius?: number;
75
81
  dataSorting?: {
76
82
  /** Determines what data value should be used to sort by.
77
83
  * Possible values are undefined to disable, "name" to sort by series name or "y"
@@ -108,6 +114,11 @@ export interface ChartSeriesOptions {
108
114
  * @default 0.2
109
115
  */
110
116
  groupPadding?: number;
117
+ /**
118
+ * The corner radius of the border surrounding each bar.
119
+ * @default 0
120
+ */
121
+ borderRadius?: number;
111
122
  dataSorting?: {
112
123
  /** Determines what data value should be used to sort by.
113
124
  * Possible values are undefined to disable, "name" to sort by series name or "x"
@@ -5,6 +5,7 @@ import type { BarXSeries, BarXSeriesData } from './bar-x';
5
5
  import type { BarYSeries, BarYSeriesData } from './bar-y';
6
6
  import type { LineSeries, LineSeriesData } from './line';
7
7
  import type { PieSeries, PieSeriesData } from './pie';
8
+ import type { SankeySeries, SankeySeriesData } from './sankey';
8
9
  import type { ScatterSeries, ScatterSeriesData } from './scatter';
9
10
  import type { TreemapSeries, TreemapSeriesData } from './treemap';
10
11
  import type { WaterfallSeries, WaterfallSeriesData } from './waterfall';
@@ -52,11 +53,16 @@ export interface TooltipDataChunkTreemap<T = MeaningfulAny> {
52
53
  data: TreemapSeriesData<T>;
53
54
  series: TreemapSeries<T>;
54
55
  }
56
+ export interface TooltipDataChunkSankey<T = MeaningfulAny> {
57
+ data: SankeySeriesData<T>;
58
+ target?: SankeySeriesData<T>;
59
+ series: SankeySeries<T>;
60
+ }
55
61
  export interface TooltipDataChunkWaterfall<T = MeaningfulAny> {
56
62
  data: WaterfallSeriesData<T>;
57
63
  series: WaterfallSeries<T>;
58
64
  }
59
- export type TooltipDataChunk<T = MeaningfulAny> = (TooltipDataChunkBarX<T> | TooltipDataChunkBarY<T> | TooltipDataChunkPie<T> | TooltipDataChunkScatter<T> | TooltipDataChunkLine<T> | TooltipDataChunkArea<T> | TooltipDataChunkTreemap<T> | TooltipDataChunkWaterfall<T>) & {
65
+ export type TooltipDataChunk<T = MeaningfulAny> = (TooltipDataChunkBarX<T> | TooltipDataChunkBarY<T> | TooltipDataChunkPie<T> | TooltipDataChunkScatter<T> | TooltipDataChunkLine<T> | TooltipDataChunkArea<T> | TooltipDataChunkTreemap<T> | TooltipDataChunkSankey<T> | TooltipDataChunkWaterfall<T>) & {
60
66
  closest?: boolean;
61
67
  };
62
68
  export interface ChartTooltipRendererArgs<T = MeaningfulAny> {
@@ -72,4 +78,6 @@ export interface ChartTooltip<T = MeaningfulAny> {
72
78
  enabled?: boolean;
73
79
  modifierKey?: 'altKey' | 'metaKey';
74
80
  };
81
+ /** Show tooltip at most once per every ```throttle``` milliseconds */
82
+ throttle?: number;
75
83
  }
@@ -25,6 +25,7 @@ export * from './chart/tooltip';
25
25
  export * from './chart/halo';
26
26
  export * from './chart/treemap';
27
27
  export * from './chart/waterfall';
28
+ export * from './chart/sankey';
28
29
  export interface ChartData<T = MeaningfulAny> {
29
30
  /**
30
31
  * General options for the chart.
@@ -17,3 +17,4 @@ export * from './chart/tooltip';
17
17
  export * from './chart/halo';
18
18
  export * from './chart/treemap';
19
19
  export * from './chart/waterfall';
20
+ export * from './chart/sankey';
@@ -3,6 +3,8 @@ import type { ChartSeries, ChartSeriesData, TooltipDataChunk } from '../../types
3
3
  type GetClosestPointsArgs = {
4
4
  position: [number, number];
5
5
  shapesData: ShapeData[];
6
+ boundsHeight: number;
7
+ boundsWidth: number;
6
8
  };
7
9
  export type ShapePoint = {
8
10
  x: number;
@@ -35,7 +35,7 @@ function getSeriesType(shapeData) {
35
35
  return get(shapeData, 'series.type') || get(shapeData, 'point.series.type');
36
36
  }
37
37
  export function getClosestPoints(args) {
38
- const { position, shapesData } = args;
38
+ const { position, shapesData, boundsHeight, boundsWidth } = args;
39
39
  const [pointerX, pointerY] = position;
40
40
  const result = [];
41
41
  const groups = groupBy(shapesData, getSeriesType);
@@ -135,13 +135,13 @@ export function getClosestPoints(args) {
135
135
  case 'pie': {
136
136
  const points = list.map((d) => d.segments).flat();
137
137
  const closestPoint = points.find((p) => {
138
- const { center, radius } = p.data.pie;
138
+ const { center } = p.data.pie;
139
139
  const x = pointerX - center[0];
140
140
  const y = pointerY - center[1];
141
141
  let angle = Math.atan2(y, x) + 0.5 * Math.PI;
142
142
  angle = angle < 0 ? Math.PI * 2 + angle : angle;
143
143
  const polarRadius = Math.sqrt(x * x + y * y);
144
- return angle >= p.startAngle && angle <= p.endAngle && polarRadius < radius;
144
+ return (angle >= p.startAngle && angle <= p.endAngle && polarRadius < p.data.radius);
145
145
  });
146
146
  if (closestPoint) {
147
147
  result.push({
@@ -166,7 +166,43 @@ export function getClosestPoints(args) {
166
166
  }
167
167
  break;
168
168
  }
169
+ case 'sankey': {
170
+ const [data] = list;
171
+ const closestLink = data.links.find((d) => {
172
+ var _a;
173
+ return isInsidePath({
174
+ path: (_a = d.path) !== null && _a !== void 0 ? _a : '',
175
+ strokeWidth: d.strokeWidth,
176
+ point: [pointerX, pointerY],
177
+ width: boundsWidth,
178
+ height: boundsHeight,
179
+ });
180
+ });
181
+ if (closestLink) {
182
+ result.push({
183
+ data: closestLink.source,
184
+ target: closestLink.target,
185
+ series: data.series,
186
+ closest: true,
187
+ });
188
+ }
189
+ break;
190
+ }
169
191
  }
170
192
  });
171
193
  return result;
172
194
  }
195
+ function isInsidePath(args) {
196
+ const { path, point, width, height, strokeWidth } = args;
197
+ const canvas = document.createElement('canvas');
198
+ canvas.width = width;
199
+ canvas.height = height;
200
+ const ctx = canvas.getContext('2d');
201
+ if (ctx) {
202
+ ctx.lineWidth = strokeWidth;
203
+ const path2D = new Path2D(path);
204
+ ctx.stroke(path2D);
205
+ return ctx.isPointInPath(path2D, ...point) || ctx.isPointInStroke(path2D, ...point);
206
+ }
207
+ return null;
208
+ }
@@ -15,7 +15,7 @@ export * from './legend';
15
15
  export * from './symbol';
16
16
  export * from './series';
17
17
  export * from './color';
18
- const CHARTS_WITHOUT_AXIS = ['pie', 'treemap'];
18
+ const CHARTS_WITHOUT_AXIS = ['pie', 'treemap', 'sankey'];
19
19
  export const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS = [
20
20
  'bar-x',
21
21
  'area',