@gravity-ui/chartkit 2.10.1 → 2.11.1-beta.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 (33) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/components/ChartKit.d.ts +1 -0
  3. package/build/components/ChartKit.js +1 -1
  4. package/build/components/ErrorBoundary/ErrorBoundary.d.ts +5 -1
  5. package/build/components/ErrorBoundary/ErrorBoundary.js +24 -2
  6. package/build/plugins/highcharts/__stories__/components/ChartStory.d.ts +5 -1
  7. package/build/plugins/highcharts/__stories__/components/ChartStory.js +9 -3
  8. package/build/plugins/highcharts/__stories__/custom-error-render/custom-error-render.stories.d.ts +4 -0
  9. package/build/plugins/highcharts/__stories__/custom-error-render/custom-error-render.stories.js +41 -0
  10. package/build/plugins/highcharts/__stories__/no-data/no-data.stories.d.ts +4 -0
  11. package/build/plugins/highcharts/__stories__/no-data/no-data.stories.js +20 -0
  12. package/build/plugins/highcharts/mocks/custom-error-render.d.ts +3 -0
  13. package/build/plugins/highcharts/mocks/custom-error-render.js +69 -0
  14. package/build/plugins/highcharts/mocks/no-data.d.ts +3 -0
  15. package/build/plugins/highcharts/mocks/no-data.js +69 -0
  16. package/build/plugins/highcharts/renderer/HighchartsWidget.d.ts +1 -0
  17. package/build/plugins/highcharts/renderer/components/withSplitPane/withSplitPane.js +4 -1
  18. package/build/plugins/indicator/renderer/IndicatorWidget.d.ts +1 -0
  19. package/build/plugins/yagr/__stories__/Yagr.stories.d.ts +2 -0
  20. package/build/plugins/yagr/__stories__/Yagr.stories.js +23 -3
  21. package/build/plugins/yagr/__stories__/mocks/line10.d.ts +50 -0
  22. package/build/plugins/yagr/__stories__/mocks/line10.js +15 -0
  23. package/build/plugins/yagr/__tests__/utils.test.js +4 -4
  24. package/build/plugins/yagr/renderer/YagrWidget.d.ts +1 -0
  25. package/build/plugins/yagr/renderer/YagrWidget.js +10 -8
  26. package/build/plugins/yagr/renderer/tooltip/renderTooltip.js +4 -4
  27. package/build/plugins/yagr/renderer/utils.js +1 -1
  28. package/build/types/index.d.ts +8 -0
  29. package/build/utils/getErrorMessage.d.ts +2 -0
  30. package/build/utils/getErrorMessage.js +5 -0
  31. package/package.json +4 -4
  32. package/build/components/ErrorView/ErrorView.d.ts +0 -7
  33. package/build/components/ErrorView/ErrorView.js +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.11.0](https://github.com/gravity-ui/chartkit/compare/v2.10.1...v2.11.0) (2023-06-20)
4
+
5
+
6
+ ### Features
7
+
8
+ * add renderError property ([#175](https://github.com/gravity-ui/chartkit/issues/175)) ([84c03a9](https://github.com/gravity-ui/chartkit/commit/84c03a9f8516e9fb846e25a920aa82b00c660a02))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * reset "No data" error on change data ([ac0da94](https://github.com/gravity-ui/chartkit/commit/ac0da94fd21ff558a739c00b8904645d5ba006ef))
14
+
3
15
  ## [2.10.1](https://github.com/gravity-ui/chartkit/compare/v2.10.0...v2.10.1) (2023-06-19)
4
16
 
5
17
 
@@ -13,6 +13,7 @@ export declare const ChartKit: <T extends keyof import("../types").ChartKitWidge
13
13
  onLoad?: ((data?: import("../types").ChartKitOnLoadData<T> | undefined) => void) | undefined;
14
14
  onRender?: ((data: import("../types").ChartKitOnRenderData) => void) | undefined;
15
15
  onChartLoad?: ((data: import("../types").ChartKitOnChartLoad<T>) => void) | undefined;
16
+ renderError?: import("../types").RenderError | undefined;
16
17
  onError?: import("../types").ChartKitOnError | undefined;
17
18
  } & { [key in keyof Omit<import("../types").ChartKitWidget[T], "widget" | "data">]: import("../types").ChartKitWidget[T][key]; } & {
18
19
  ref?: React.ForwardedRef<ChartKitRef | undefined> | undefined;
@@ -36,7 +36,7 @@ const ChartKitComponent = (props) => {
36
36
  React.createElement(ChartComponent, Object.assign({ ref: widgetRef, id: id, lang: lang }, restProps)))));
37
37
  };
