@gravity-ui/chartkit 3.4.1 → 3.4.3

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 (28) hide show
  1. package/build/components/ChartKit.js +2 -2
  2. package/build/components/Loader/Loader.js +2 -2
  3. package/build/plugins/d3/renderer/components/AxisX.js +2 -2
  4. package/build/plugins/d3/renderer/components/AxisY.js +2 -2
  5. package/build/plugins/d3/renderer/components/Chart.js +5 -5
  6. package/build/plugins/d3/renderer/components/Legend.js +2 -2
  7. package/build/plugins/d3/renderer/components/Title.js +2 -2
  8. package/build/plugins/d3/renderer/components/Tooltip/index.js +2 -2
  9. package/build/plugins/d3/renderer/hooks/index.d.ts +1 -1
  10. package/build/plugins/d3/renderer/hooks/index.js +1 -1
  11. package/build/plugins/d3/renderer/hooks/{useScales → useAxisScales}/index.d.ts +6 -3
  12. package/build/plugins/d3/renderer/hooks/useAxisScales/index.js +122 -0
  13. package/build/plugins/d3/renderer/hooks/useShapes/bar-x.d.ts +1 -1
  14. package/build/plugins/d3/renderer/hooks/useShapes/bar-x.js +2 -2
  15. package/build/plugins/d3/renderer/hooks/useShapes/index.d.ts +3 -3
  16. package/build/plugins/d3/renderer/hooks/useShapes/index.js +23 -19
  17. package/build/plugins/d3/renderer/hooks/useShapes/scatter.d.ts +1 -1
  18. package/build/plugins/d3/renderer/hooks/useShapes/scatter.js +2 -2
  19. package/build/plugins/highcharts/renderer/components/StyledSplitPane/StyledSplitPane.js +2 -2
  20. package/build/plugins/highcharts/renderer/components/withSplitPane/withSplitPane.js +2 -2
  21. package/build/plugins/highcharts/renderer/helpers/config/config.js +2 -2
  22. package/build/plugins/highcharts/renderer/helpers/config/options.js +2 -2
  23. package/build/plugins/indicator/renderer/IndicatorItem.js +2 -2
  24. package/build/plugins/indicator/renderer/IndicatorWidget.js +2 -2
  25. package/build/utils/cn.d.ts +3 -0
  26. package/build/utils/cn.js +4 -0
  27. package/package.json +4 -7
  28. package/build/plugins/d3/renderer/hooks/useScales/index.js +0 -109
@@ -1,13 +1,13 @@
1
1
  import { __rest } from "tslib";
2
2
  import React from 'react';
3
- import block from 'bem-cn-lite';
4
3
  import { i18n } from '../i18n';
5
4
  import { CHARTKIT_ERROR_CODE, ChartKitError, settings } from '../libs';
6
5
  import { getRandomCKId, typedMemo } from '../utils';
6
+ import { cn } from '../utils/cn';
7
7
  import { ErrorBoundary } from './ErrorBoundary/ErrorBoundary';
8
8
  import { Loader } from './Loader/Loader';
9
9
  import './ChartKit.css';
10
- const b = block('chartkit');
10
+ const b = cn('chartkit');
11
11
  const ChartKitComponent = (props) => {
12
12
  const widgetRef = React.useRef();
13
13
  const { instanceRef, id: propsId, type, isMobile, renderPluginLoader } = props, restProps = __rest(props, ["instanceRef", "id", "type", "isMobile", "renderPluginLoader"]);
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
2
  import { Loader as BaseLoader } from '@gravity-ui/uikit';
3
+ import { block } from '../../utils/cn';
4
4
  import './Loader.css';
5
- const b = block('chartkit-loader');
5
+ const b = block('loader');
6
6
  export const Loader = (props) => {
7
7
  return (React.createElement("div", { className: b() },
8
8
  React.createElement(BaseLoader, Object.assign({}, props))));
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
2
  import { axisBottom, select } from 'd3';
3
+ import { block } from '../../../../utils/cn';
4
4
  import { formatAxisTickLabel, parseTransformStyle } from '../utils';
5
- const b = block('chartkit-d3-axis');
5
+ const b = block('d3-axis');
6
6
  const EMPTY_SPACE_BETWEEN_LABELS = 10;
7
7
  // Note: this method do not prepared for rotated labels
8
8
  const removeOverlappingXTicks = (axis) => {
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
2
  import { axisLeft, select } from 'd3';
3
+ import { block } from '../../../../utils/cn';
4
4
  import { formatAxisTickLabel, parseTransformStyle } from '../utils';
5
- const b = block('chartkit-d3-axis');
5
+ const b = block('d3-axis');
6
6
  const EMPTY_SPACE_BETWEEN_LABELS = 10;
7
7
  // Note: this method do not prepared for rotated labels
8
8
  const removeOverlappingYTicks = (axis) => {
@@ -1,14 +1,14 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
2
+ import { block } from '../../../../utils/cn';
3
3
  import { AxisY } from './AxisY';
4
4
  import { AxisX } from './AxisX';
5
5
  import { Legend } from './Legend';
6
6
  import { Title } from './Title';
7
7
  import { Tooltip } from './Tooltip';
8
- import { useChartDimensions, useChartEvents, useChartOptions, useLegend, useScales, useSeries, useShapes, useTooltip, } from '../hooks';
8
+ import { useChartDimensions, useChartEvents, useChartOptions, useLegend, useAxisScales, useSeries, useShapes, useTooltip, } from '../hooks';
9
9
  import { isAxisRelatedSeries } from '../utils';
10
10
  import './styles.css';
11
- const b = block('chartkit-d3');
11
+ const b = block('d3');
12
12
  export const Chart = ({ width, height, data }) => {
13
13
  // FIXME: add data validation
14
14
  const { series } = data;
@@ -27,7 +27,7 @@ export const Chart = ({ width, height, data }) => {
27
27
  });
28
28
  const { activeLegendItems, handleLegendItemClick } = useLegend({ series: series.data });
29
29
  const { chartSeries } = useSeries({ activeLegendItems, series: series.data });
30
- const { xScale, yScale } = useScales({
30
+ const { xScale, yScale } = useAxisScales({
31
31
  boundsWidth,
32
32
  boundsHeight,
33
33
  series: chartSeries,
@@ -54,7 +54,7 @@ export const Chart = ({ width, height, data }) => {
54
54
  chart.margin.left,
55
55
  chart.margin.top + ((title === null || title === void 0 ? void 0 : title.height) || 0),
56
56
  ].join(',')})` },
57
- hasAxisRelatedSeries && (React.createElement(React.Fragment, null,
57
+ hasAxisRelatedSeries && xScale && yScale && (React.createElement(React.Fragment, null,
58
58
  React.createElement(AxisY, { axises: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale }),
59
59
  React.createElement("g", { transform: `translate(0, ${boundsHeight})` },
60
60
  React.createElement(AxisX, { axis: xAxis, width: boundsWidth, height: boundsHeight, scale: xScale })))),
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
2
  import { select } from 'd3';
4
- const b = block('chartkit-d3-legend');
3
+ import { block } from '../../../../utils/cn';
4
+ const b = block('d3-legend');
5
5
  export const Legend = (props) => {
6
6
  const { width, offsetWidth, height, offsetHeight, chartSeries, onItemClick } = props;
7
7
  return (React.createElement("g", { width: width, height: height, ref: (node) => {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
- const b = block('chartkit-d3-title');
2
+ import { block } from '../../../../utils/cn';
3
+ const b = block('d3-title');
4
4
  export const Title = (props) => {
5
5
  const { chartWidth, text, height, style } = props;
6
6
  return (React.createElement("text", { className: b(), dx: chartWidth / 2, dy: height / 2, dominantBaseline: "middle", textAnchor: "middle", style: { fontSize: style === null || style === void 0 ? void 0 : style.fontSize, lineHeight: `${height}px` } },
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
2
+ import { block } from '../../../../../utils/cn';
3
3
  import { DefaultContent } from './DefaultContent';
4
- const b = block('chartkit-d3-tooltip');
4
+ const b = block('d3-tooltip');
5
5
  const POINTER_OFFSET_X = 20;
6
6
  export const Tooltip = (props) => {
7
7
  const { hovered, pointerPosition, tooltip, xAxis, yAxis } = props;
@@ -3,7 +3,7 @@ export * from './useChartEvents';
3
3
  export * from './useChartOptions';
4
4
  export * from './useChartOptions/types';
5
5
  export * from './useLegend';
6
- export * from './useScales';
6
+ export * from './useAxisScales';
7
7
  export * from './useSeries';
8
8
  export * from './useShapes';
9
9
  export * from './useTooltip';
@@ -3,7 +3,7 @@ export * from './useChartEvents';
3
3
  export * from './useChartOptions';
4
4
  export * from './useChartOptions/types';
5
5
  export * from './useLegend';
6
- export * from './useScales';
6
+ export * from './useAxisScales';
7
7
  export * from './useSeries';
8
8
  export * from './useShapes';
9
9
  export * from './useTooltip';
@@ -10,8 +10,11 @@ type Args = {
10
10
  yAxis: ChartOptions['yAxis'];
11
11
  };
12
12
  type ReturnValue = {
13
- xScale: ChartScale;
14
- yScale: ChartScale;
13
+ xScale?: ChartScale;
14
+ yScale?: ChartScale;
15
15
  };
16
- export declare const useScales: (args: Args) => ReturnValue;
16
+ /**
17
+ * Uses to create scales for axis related series
18
+ */
19
+ export declare const useAxisScales: (args: Args) => ReturnValue;
17
20
  export {};
@@ -0,0 +1,122 @@
1
+ import React from 'react';
2
+ import { scaleBand, scaleLinear, scaleUtc, extent } from 'd3';
3
+ import get from 'lodash/get';
4
+ import { getOnlyVisibleSeries, getDomainDataXBySeries, getDomainDataYBySeries, isAxisRelatedSeries, } from '../../utils';
5
+ const isNumericalArrayData = (data) => {
6
+ return data.every((d) => typeof d === 'number' || d === null);
7
+ };
8
+ const filterCategoriesByVisibleSeries = (categories, series) => {
9
+ return categories.filter((category) => {
10
+ return series.some((s) => {
11
+ return s.data.some((d) => 'category' in d && d.category === category);
12
+ });
13
+ });
14
+ };
15
+ const createScales = (args) => {
16
+ const { boundsWidth, boundsHeight, series, xAxis, yAxis } = args;
17
+ const xMin = get(xAxis, 'min');
18
+ const xType = get(xAxis, 'type', 'linear');
19
+ const xCategories = get(xAxis, 'categories');
20
+ const xTimestamps = get(xAxis, 'timestamps');
21
+ const yType = get(yAxis[0], 'type', 'linear');
22
+ const yMin = get(yAxis[0], 'min');
23
+ const yCategories = get(yAxis[0], 'categories');
24
+ const yTimestamps = get(xAxis, 'timestamps');
25
+ let visibleSeries = getOnlyVisibleSeries(series);
26
+ // Reassign to all series in case of all series unselected,
27
+ // otherwise we will get an empty space without grid
28
+ visibleSeries = visibleSeries.length === 0 ? series : visibleSeries;
29
+ let xScale;
30
+ let yScale;
31
+ switch (xType) {
32
+ case 'linear': {
33
+ const domain = getDomainDataXBySeries(visibleSeries);
34
+ const range = [0, boundsWidth - boundsWidth * xAxis.maxPadding];
35
+ if (isNumericalArrayData(domain)) {
36
+ const [domainXMin, xMax] = extent(domain);
37
+ const xMinValue = typeof xMin === 'number' ? xMin : domainXMin;
38
+ xScale = scaleLinear().domain([xMinValue, xMax]).range(range).nice();
39
+ }
40
+ break;
41
+ }
42
+ case 'category': {
43
+ if (xCategories) {
44
+ const filteredCategories = filterCategoriesByVisibleSeries(xCategories, visibleSeries);
45
+ xScale = scaleBand().domain(filteredCategories).range([0, boundsWidth]);
46
+ }
47
+ break;
48
+ }
49
+ case 'datetime': {
50
+ const range = [0, boundsWidth - boundsWidth * xAxis.maxPadding];
51
+ if (xTimestamps) {
52
+ const [xMin, xMax] = extent(xTimestamps);
53
+ xScale = scaleUtc().domain([xMin, xMax]).range(range).nice();
54
+ }
55
+ else {
56
+ const domain = getDomainDataXBySeries(visibleSeries);
57
+ if (isNumericalArrayData(domain)) {
58
+ const [xMin, xMax] = extent(domain);
59
+ xScale = scaleUtc().domain([xMin, xMax]).range(range).nice();
60
+ }
61
+ }
62
+ break;
63
+ }
64
+ }
65
+ if (!xScale) {
66
+ throw new Error('Failed to create xScale');
67
+ }
68
+ switch (yType) {
69
+ case 'linear': {
70
+ const domain = getDomainDataYBySeries(visibleSeries);
71
+ const range = [boundsHeight, boundsHeight * yAxis[0].maxPadding];
72
+ if (isNumericalArrayData(domain)) {
73
+ const [domainYMin, yMax] = extent(domain);
74
+ const yMinValue = typeof yMin === 'number' ? yMin : domainYMin;
75
+ yScale = scaleLinear().domain([yMinValue, yMax]).range(range).nice();
76
+ }
77
+ break;
78
+ }
79
+ case 'category': {
80
+ if (yCategories) {
81
+ const filteredCategories = filterCategoriesByVisibleSeries(yCategories, visibleSeries);
82
+ yScale = scaleBand().domain(filteredCategories).range([boundsHeight, 0]);
83
+ }
84
+ break;
85
+ }
86
+ case 'datetime': {
87
+ const range = [boundsHeight, boundsHeight * yAxis[0].maxPadding];
88
+ if (yTimestamps) {
89
+ const [yMin, yMax] = extent(yTimestamps);
90
+ yScale = scaleUtc().domain([yMin, yMax]).range(range).nice();
91
+ }
92
+ else {
93
+ const domain = getDomainDataYBySeries(visibleSeries);
94
+ if (isNumericalArrayData(domain)) {
95
+ const [yMin, yMax] = extent(domain);
96
+ yScale = scaleUtc().domain([yMin, yMax]).range(range).nice();
97
+ }
98
+ }
99
+ break;
100
+ }
101
+ }
102
+ if (!yScale) {
103
+ throw new Error('Failed to create yScale');
104
+ }
105
+ return { xScale, yScale };
106
+ };
107
+ /**
108
+ * Uses to create scales for axis related series
109
+ */
110
+ export const useAxisScales = (args) => {
111
+ const { boundsWidth, boundsHeight, series, xAxis, yAxis } = args;
112
+ const scales = React.useMemo(() => {
113
+ let xScale;
114
+ let yScale;
115
+ const hasAxisRelatedSeries = series.some(isAxisRelatedSeries);
116
+ if (hasAxisRelatedSeries) {
117
+ ({ xScale, yScale } = createScales({ boundsWidth, boundsHeight, series, xAxis, yAxis }));
118
+ }
119
+ return { xScale, yScale };
120
+ }, [boundsWidth, boundsHeight, series, xAxis, yAxis]);
121
+ return scales;
122
+ };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ChartOptions } from '../useChartOptions/types';
3
- import { ChartScale } from '../useScales';
3
+ import { ChartScale } from '../useAxisScales';
4
4
  import { OnSeriesMouseLeave, OnSeriesMouseMove } from '../useTooltip/types';
5
5
  import { BarXSeries } from '../../../../../types/widget-data';
6
6
  type Args = {
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
2
+ import { block } from '../../../../../utils/cn';
3
3
  const DEFAULT_BAR_RECT_WIDTH = 50;
4
4
  const DEFAULT_LINEAR_BAR_RECT_WIDTH = 20;
5
5
  const MIN_RECT_GAP = 1;
6
- const b = block('chartkit-d3-bar');
6
+ const b = block('d3-bar');
7
7
  const getRectProperties = (args) => {
8
8
  const { point, xAxis, xScale, yAxis, yScale, minPointDistance } = args;
9
9
  let cx;
@@ -1,17 +1,17 @@
1
1
  import React from 'react';
2
2
  import type { ChartOptions } from '../useChartOptions/types';
3
- import type { ChartScale } from '../useScales';
3
+ import type { ChartScale } from '../useAxisScales';
4
4
  import type { ChartSeries } from '../useSeries';
5
5
  import type { OnSeriesMouseMove, OnSeriesMouseLeave } from '../useTooltip/types';
6
6
  type Args = {
7
7
  series: ChartSeries[];
8
8
  xAxis: ChartOptions['xAxis'];
9
- xScale: ChartScale;
10
9
  yAxis: ChartOptions['yAxis'];
11
- yScale: ChartScale;
12
10
  svgContainer: SVGSVGElement | null;
13
11
  onSeriesMouseMove?: OnSeriesMouseMove;
14
12
  onSeriesMouseLeave?: OnSeriesMouseLeave;
13
+ xScale?: ChartScale;
14
+ yScale?: ChartScale;
15
15
  };
16
16
  export declare const useShapes: (args: Args) => {
17
17
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
@@ -12,28 +12,32 @@ export const useShapes = (args) => {
12
12
  const [seriesType, chartSeries] = item;
13
13
  switch (seriesType) {
14
14
  case 'bar-x': {
15
- acc.push(...prepareBarXSeries({
16
- series: chartSeries,
17
- xAxis,
18
- xScale,
19
- yAxis,
20
- yScale,
21
- onSeriesMouseMove,
22
- onSeriesMouseLeave,
23
- }));
15
+ if (xScale && yScale) {
16
+ acc.push(...prepareBarXSeries({
17
+ series: chartSeries,
18
+ xAxis,
19
+ xScale,
20
+ yAxis,
21
+ yScale,
22
+ onSeriesMouseMove,
23
+ onSeriesMouseLeave,
24
+ }));
25
+ }
24
26
  break;
25
27
  }
26
28
  case 'scatter': {
27
- acc.push(...prepareScatterSeries({
28
- series: chartSeries,
29
- xAxis,
30
- xScale,
31
- yAxis,
32
- yScale,
33
- onSeriesMouseMove,
34
- onSeriesMouseLeave,
35
- svgContainer,
36
- }));
29
+ if (xScale && yScale) {
30
+ acc.push(...prepareScatterSeries({
31
+ series: chartSeries,
32
+ xAxis,
33
+ xScale,
34
+ yAxis,
35
+ yScale,
36
+ onSeriesMouseMove,
37
+ onSeriesMouseLeave,
38
+ svgContainer,
39
+ }));
40
+ }
37
41
  break;
38
42
  }
39
43
  }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ChartOptions } from '../useChartOptions/types';
3
- import { ChartScale } from '../useScales';
3
+ import { ChartScale } from '../useAxisScales';
4
4
  import { OnSeriesMouseLeave, OnSeriesMouseMove } from '../useTooltip/types';
5
5
  import { ScatterSeries } from '../../../../../types/widget-data';
6
6
  type PrepareScatterSeriesArgs = {
@@ -1,7 +1,7 @@
1
1
  import { pointer } from 'd3';
2
2
  import React from 'react';
3
- import block from 'bem-cn-lite';
4
- const b = block('chartkit-d3-scatter');
3
+ import { block } from '../../../../../utils/cn';
4
+ const b = block('d3-scatter');
5
5
  const DEFAULT_SCATTER_POINT_RADIUS = 4;
6
6
  const prepareCategoricalScatterData = (data) => {
7
7
  return data.filter((d) => typeof d.category === 'string');
@@ -1,9 +1,9 @@
1
1
  import { __rest } from "tslib";
2
2
  import React from 'react';
3
3
  import SplitPane, { Pane } from 'react-split-pane';
4
- import block from 'bem-cn-lite';
4
+ import { cn } from '../../../../../utils/cn';
5
5
  import './StyledSplitPane.css';
6
- const b = block('styled-split-pane');
6
+ const b = cn('styled-split-pane');
7
7
  const resizerClassName = b('pane-resizer');
8
8
  export const StyledSplitPane = (_a) => {
9
9
  var { paneOneRender, paneTwoRender } = _a, splitPaneProps = __rest(_a, ["paneOneRender", "paneTwoRender"]);
@@ -1,12 +1,12 @@
1
1
  /* eslint callback-return: 0 */
2
2
  import React from 'react';
3
- import block from 'bem-cn-lite';
4
3
  import { debounce, get } from 'lodash';
5
4
  import { getRandomCKId } from '../../../../../utils';
5
+ import { cn } from '../../../../../utils/cn';
6
6
  import { chartTypesWithoutCrosshair } from '../../helpers/config/config';
7
7
  import { StyledSplitPane } from '../StyledSplitPane/StyledSplitPane';
8
8
  import './WithSplitPane.css';
9
- const b = block('with-split-pane');
9
+ const b = cn('with-split-pane');
10
10
  const PANE_RESIZER_HEIGHT = 24;
11
11
  const CHART_SECTION_PERCENTAGE = 0.6;
12
12
  const MIN_TOOLTIP_SECTION_HEIGHT = 62;
@@ -1,6 +1,5 @@
1
1
  /* eslint new-cap: 0, complexity: 0 */
2
2
  import Highcharts from 'highcharts';
3
- import block from 'bem-cn-lite';
4
3
  import merge from 'lodash/merge';
5
4
  import mergeWith from 'lodash/mergeWith';
6
5
  import get from 'lodash/get';
@@ -13,13 +12,14 @@ import debounce from 'lodash/debounce';
13
12
  import { dateTime } from '@gravity-ui/date-utils';
14
13
  import { i18n } from '../../../../../i18n';
15
14
  import { formatNumber } from '../../../../shared';
15
+ import { block } from '../../../../../utils/cn';
16
16
  import { getCommentsOnLine, drawComments, hideComments, drawOnlyRendererComments, } from '../comments/drawing';
17
17
  import formatTooltip, { TOOLTIP_ROW_CLASS_NAME, SERIES_NAME_DATA_ATTRIBUTE, TOOLTIP_HEADER_CLASS_NAME, TOOLTIP_LIST_CLASS_NAME, TOOLTIP_FOOTER_CLASS_NAME, TOOLTIP_CONTAINER_CLASS_NAME, TOOLTIP_ROW_NAME_CLASS_NANE, } from '../tooltip';
18
18
  import defaultOptions from './options';
19
19
  import { calculatePrecision, isTooltipShared, isSafari, mergeArrayWithObject, concatStrings, buildNavigatorFallback, addShowInNavigatorToSeries, setNavigatorDefaultPeriod, numberFormat, getFormatOptionsFromLine, checkTooltipPinningAvailability, getSortedData, } from './utils';
20
20
  import { handleLegendItemClick } from './handleLegendItemClick';
21
21
  import { getChartKitFormattedValue } from './utils/getChartKitFormattedValue';
22
- const b = block('chartkit-tooltip');
22
+ const b = block('tooltip');
23
23
  const TOOLTIP_OFFSET_FROM_CURSOR = 15;
24
24
  const TOOLTIP_ROOT_CLASS_NAME = 'chartkit-highcharts-tooltip-container';
25
25
  const MOBILE_TOOLTIP_OFFSET_FROM_POINTER = 30;
@@ -1,10 +1,10 @@
1
1
  /** Default options for Highcharts & Highstock */
2
- import block from 'bem-cn-lite';
3
2
  import merge from 'lodash/merge';
4
3
  import { i18n } from '../../../../../i18n';
4
+ import { block } from '../../../../../utils/cn';
5
5
  import { getChartKitFormattedValue } from './utils';
6
6
  import LocalStorage from './utils/localStorage';
7
- const b = block('chartkit-tooltip');
7
+ const b = block('tooltip');
8
8
  function getTooltipHeaderFormat(format, showColor) {
9
9
  return `<div class="${b('header')}">
10
10
  ${showColor
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
- const b = block('chartkit-indicator');
2
+ import { block } from '../../../utils/cn';
3
+ const b = block('indicator');
4
4
  export const IndicatorItem = (props) => {
5
5
  const { formatNumber, content, color, defaultColor, size, title, nowrap } = props;
6
6
  const mods = { size, nowrap };
@@ -1,13 +1,13 @@
1
1
  import React from 'react';
2
- import block from 'bem-cn-lite';
3
2
  import { isEmpty } from 'lodash';
4
3
  import { i18n } from '../../../i18n';
5
4
  import { CHARTKIT_ERROR_CODE, ChartKitError } from '../../../libs';
6
5
  import { CHARTKIT_SCROLLABLE_NODE_CLASSNAME } from '../../../constants';
7
6
  import { getChartPerformanceDuration, getRandomCKId, markChartPerformance } from '../../../utils';
7
+ import { block } from '../../../utils/cn';
8
8
  import { IndicatorItem } from './IndicatorItem';
9
9
  import './IndicatorWidget.css';
10
- const b = block('chartkit-indicator');
10
+ const b = block('indicator');
11
11
  const IndicatorWidget = React.forwardRef(
12
12
  // _ref needs to avoid this React warning:
13
13
  // "forwardRef render functions accept exactly two parameters: props and ref"
@@ -0,0 +1,3 @@
1
+ export declare const NAMESPACE = "chartkit-";
2
+ export declare const cn: import("@bem-react/classname").ClassNameInitilizer;
3
+ export declare const block: import("@bem-react/classname").ClassNameInitilizer;
@@ -0,0 +1,4 @@
1
+ import { withNaming } from '@bem-react/classname';
2
+ export const NAMESPACE = 'chartkit-';
3
+ export const cn = withNaming({ e: '__', m: '_' });
4
+ export const block = withNaming({ n: NAMESPACE, e: '__', m: '_' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/chartkit",
3
- "version": "3.4.1",
3
+ "version": "3.4.3",
4
4
  "description": "React component used to render charts based on any sources you need",
5
5
  "license": "MIT",
6
6
  "repository": "git@github.com:gravity-ui/ChartKit.git",
@@ -14,13 +14,10 @@
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
17
- "sideEffects": [
18
- "*.css"
19
- ],
20
17
  "dependencies": {
18
+ "@bem-react/classname": "^1.6.0",
21
19
  "@gravity-ui/date-utils": "^1.4.1",
22
- "@gravity-ui/yagr": "^3.7.9",
23
- "bem-cn-lite": "^4.1.0",
20
+ "@gravity-ui/yagr": "^3.7.10",
24
21
  "d3": "^7.8.5",
25
22
  "lodash": "^4.17.21",
26
23
  "react-split-pane": "^0.1.92"
@@ -34,7 +31,7 @@
34
31
  "@gravity-ui/prettier-config": "^1.0.1",
35
32
  "@gravity-ui/stylelint-config": "^1.0.1",
36
33
  "@gravity-ui/tsconfig": "^1.0.0",
37
- "@gravity-ui/uikit": "^5.0.0",
34
+ "@gravity-ui/uikit": "^5.6.0",
38
35
  "@storybook/addon-essentials": "^7.0.26",
39
36
  "@storybook/addon-knobs": "^7.0.2",
40
37
  "@storybook/cli": "^7.0.26",
@@ -1,109 +0,0 @@
1
- import React from 'react';
2
- import { scaleBand, scaleLinear, scaleUtc, extent } from 'd3';
3
- import get from 'lodash/get';
4
- import { getOnlyVisibleSeries, getDomainDataXBySeries, getDomainDataYBySeries } from '../../utils';
5
- const isNumericalArrayData = (data) => {
6
- return data.every((d) => typeof d === 'number' || d === null);
7
- };
8
- const filterCategoriesByVisibleSeries = (categories, series) => {
9
- return categories.filter((category) => {
10
- return series.some((s) => {
11
- return s.data.some((d) => 'category' in d && d.category === category);
12
- });
13
- });
14
- };
15
- export const useScales = (args) => {
16
- const { boundsWidth, boundsHeight, series, xAxis, yAxis } = args;
17
- const scales = React.useMemo(() => {
18
- const xMin = get(xAxis, 'min');
19
- const xType = get(xAxis, 'type', 'linear');
20
- const xCategories = get(xAxis, 'categories');
21
- const xTimestamps = get(xAxis, 'timestamps');
22
- const yType = get(yAxis[0], 'type', 'linear');
23
- const yMin = get(yAxis[0], 'min');
24
- const yCategories = get(yAxis[0], 'categories');
25
- const yTimestamps = get(xAxis, 'timestamps');
26
- let visibleSeries = getOnlyVisibleSeries(series);
27
- // Reassign to all series in case of all series unselected,
28
- // otherwise we will get an empty space without grid
29
- visibleSeries = visibleSeries.length === 0 ? series : visibleSeries;
30
- let xScale;
31
- let yScale;
32
- switch (xType) {
33
- case 'linear': {
34
- const domain = getDomainDataXBySeries(visibleSeries);
35
- const range = [0, boundsWidth - boundsWidth * xAxis.maxPadding];
36
- if (isNumericalArrayData(domain)) {
37
- const [domainXMin, xMax] = extent(domain);
38
- const xMinValue = typeof xMin === 'number' ? xMin : domainXMin;
39
- xScale = scaleLinear().domain([xMinValue, xMax]).range(range).nice();
40
- }
41
- break;
42
- }
43
- case 'category': {
44
- if (xCategories) {
45
- const filteredCategories = filterCategoriesByVisibleSeries(xCategories, visibleSeries);
46
- xScale = scaleBand().domain(filteredCategories).range([0, boundsWidth]);
47
- }
48
- break;
49
- }
50
- case 'datetime': {
51
- const range = [0, boundsWidth - boundsWidth * xAxis.maxPadding];
52
- if (xTimestamps) {
53
- const [xMin, xMax] = extent(xTimestamps);
54
- xScale = scaleUtc().domain([xMin, xMax]).range(range).nice();
55
- }
56
- else {
57
- const domain = getDomainDataXBySeries(visibleSeries);
58
- if (isNumericalArrayData(domain)) {
59
- const [xMin, xMax] = extent(domain);
60
- xScale = scaleUtc().domain([xMin, xMax]).range(range).nice();
61
- }
62
- }
63
- break;
64
- }
65
- }
66
- if (!xScale) {
67
- throw new Error('Failed to create xScale');
68
- }
69
- switch (yType) {
70
- case 'linear': {
71
- const domain = getDomainDataYBySeries(visibleSeries);
72
- const range = [boundsHeight, boundsHeight * yAxis[0].maxPadding];
73
- if (isNumericalArrayData(domain)) {
74
- const [domainYMin, yMax] = extent(domain);
75
- const yMinValue = typeof yMin === 'number' ? yMin : domainYMin;
76
- yScale = scaleLinear().domain([yMinValue, yMax]).range(range).nice();
77
- }
78
- break;
79
- }
80
- case 'category': {
81
- if (yCategories) {
82
- const filteredCategories = filterCategoriesByVisibleSeries(yCategories, visibleSeries);
83
- yScale = scaleBand().domain(filteredCategories).range([boundsHeight, 0]);
84
- }
85
- break;
86
- }
87
- case 'datetime': {
88
- const range = [boundsHeight, boundsHeight * yAxis[0].maxPadding];
89
- if (yTimestamps) {
90
- const [yMin, yMax] = extent(yTimestamps);
91
- yScale = scaleUtc().domain([yMin, yMax]).range(range).nice();
92
- }
93
- else {
94
- const domain = getDomainDataYBySeries(visibleSeries);
95
- if (isNumericalArrayData(domain)) {
96
- const [yMin, yMax] = extent(domain);
97
- yScale = scaleUtc().domain([yMin, yMax]).range(range).nice();
98
- }
99
- }
100
- break;
101
- }
102
- }
103
- if (!yScale) {
104
- throw new Error('Failed to create yScale');
105
- }
106
- return { xScale, yScale };
107
- }, [boundsWidth, boundsHeight, series, xAxis, yAxis]);
108
- return scales;
109
- };