38
38
  const ChartKitComponentWithErrorBoundary = React.forwardRef(function ChartKitComponentWithErrorBoundary(props, ref) {
39
- return (React.createElement(ErrorBoundary, { onError: props.onError },
39
+ return (React.createElement(ErrorBoundary, { onError: props.onError, data: props.data, renderError: props.renderError },
40
40
  React.createElement(ChartKitComponent, Object.assign({ instanceRef: ref }, props))));
41
41
  }) /* https://stackoverflow.com/a/58473012 */;
42
42
  export const ChartKit = typedMemo(ChartKitComponentWithErrorBoundary);
@@ -1,8 +1,10 @@
1
1
  import React from 'react';
2
2
  import type { ChartKitError } from '../../libs';
3
- import type { ChartKitOnError } from '../../types';
3
+ import type { ChartKitOnError, ChartKitType, ChartKitWidget, RenderError } from '../../types';
4
4
  declare type Props = {
5
5
  onError?: ChartKitOnError;
6
+ data: ChartKitWidget[ChartKitType]['data'];
7
+ renderError?: RenderError;
6
8
  };
7
9
  declare type State = {
8
10
  error?: ChartKitError | Error;
@@ -13,6 +15,8 @@ export declare class ErrorBoundary extends React.Component<Props, State> {
13
15
  };
14
16
  state: State;
15
17
  componentDidCatch(): void;
18
+ componentDidUpdate(prevProps: Readonly<Props>): void;
16
19
  render(): React.ReactNode;
20
+ resetError: () => void;
17
21
  }
18
22
  export {};
@@ -1,11 +1,17 @@
1
1
  import React from 'react';
2
- import { ErrorView } from '../ErrorView/ErrorView';
2
+ import { getErrorMessage } from '../../utils/getErrorMessage';
3
+ import { CHARTKIT_ERROR_CODE } from '../../libs';
3
4
  export class ErrorBoundary extends React.Component {
4
5
  constructor() {
5
6
  super(...arguments);
6
7
  this.state = {
7
8
  error: undefined,
8
9
  };
10
+ this.resetError = () => {
11
+ if (this.state.error) {
12
+ this.setState({ error: undefined });
13
+ }
14
+ };
9
15
  }
10
16
  static getDerivedStateFromError(error) {
11
17
  return { error };
@@ -17,10 +23,26 @@ export class ErrorBoundary extends React.Component {
17
23
  (_b = (_a = this.props).onError) === null || _b === void 0 ? void 0 : _b.call(_a, { error });
18
24
  }
19
25
  }
26
+ componentDidUpdate(prevProps) {
27
+ if (prevProps.data !== this.props.data) {
28
+ const { error } = this.state;
29
+ if (error && 'code' in error && error.code === CHARTKIT_ERROR_CODE.NO_DATA) {
30
+ this.resetError();
31
+ }
32
+ }
33
+ }
20
34
  render() {
21
35
  const { error } = this.state;
22
36
  if (error) {
23
- return React.createElement(ErrorView, { error: error });
37
+ const message = getErrorMessage(error);
38
+ if (this.props.renderError) {
39
+ return this.props.renderError({
40
+ error,
41
+ message,
42
+ resetError: this.resetError,
43
+ });
44
+ }
45
+ return React.createElement("div", null, message);
24
46
  }
25
47
  return this.props.children;
26
48
  }
@@ -1,8 +1,12 @@
1
1
  import React from 'react';
2
+ import { RenderError } from '../../../../types';
2
3
  import { HighchartsWidgetData } from '../../types';
3
4
  export declare type ChartStoryProps = {
5
+ data: HighchartsWidgetData;
6
+ withoutPlugin?: boolean;
7
+ visible?: boolean;
4
8
  height?: string;
5
9
  width?: string;
6
- data: HighchartsWidgetData;
10
+ renderError?: RenderError;
7
11
  };
8
12
  export declare const ChartStory: React.FC<ChartStoryProps>;
@@ -8,15 +8,21 @@ const DEFAULT_STORY_HEIGHT = '300px';
8
8
  const DEFAULT_STORY_WIDTH = '100%';
9
9
  export const ChartStory = (props) => {
10
10
  const { height, width, data } = props;
11
- const [visible, setVisible] = React.useState(false);
11
+ const initRef = React.useRef(false);
12
+ const [visible, setVisible] = React.useState(Boolean(props.visible));
12
13
  const chartKitRef = React.useRef();
14
+ if (!initRef.current) {
15
+ if (!props.withoutPlugin) {
16
+ settings.set({ plugins: [HighchartsPlugin], extra: { holidays } });
17
+ }
18
+ initRef.current = true;
19
+ }
13
20
  if (!visible) {
14
- settings.set({ plugins: [HighchartsPlugin], extra: { holidays } });
15
21
  return React.createElement(Button, { onClick: () => setVisible(true) }, "Show chart");
16
22
  }
17
23
  return (React.createElement("div", { style: {
18
24
  height: height || DEFAULT_STORY_HEIGHT,
19
25
  width: width || DEFAULT_STORY_WIDTH,
20
26
  } },
21
- React.createElement(ChartKit, { ref: chartKitRef, type: "highcharts", data: data })));
27
+ React.createElement(ChartKit, { ref: chartKitRef, type: "highcharts", data: data, renderError: props.renderError })));
22
28
  };
@@ -0,0 +1,4 @@
1
+ import { Meta, Story } from '@storybook/react';
2
+ declare const _default: Meta<import("@storybook/react").Args>;
3
+ export default _default;
4
+ export declare const CustomErrorRender: Story<import("@storybook/react").Args>;
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { ChartKit } from '../../../../components/ChartKit';
3
+ import { ChartStory } from '../components/ChartStory';
4
+ import { Button } from '@gravity-ui/uikit';
5
+ import { CHARTKIT_ERROR_CODE, settings } from '../../../../libs';
6
+ import { HighchartsPlugin } from '../../index';
7
+ import holidays from '../../mocks/holidays';
8
+ import { noData, filledData } from '../../mocks/custom-error-render';
9
+ export default {
10
+ title: 'Plugins/Highcharts/CustomErrorRender',
11
+ component: ChartKit,
12
+ };
13
+ const Template = () => {
14
+ const [data, setData] = React.useState(noData);
15
+ const renderErrorView = React.useCallback(({ error, message, resetError }) => {
16
+ function renderFixButton() {
17
+ if (!('code' in error)) {
18
+ return null;
19
+ }
20
+ switch (error.code) {
21
+ case CHARTKIT_ERROR_CODE.UNKNOWN_PLUGIN:
22
+ return (React.createElement(Button, { onClick: () => {
23
+ settings.set({ plugins: [HighchartsPlugin], extra: { holidays } });
24
+ resetError();
25
+ } }, "Add highcharts plugin"));
26
+ case CHARTKIT_ERROR_CODE.NO_DATA:
27
+ return (React.createElement(Button, { onClick: () => {
28
+ setData(filledData);
29
+ } }, "Add data"));
30
+ default:
31
+ return null;
32
+ }
33
+ }
34
+ return (React.createElement("div", null,
35
+ React.createElement("h2", null, message),
36
+ renderFixButton()));
37
+ }, []);
38
+ return (React.createElement("div", null,
39
+ React.createElement(ChartStory, { withoutPlugin: true, data: data, visible: true, renderError: renderErrorView })));
40
+ };
41
+ export const CustomErrorRender = Template.bind({});
@@ -0,0 +1,4 @@
1
+ import { Meta, Story } from '@storybook/react';
2
+ declare const _default: Meta<import("@storybook/react").Args>;
3
+ export default _default;
4
+ export declare const NoData: Story<import("@storybook/react").Args>;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { ChartKit } from '../../../../components/ChartKit';
3
+ import { noData, filledData } from '../../mocks/no-data';
4
+ import { ChartStory } from '../components/ChartStory';
5
+ import { Button } from '@gravity-ui/uikit';
6
+ export default {
7
+ title: 'Plugins/Highcharts/NoData',
8
+ component: ChartKit,
9
+ };
10
+ const Template = () => {
11
+ const [data, setData] = React.useState(noData);
12
+ const handleUpdateData = React.useCallback(() => {
13
+ setData(filledData);
14
+ }, []);
15
+ return (React.createElement("div", null,
16
+ React.createElement("div", { style: { marginBottom: 12 } },
17
+ React.createElement(Button, { onClick: handleUpdateData }, "Add data")),
18
+ React.createElement(ChartStory, { data: data, visible: true })));
19
+ };
20
+ export const NoData = Template.bind({});
@@ -0,0 +1,3 @@
1
+ import type { HighchartsWidgetData } from '../types';
2
+ export declare const noData: HighchartsWidgetData;
3
+ export declare const filledData: HighchartsWidgetData;
@@ -0,0 +1,69 @@
1
+ const baseData = {
2
+ config: {
3
+ hideHolidays: false,
4
+ normalizeDiv: false,
5
+ normalizeSub: false,
6
+ },
7
+ libraryConfig: {
8
+ chart: {
9
+ type: 'arearange',
10
+ },
11
+ title: {
12
+ text: 'Temperature variation by day',
13
+ },
14
+ xAxis: {
15
+ type: 'datetime',
16
+ },
17
+ tooltip: {
18
+ valueSuffix: '°C',
19
+ },
20
+ },
21
+ };
22
+ export const noData = Object.assign(Object.assign({}, baseData), { data: {
23
+ graphs: [
24
+ {
25
+ name: 'Temperatures',
26
+ data: [],
27
+ },
28
+ ],
29
+ } });
30
+ export const filledData = Object.assign(Object.assign({}, baseData), { data: {
31
+ graphs: [
32
+ {
33
+ name: 'Temperatures',
34
+ data: [
35
+ [1246406400000, 10.4, 17],
36
+ [1246492800000, 10.3, 28.6],
37
+ [1246579200000, 14.8, 18.4],
38
+ [1246665600000, 11.5, 25.8],
39
+ [1246752000000, 11.1, 24.4],
40
+ [1246838400000, 17.7, 19.6],
41
+ [1246924800000, 15.1, 18.1],
42
+ [1247011200000, 15.1, 27.2],
43
+ [1247097600000, 17, 17.5],
44
+ [1247184000000, 12.6, 18.5],
45
+ [1247270400000, 12.2, 26],
46
+ [1247356800000, 15.9, 22.9],
47
+ [1247443200000, 17.1, 18.1],
48
+ [1247529600000, 13.3, 24.2],
49
+ [1247616000000, 17, 28.1],
50
+ [1247702400000, 16.2, 22.6],
51
+ [1247788800000, 10.6, 19],
52
+ [1247875200000, 11.3, 19.7],
53
+ [1247961600000, 14.1, 24.6],
54
+ [1248048000000, 14.2, 22.5],
55
+ [1248134400000, 14.1, 28.5],
56
+ [1248220800000, 14, 27],
57
+ [1248307200000, 10.2, 20.6],
58
+ [1248393600000, 13.1, 29.9],
59
+ [1248480000000, 13.7, 21.1],
60
+ [1248566400000, 15, 28.6],
61
+ [1248652800000, 12, 17.5],
62
+ [1248739200000, 17.8, 24.4],
63
+ [1248825600000, 11.7, 25.9],
64
+ [1248912000000, 13.6, 25.6],
65
+ [1248998400000, 17.3, 22.2],
66
+ ],
67
+ },
68
+ ],
69
+ } });
@@ -0,0 +1,3 @@
1
+ import type { HighchartsWidgetData } from '../types';
2
+ export declare const noData: HighchartsWidgetData;
3
+ export declare const filledData: HighchartsWidgetData;
@@ -0,0 +1,69 @@
1
+ const baseData = {
2
+ config: {
3
+ hideHolidays: false,
4
+ normalizeDiv: false,
5
+ normalizeSub: false,
6
+ },
7
+ libraryConfig: {
8
+ chart: {
9
+ type: 'arearange',
10
+ },
11
+ title: {
12
+ text: 'Temperature variation by day',
13
+ },
14
+ xAxis: {
15
+ type: 'datetime',
16
+ },
17
+ tooltip: {
18
+ valueSuffix: '°C',
19
+ },
20
+ },
21
+ };
22
+ export const noData = Object.assign(Object.assign({}, baseData), { data: {
23
+ graphs: [
24
+ {
25
+ name: 'Temperatures',
26
+ data: [],
27
+ },
28
+ ],
29
+ } });
30
+ export const filledData = Object.assign(Object.assign({}, baseData), { data: {
31
+ graphs: [
32
+ {
33
+ name: 'Temperatures',
34
+ data: [
35
+ [1246406400000, 10.4, 17],
36
+ [1246492800000, 10.3, 28.6],
37
+ [1246579200000, 14.8, 18.4],
38
+ [1246665600000, 11.5, 25.8],
39
+ [1246752000000, 11.1, 24.4],
40
+ [1246838400000, 17.7, 19.6],
41
+ [1246924800000, 15.1, 18.1],
42
+ [1247011200000, 15.1, 27.2],
43
+ [1247097600000, 17, 17.5],
44
+ [1247184000000, 12.6, 18.5],
45
+ [1247270400000, 12.2, 26],
46
+ [1247356800000, 15.9, 22.9],
47
+ [1247443200000, 17.1, 18.1],
48
+ [1247529600000, 13.3, 24.2],
49
+ [1247616000000, 17, 28.1],
50
+ [1247702400000, 16.2, 22.6],
51
+ [1247788800000, 10.6, 19],
52
+ [1247875200000, 11.3, 19.7],
53
+ [1247961600000, 14.1, 24.6],
54
+ [1248048000000, 14.2, 22.5],
55
+ [1248134400000, 14.1, 28.5],
56
+ [1248220800000, 14, 27],
57
+ [1248307200000, 10.2, 20.6],
58
+ [1248393600000, 13.1, 29.9],
59
+ [1248480000000, 13.7, 21.1],
60
+ [1248566400000, 15, 28.6],
61
+ [1248652800000, 12, 17.5],
62
+ [1248739200000, 17.8, 24.4],
63
+ [1248825600000, 11.7, 25.9],
64
+ [1248912000000, 13.6, 25.6],
65
+ [1248998400000, 17.3, 22.2],
66
+ ],
67
+ },
68
+ ],
69
+ } });
@@ -8,6 +8,7 @@ declare const HighchartsWidget: React.ForwardRefExoticComponent<{
8
8
  onLoad?: ((data?: import("../../../types").ChartKitOnLoadData<"highcharts"> | undefined) => void) | undefined;
9
9
  onRender?: ((data: import("../../../types").ChartKitOnRenderData) => void) | undefined;
10
10
  onChartLoad?: ((data: import("../../../types").ChartKitOnChartLoad<"highcharts">) => void) | undefined;
11
+ renderError?: import("../../../types").RenderError | undefined;
11
12
  onError?: import("../../../types").ChartKitOnError | undefined;
12
13
  } & {
13
14
  hoistConfigError?: boolean | undefined;
@@ -43,6 +43,9 @@ function getPointsForInitialRefresh(chart) {
43
43
  }
44
44
  function forceHoverState(chart, activePoints) {
45
45
  const chartType = get(chart, 'userOptions.chart.type');
46
+ if (!chartType) {
47
+ return;
48
+ }
46
49
  if (chartType === 'pie') {
47
50
  chart.tooltip.refresh(activePoints);
48
51
  chart.pointsForInitialRefresh = activePoints;
@@ -205,6 +208,6 @@ export const withSplitPane = (ComposedComponent) => {
205
208
  }
206
209
  }
207
210
  return React.forwardRef((props, ref) => {
208
- return React.createElement(WithSplitPane, Object.assign({ forwardedRef: ref }, props));
211
+ return React.createElement(WithSplitPane, Object.assign({}, props, { forwardedRef: ref }));
209
212
  });
210
213
  };
@@ -9,6 +9,7 @@ declare const IndicatorWidget: React.ForwardRefExoticComponent<{
9
9
  onLoad?: ((data?: import("../../../types").ChartKitOnLoadData<"indicator"> | undefined) => void) | undefined;
10
10
  onRender?: ((data: import("../../../types").ChartKitOnRenderData) => void) | undefined;
11
11
  onChartLoad?: ((data: import("../../../types").ChartKitOnChartLoad<"indicator">) => void) | undefined;
12
+ renderError?: import("../../../types").RenderError | undefined;
12
13
  onError?: import("../../../types").ChartKitOnError | undefined;
13
14
  } & {
14
15
  formatNumber?: (<T = any>(value: number, options?: T | undefined) => string) | undefined;
@@ -1,4 +1,6 @@
1
1
  import { Meta, Story } from '@storybook/react';
2
+ import '@gravity-ui/yagr/dist/index.css';
2
3
  declare const _default: Meta<import("@storybook/react").Args>;
3
4
  export default _default;
4
5
  export declare const Line: Story<any>;
6
+ export declare const Updates: Story<any>;
@@ -3,12 +3,13 @@ import { Button } from '@gravity-ui/uikit';
3
3
  import { settings } from '../../../libs';
4
4
  import { YagrPlugin } from '../../../plugins';
5
5
  import { ChartKit } from '../../../components/ChartKit';
6
- import { line10 } from './mocks/line10';
6
+ import { getNewConfig, line10 } from './mocks/line10';
7
+ import '@gravity-ui/yagr/dist/index.css';
7
8
  export default {
8
9
  title: 'Plugins/Yagr',
9
10
  component: ChartKit,
10
11
  };
11
- const Template = () => {
12
+ const LineTemplate = () => {
12
13
  const [shown, setShown] = React.useState(false);
13
14
  const chartkitRef = React.useRef();
14
15
  if (!shown) {
@@ -18,4 +19,23 @@ const Template = () => {
18
19
  return (React.createElement("div", { style: { height: 300, width: '100%' } },
19
20
  React.createElement(ChartKit, { ref: chartkitRef, id: "1", type: "yagr", data: line10 })));
20
21
  };
21
- export const Line = Template.bind({});
22
+ const UpdatesTemplate = () => {
23
+ const [shown, setShown] = React.useState(false);
24
+ const chartkitRef = React.useRef();
25
+ const [state, setState] = React.useState(line10);
26
+ const onStartUpdates = React.useCallback(() => {
27
+ setInterval(() => {
28
+ setState(getNewConfig());
29
+ }, 1000);
30
+ }, []);
31
+ if (!shown) {
32
+ settings.set({ plugins: [YagrPlugin] });
33
+ return React.createElement(Button, { onClick: () => setShown(true) }, "Show chart");
34
+ }
35
+ return (React.createElement("div", { style: { height: 300, width: '100%' } },
36
+ React.createElement(ChartKit, { ref: chartkitRef, id: "1", type: "yagr", data: state }),
37
+ React.createElement(Button, { onClick: onStartUpdates }, "Start Updates"),
38
+ React.createElement(Button, { onClick: () => setState(getNewConfig()) }, "Once")));
39
+ };
40
+ export const Line = LineTemplate.bind({});
41
+ export const Updates = UpdatesTemplate.bind({});
@@ -1,2 +1,52 @@
1
1
  import type { YagrWidgetData } from '../../types';
2
2
  export declare const line10: YagrWidgetData;
3
+ export declare const getNewConfig: () => {
4
+ libraryConfig: {
5
+ title: {
6
+ text: string;
7
+ };
8
+ chart?: import("@gravity-ui/yagr/dist/YagrCore/types").YagrChartOptions | undefined;
9
+ legend?: import("@gravity-ui/yagr/dist/YagrCore/plugins/legend/legend").LegendOptions | undefined;
10
+ axes?: Record<string, import("@gravity-ui/yagr/dist/YagrCore/types").AxisOptions> | undefined;
11
+ cursor?: import("@gravity-ui/yagr/dist/YagrCore/plugins/cursor/cursor").CursorOptions | undefined;
12
+ timeline?: number[] | undefined;
13
+ tooltip?: Partial<import("@gravity-ui/yagr/dist/YagrCore/plugins/tooltip/types").TooltipOptions> | undefined;
14
+ grid?: import("uplot").Axis.Grid | undefined;
15
+ markers?: import("@gravity-ui/yagr/dist/YagrCore/types").MarkersOptions | undefined;
16
+ scales?: Record<string, import("@gravity-ui/yagr/dist/YagrCore/types").Scale> | undefined;
17
+ series?: import("@gravity-ui/yagr/dist/YagrCore/types").RawSerieData<Omit<import("@gravity-ui/yagr/dist/YagrCore/types").SeriesOptions, "type"> & {
18
+ type?: import("@gravity-ui/yagr/dist/YagrCore/types").ChartType | undefined;
19
+ }>[] | undefined;
20
+ hooks?: import("@gravity-ui/yagr/dist/YagrCore/types").YagrHooks | undefined;
21
+ processing?: import("@gravity-ui/yagr/dist/YagrCore/types").ProcessingSettings | undefined;
22
+ editUplotOptions?: ((opts: import("uplot").Options) => import("uplot").Options) | undefined;
23
+ plugins?: Record<string, import("@gravity-ui/yagr/dist/YagrCore/types").YagrPlugin<{}, []>> | undefined;
24
+ };
25
+ data: {
26
+ timeline: number[];
27
+ graphs: {
28
+ data: number[];
29
+ name?: string | undefined;
30
+ id?: string | undefined;
31
+ scale?: string | undefined;
32
+ focus?: boolean | undefined;
33
+ show?: boolean | undefined;
34
+ color?: string | undefined;
35
+ spanGaps?: boolean | undefined;
36
+ cursorOptions?: Pick<import("@gravity-ui/yagr/dist/YagrCore/plugins/cursor/cursor").CursorOptions, "snapToValues" | "markersSize"> | undefined;
37
+ formatter?: ((value: string | number | null, serie: import("uplot").Series) => string) | undefined;
38
+ precision?: number | undefined;
39
+ snapToValues?: false | import("@gravity-ui/yagr/dist/YagrCore/types").SnapToValue | undefined;
40
+ stackGroup?: number | undefined;
41
+ title?: string | ((sIdx: number) => string) | undefined;
42
+ transform?: ((val: string | number | null, series: import("@gravity-ui/yagr/dist/YagrCore/types").DataSeries[], idx: number) => number | null) | undefined;
43
+ showInTooltip?: boolean | undefined;
44
+ type?: import("@gravity-ui/yagr/dist/YagrCore/types").ChartType | undefined;
45
+ }[];
46
+ };
47
+ sources?: Record<number, {
48
+ data: {
49
+ program: string;
50
+ };
51
+ }> | undefined;
52
+ };
@@ -61,3 +61,18 @@ export const line10 = {
61
61
  processing: {},
62
62
  },
63
63
  };
64
+ export const getNewConfig = () => {
65
+ const startPoint = (Math.random() * 10 ** 5) >> 0; // eslint-disable-line no-bitwise
66
+ return Object.assign(Object.assign({}, line10), { libraryConfig: Object.assign(Object.assign({}, line10.libraryConfig), { title: {
67
+ text: 'line: random 100 pts',
68
+ } }), data: {
69
+ timeline: new Array(100).fill(0).map((_, i) => {
70
+ return startPoint + i * 1000;
71
+ }),
72
+ graphs: line10.data.graphs.map((graph) => {
73
+ return Object.assign(Object.assign({}, graph), { data: new Array(100).fill(0).map(() => {
74
+ return (Math.random() * 100) >> 0; // eslint-disable-line no-bitwise
75
+ }) });
76
+ }),
77
+ } });
78
+ };
@@ -6,13 +6,13 @@ const DATA = {
6
6
  describe('plugins/yagr/utils', () => {
7
7
  describe('shapeYagrConfig > check chart property', () => {
8
8
  test.each([
9
- [{}, { appereance: { locale: 'en', theme: 'dark' } }],
10
- [{ appereance: { locale: 'ru' } }, { appereance: { locale: 'ru', theme: 'dark' } }],
11
- [{ appereance: { theme: 'light' } }, { appereance: { locale: 'en', theme: 'light' } }],
9
+ [{}, { appearance: { locale: 'en', theme: 'dark' } }],
10
+ [{ appearance: { locale: 'ru' } }, { appearance: { locale: 'ru', theme: 'dark' } }],
11
+ [{ appearance: { theme: 'light' } }, { appearance: { locale: 'en', theme: 'light' } }],
12
12
  [
13
13
  { series: { type: 'dots' }, select: { zoom: false }, timeMultiplier: 1 },
14
14
  {
15
- appereance: { locale: 'en', theme: 'dark' },
15
+ appearance: { locale: 'en', theme: 'dark' },
16
16
  series: { type: 'dots' },
17
17
  select: { zoom: false },
18
18
  timeMultiplier: 1,
@@ -11,6 +11,7 @@ declare const YagrWidget: React.ForwardRefExoticComponent<{
11
11
  onLoad?: ((data?: import("../../../types").ChartKitOnLoadData<"yagr"> | undefined) => void) | undefined;
12
12
  onRender?: ((data: import("../../../types").ChartKitOnRenderData) => void) | undefined;
13
13
  onChartLoad?: ((data: import("../../../types").ChartKitOnChartLoad<"yagr">) => void) | undefined;
14
+ renderError?: import("../../../types").RenderError | undefined;
14
15
  onError?: import("../../../types").ChartKitOnError | undefined;
15
16
  } & {} & {
16
17
  id: string;
@@ -23,9 +23,11 @@ const YagrWidget = React.forwardRef((props, forwardedRef) => {
23
23
  onRender === null || onRender === void 0 ? void 0 : onRender({ renderTime });
24
24
  }, [onLoad, data]);
25
25
  const onWindowResize = React.useCallback(() => {
26
- var _a;
27
- if ((_a = yagrRef.current) === null || _a === void 0 ? void 0 : _a.chart) {
28
- const chart = yagrRef.current.chart;
26
+ if (yagrRef.current) {
27
+ const chart = yagrRef.current.yagr();
28
+ if (!chart) {
29
+ return;
30
+ }
29
31
  const root = chart.root;
30
32
  const height = root.offsetHeight;
31
33
  const width = root.offsetWidth;
@@ -38,9 +40,9 @@ const YagrWidget = React.forwardRef((props, forwardedRef) => {
38
40
  onWindowResize();
39
41
  },
40
42
  }), [onWindowResize]);
41
- React.useLayoutEffect(() => {
43
+ React.useEffect(() => {
42
44
  var _a, _b, _c, _d;
43
- const yagr = (_a = yagrRef.current) === null || _a === void 0 ? void 0 : _a.chart;
45
+ const yagr = (_a = yagrRef.current) === null || _a === void 0 ? void 0 : _a.yagr();
44
46
  if (!yagr) {
45
47
  return;
46
48
  }
@@ -67,11 +69,11 @@ const YagrWidget = React.forwardRef((props, forwardedRef) => {
67
69
  handlers.mouseDown = null;
68
70
  }
69
71
  });
70
- });
72
+ }, []);
71
73
  React.useLayoutEffect(() => {
72
74
  var _a;
73
- onChartLoad === null || onChartLoad === void 0 ? void 0 : onChartLoad({ widget: (_a = yagrRef.current) === null || _a === void 0 ? void 0 : _a.chart });
74
- }, []);
75
+ onChartLoad === null || onChartLoad === void 0 ? void 0 : onChartLoad({ widget: (_a = yagrRef.current) === null || _a === void 0 ? void 0 : _a.yagr() });
76
+ }, [yagrRef, onChartLoad]);
75
77
  return (React.createElement(YagrComponent, { ref: yagrRef, id: id, config: config, debug: debug, onChartLoad: handleChartLoading }));
76
78
  });
77
79
  export default YagrWidget;
@@ -1,7 +1,7 @@
1
1
  import moment from 'moment';
2
2
  import { formatTooltip } from './tooltip';
3
3
  const calcOption = (d) => {
4
- return typeof d === 'object'
4
+ return typeof d === 'object' && d !== null
5
5
  ? Object.values(d).reduce((_, t) => {
6
6
  return t;
7
7
  })
@@ -16,7 +16,7 @@ export const renderTooltip = (data) => {
16
16
  const cfg = data.yagr.config;
17
17
  const timeMultiplier = cfg.chart.timeMultiplier || 1;
18
18
  const opts = data.options;
19
- const { x, pinned } = data;
19
+ const { x, state } = data;
20
20
  let sumTotal = 0;
21
21
  const rows = Object.values(data.scales).reduce((acc, scale) => {
22
22
  sumTotal += scale.sum || 0;
@@ -27,7 +27,7 @@ export const renderTooltip = (data) => {
27
27
  const maxLines = calcOption(opts.maxLines);
28
28
  const valueFormatter = calcOption(opts.value);
29
29
  // eslint-disable-next-line no-nested-ternary
30
- const hiddenRowsNumber = pinned
30
+ const hiddenRowsNumber = state.pinned
31
31
  ? undefined
32
32
  : lines > maxLines
33
33
  ? Math.abs(maxLines - lines)
@@ -50,6 +50,6 @@ export const renderTooltip = (data) => {
50
50
  tooltipFormatOptions.sum = valueFormatter(sumTotal);
51
51
  }
52
52
  return formatTooltip(tooltipFormatOptions, {
53
- lastVisibleRowIndex: pinned ? rows.length - 1 : maxLines - 1,
53
+ lastVisibleRowIndex: state.pinned ? rows.length - 1 : maxLines - 1,
54
54
  });
55
55
  };
@@ -87,7 +87,7 @@ export const shapeYagrConfig = (args) => {
87
87
  const { data, libraryConfig, theme } = args;
88
88
  const config = Object.assign(Object.assign({}, libraryConfig), { timeline: data.timeline, series: data.graphs });
89
89
  const chart = {
90
- appereance: {
90
+ appearance: {
91
91
  locale: settings.get('lang'),
92
92
  theme,
93
93
  },
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { ChartKitWidget } from './widget';
3
+ import { ChartKitError } from '../libs';
3
4
  export type { ChartKitHolidays } from './misc';
4
5
  export declare type ChartKitLang = 'ru' | 'en';
5
6
  export declare type ChartKitType = keyof ChartKitWidget;
@@ -38,6 +39,7 @@ export declare type ChartKitProps<T extends ChartKitType> = {
38
39
  * @param data
39
40
  */
40
41
  onChartLoad?: (data: ChartKitOnChartLoad<T>) => void;
42
+ renderError?: RenderError;
41
43
  onError?: ChartKitOnError;
42
44
  } & {
43
45
  [key in keyof Omit<ChartKitWidget[T], 'data' | 'widget'>]: ChartKitWidget[T][key];
@@ -46,4 +48,10 @@ export declare type ChartKitPlugin = {
46
48
  type: ChartKitType;
47
49
  renderer: React.LazyExoticComponent<any>;
48
50
  };
51
+ export declare type RenderErrorOpts = {
52
+ message: string;
53
+ error: ChartKitError | Error;
54
+ resetError: () => void;
55
+ };
56
+ export declare type RenderError = (opts: RenderErrorOpts) => React.ReactNode;
49
57
  export type { ChartKitWidget };
@@ -0,0 +1,2 @@
1
+ import type { ChartKitError } from '../libs';
2
+ export declare function getErrorMessage(error: ChartKitError | Error): string;
@@ -0,0 +1,5 @@
1
+ import { i18n } from '../i18n';
2
+ export function getErrorMessage(error) {
3
+ const code = 'code' in error && error.code;
4
+ return (error.message || code || i18n('error', 'label_unknown-error')).toString();
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/chartkit",
3
- "version": "2.10.1",
3
+ "version": "2.11.1-beta.0",
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",
@@ -13,7 +13,7 @@
13
13
  "access": "public"
14
14
  },
15
15
  "dependencies": {
16
- "@gravity-ui/yagr": "^2.2.5",
16
+ "@gravity-ui/yagr": "^3.1.0",
17
17
  "bem-cn-lite": "^4.1.0",
18
18
  "highcharts": "^8.2.2",
19
19
  "highcharts-react-official": "^3.0.0",
@@ -65,9 +65,9 @@
65
65
  "typescript": "^4.2.3"
66
66
  },
67
67
  "peerDependencies": {
68
- "react": "^16.0.0 || ^17.0.0 || ^18.0.0",
68
+ "@gravity-ui/uikit": "^4.0.0",
69
69
  "moment": "^2.19.3",
70
- "@gravity-ui/uikit": "^4.0.0"
70
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0"
71
71
  },
72
72
  "scripts": {
73
73
  "test": "jest",
@@ -1,7 +0,0 @@
1
- /// <reference types="react" />
2
- import type { ChartKitError } from '../../libs';
3
- declare type Props = {
4
- error: ChartKitError | Error;
5
- };
6
- export declare const ErrorView: ({ error }: Props) => JSX.Element;
7
- export {};
@@ -1,7 +0,0 @@
1
- import React from 'react';
2
- import { i18n } from '../../i18n';
3
- export const ErrorView = ({ error }) => {
4
- const code = 'code' in error && error.code;
5
- const message = error.message || code || i18n('error', 'label_unknown-error');
6
- return React.createElement("div", null, message);
7
- };