@pie-lib/charting 5.15.7 → 5.17.0-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 (132) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/NEXT.CHANGELOG.json +1 -0
  3. package/lib/__tests__/axes.test.js +181 -0
  4. package/lib/__tests__/chart-setup.test.js +58 -0
  5. package/lib/__tests__/chart-type.test.js +42 -0
  6. package/lib/__tests__/chart.test.js +108 -0
  7. package/lib/__tests__/grid.test.js +48 -0
  8. package/lib/__tests__/mark-label.test.js +57 -0
  9. package/lib/__tests__/utils.js +56 -0
  10. package/lib/__tests__/utils.test.js +197 -0
  11. package/lib/axes.js +75 -30
  12. package/lib/bars/__tests__/bar.test.js +62 -0
  13. package/lib/bars/__tests__/histogram.test.js +64 -0
  14. package/lib/bars/__tests__/utils.js +56 -0
  15. package/lib/bars/bar.js +1 -1
  16. package/lib/bars/common/__tests__/bars.test.js +100 -0
  17. package/lib/bars/common/__tests__/utils.js +56 -0
  18. package/lib/bars/common/bars.js +36 -2
  19. package/lib/bars/histogram.js +1 -1
  20. package/lib/chart-setup.js +1 -1
  21. package/lib/chart-type.js +5 -5
  22. package/lib/chart-types.js +3 -3
  23. package/lib/chart.js +26 -11
  24. package/lib/common/__tests__/drag-handle.test.js +134 -0
  25. package/lib/common/__tests__/utils.js +56 -0
  26. package/lib/common/drag-handle.js +12 -6
  27. package/lib/common/drag-icon.js +8 -25
  28. package/lib/common/styles.js +1 -1
  29. package/lib/grid.js +1 -1
  30. package/lib/index.js +1 -1
  31. package/lib/line/__tests__/line-cross.test.js +64 -0
  32. package/lib/line/__tests__/line-dot.test.js +64 -0
  33. package/lib/line/__tests__/utils.js +56 -0
  34. package/lib/line/common/__tests__/drag-handle.test.js +134 -0
  35. package/lib/line/common/__tests__/line.test.js +128 -0
  36. package/lib/line/common/__tests__/utils.js +56 -0
  37. package/lib/line/common/drag-handle.js +10 -5
  38. package/lib/line/common/line.js +1 -1
  39. package/lib/line/line-cross.js +17 -6
  40. package/lib/line/line-dot.js +11 -3
  41. package/lib/mark-label.js +21 -12
  42. package/lib/plot/__tests__/dot.test.js +64 -0
  43. package/lib/plot/__tests__/line.test.js +64 -0
  44. package/lib/plot/__tests__/utils.js +56 -0
  45. package/lib/plot/common/__tests__/plot.test.js +103 -0
  46. package/lib/plot/common/__tests__/utils.js +56 -0
  47. package/lib/plot/common/plot.js +4 -2
  48. package/lib/plot/dot.js +2 -2
  49. package/lib/plot/line.js +2 -2
  50. package/lib/tool-menu.js +1 -5
  51. package/lib/utils.js +1 -1
  52. package/package.json +4 -4
  53. package/src/__tests__/__snapshots__/axes.test.jsx.snap +564 -0
  54. package/src/__tests__/__snapshots__/chart-type.test.jsx.snap +14 -0
  55. package/src/__tests__/__snapshots__/chart.test.jsx.snap +610 -0
  56. package/src/__tests__/__snapshots__/grid.test.jsx.snap +28 -0
  57. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +67 -0
  58. package/src/__tests__/axes.test.jsx +146 -0
  59. package/src/__tests__/chart-setup.test.jsx +47 -0
  60. package/src/__tests__/chart-type.test.jsx +29 -0
  61. package/src/__tests__/chart.test.jsx +87 -0
  62. package/src/__tests__/grid.test.jsx +25 -0
  63. package/src/__tests__/mark-label.test.jsx +31 -0
  64. package/src/__tests__/utils.js +30 -0
  65. package/src/__tests__/utils.test.js +100 -0
  66. package/src/axes.jsx +59 -23
  67. package/src/bars/__tests__/__snapshots__/bar.test.jsx.snap +43 -0
  68. package/src/bars/__tests__/__snapshots__/histogram.test.jsx.snap +45 -0
  69. package/src/bars/__tests__/bar.test.jsx +37 -0
  70. package/src/bars/__tests__/histogram.test.jsx +38 -0
  71. package/src/bars/__tests__/utils.js +30 -0
  72. package/src/bars/common/__tests__/__snapshots__/bars.test.jsx.snap +110 -0
  73. package/src/bars/common/__tests__/bars.test.jsx +69 -0
  74. package/src/bars/common/__tests__/utils.js +30 -0
  75. package/src/bars/common/bars.jsx +37 -1
  76. package/src/chart-type.js +7 -3
  77. package/src/chart-types.js +2 -2
  78. package/src/chart.jsx +15 -5
  79. package/src/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +45 -0
  80. package/src/common/__tests__/drag-handle.test.jsx +88 -0
  81. package/src/common/__tests__/utils.js +30 -0
  82. package/src/common/drag-handle.jsx +18 -10
  83. package/src/common/drag-icon.jsx +6 -21
  84. package/src/line/__tests__/__snapshots__/line-cross.test.jsx.snap +45 -0
  85. package/src/line/__tests__/__snapshots__/line-dot.test.jsx.snap +45 -0
  86. package/src/line/__tests__/line-cross.test.jsx +38 -0
  87. package/src/line/__tests__/line-dot.test.jsx +38 -0
  88. package/src/line/__tests__/utils.js +30 -0
  89. package/src/line/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +44 -0
  90. package/src/line/common/__tests__/__snapshots__/line.test.jsx.snap +141 -0
  91. package/src/line/common/__tests__/drag-handle.test.jsx +88 -0
  92. package/src/line/common/__tests__/line.test.jsx +82 -0
  93. package/src/line/common/__tests__/utils.js +30 -0
  94. package/src/line/common/drag-handle.jsx +9 -4
  95. package/src/line/line-cross.js +4 -1
  96. package/src/line/line-dot.js +17 -7
  97. package/src/mark-label.jsx +19 -7
  98. package/src/plot/__tests__/__snapshots__/dot.test.jsx.snap +45 -0
  99. package/src/plot/__tests__/__snapshots__/line.test.jsx.snap +45 -0
  100. package/src/plot/__tests__/dot.test.jsx +38 -0
  101. package/src/plot/__tests__/line.test.jsx +38 -0
  102. package/src/plot/__tests__/utils.js +30 -0
  103. package/src/plot/common/__tests__/__snapshots__/plot.test.jsx.snap +96 -0
  104. package/src/plot/common/__tests__/plot.test.jsx +70 -0
  105. package/src/plot/common/__tests__/utils.js +30 -0
  106. package/src/plot/common/plot.jsx +6 -1
  107. package/src/plot/dot.js +1 -1
  108. package/src/plot/line.js +1 -1
  109. package/src/tool-menu.jsx +0 -4
  110. package/lib/axes.js.map +0 -1
  111. package/lib/bars/bar.js.map +0 -1
  112. package/lib/bars/common/bars.js.map +0 -1
  113. package/lib/bars/histogram.js.map +0 -1
  114. package/lib/chart-setup.js.map +0 -1
  115. package/lib/chart-type.js.map +0 -1
  116. package/lib/chart-types.js.map +0 -1
  117. package/lib/chart.js.map +0 -1
  118. package/lib/common/drag-handle.js.map +0 -1
  119. package/lib/common/drag-icon.js.map +0 -1
  120. package/lib/common/styles.js.map +0 -1
  121. package/lib/grid.js.map +0 -1
  122. package/lib/index.js.map +0 -1
  123. package/lib/line/common/drag-handle.js.map +0 -1
  124. package/lib/line/common/line.js.map +0 -1
  125. package/lib/line/line-cross.js.map +0 -1
  126. package/lib/line/line-dot.js.map +0 -1
  127. package/lib/mark-label.js.map +0 -1
  128. package/lib/plot/common/plot.js.map +0 -1
  129. package/lib/plot/dot.js.map +0 -1
  130. package/lib/plot/line.js.map +0 -1
  131. package/lib/tool-menu.js.map +0 -1
  132. package/lib/utils.js.map +0 -1
@@ -0,0 +1,146 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import ChartAxes, { TickComponent, RawChartAxes } from '../axes';
4
+ import { graphProps } from './utils';
5
+
6
+ describe('ChartAxes', () => {
7
+ const wrapper = (extras) => {
8
+ const defaults = {
9
+ classes: {},
10
+ className: 'className',
11
+ graphProps: graphProps(),
12
+ xBand: {
13
+ bandwidth: () => {},
14
+ },
15
+ };
16
+ const props = { ...defaults, ...extras };
17
+ return shallow(<ChartAxes {...props} />);
18
+ };
19
+
20
+ describe('snapshot', () => {
21
+ it('renders', () => expect(wrapper()).toMatchSnapshot());
22
+ });
23
+ });
24
+
25
+ describe('RawChartAxes', () => {
26
+ const wrapper = (extras) => {
27
+ const defaults = {
28
+ classes: {},
29
+ className: 'className',
30
+ graphProps: graphProps(),
31
+ xBand: {
32
+ bandwidth: () => {},
33
+ rangeRound: () => {},
34
+ },
35
+ categories: [],
36
+ };
37
+ const props = { ...defaults, ...extras };
38
+ return shallow(<RawChartAxes {...props} />);
39
+ };
40
+
41
+ describe('snapshot', () => {
42
+ it('renders', () => expect(wrapper()).toMatchSnapshot());
43
+
44
+ it('renders if graphProps is not defined', () => expect(wrapper({ graphProps: undefined })).toMatchSnapshot());
45
+
46
+ it('renders if categories are not defined', () => expect(wrapper({ categories: undefined })).toMatchSnapshot());
47
+ });
48
+ });
49
+
50
+ describe('splitText method', () => {
51
+ const wrapper = (extras) => {
52
+ const xBand = jest.fn();
53
+ xBand.bandwidth = jest.fn();
54
+
55
+ const defaults = {
56
+ graphProps: graphProps(),
57
+ xBand,
58
+ };
59
+ const props = { ...defaults, ...extras };
60
+ return shallow(<TickComponent {...props} />);
61
+ };
62
+
63
+ it('splits a string into chunks of up to the specified length', () => {
64
+ const w = wrapper();
65
+ const input = 'This is a test string for splitText function';
66
+ const output = w.instance().splitText(input, 20);
67
+ expect(output).toEqual(['This is a test', 'string for splitText', 'function']);
68
+ });
69
+
70
+ it('returns an array with a single string when the input is less than the specified length', () => {
71
+ const w = wrapper();
72
+ const input = 'Short text';
73
+ const output = w.instance().splitText(input, 20);
74
+ expect(output).toEqual(['Short text']);
75
+ });
76
+
77
+ it('splits a string into chunks of exact length when no spaces are present', () => {
78
+ const w = wrapper();
79
+ const input = 'ThisisateststringforsplitTextfunction';
80
+ const output = w.instance().splitText(input, 10);
81
+ expect(output).toEqual(['Thisisates', 'tstringfor', 'splitTextf', 'unction']);
82
+ });
83
+
84
+ it('returns an empty array when the input is an empty string', () => {
85
+ const w = wrapper();
86
+ const input = '';
87
+ const output = w.instance().splitText(input, 20);
88
+ expect(output).toEqual([]);
89
+ });
90
+
91
+ it('returns an empty array when the input is null', () => {
92
+ const w = wrapper();
93
+ const input = null;
94
+ const output = w.instance().splitText(input, 20);
95
+ expect(output).toEqual([]);
96
+ });
97
+ });
98
+
99
+ describe('TickComponent', () => {
100
+ const wrapper = (extras) => {
101
+ const xBand = jest.fn();
102
+ xBand.bandwidth = jest.fn();
103
+
104
+ const defaults = {
105
+ graphProps: graphProps(),
106
+ xBand,
107
+ };
108
+ const props = { ...defaults, ...extras };
109
+ return shallow(<TickComponent {...props} />);
110
+ };
111
+
112
+ describe('snapshot', () => {
113
+ it('renders', () => expect(wrapper()).toMatchSnapshot());
114
+ });
115
+
116
+ describe('snapshot1', () => {
117
+ it('renders', () =>
118
+ expect(
119
+ wrapper({
120
+ formattedValue: '0-test',
121
+ categories: [{ value: 1, label: 'test' }],
122
+ }),
123
+ ).toMatchSnapshot());
124
+ });
125
+
126
+ describe('logic', () => {
127
+ const onChange = jest.fn();
128
+ const onChangeCategory = jest.fn();
129
+ const w = wrapper({
130
+ formattedValue: '0-test',
131
+ categories: [{ value: 1, label: 'test' }],
132
+ onChange,
133
+ onChangeCategory,
134
+ });
135
+
136
+ it('calls onChangeCategory', () => {
137
+ w.instance().changeCategory(0, 'new label');
138
+ expect(onChangeCategory).toHaveBeenCalledWith(0, { value: 1, label: 'new label' });
139
+ });
140
+
141
+ it('calls onChange', () => {
142
+ w.instance().deleteCategory(0);
143
+ expect(onChange).toHaveBeenCalledWith([]);
144
+ });
145
+ });
146
+ });
@@ -0,0 +1,47 @@
1
+ import { resetValues } from '../chart-setup';
2
+
3
+ describe('resetValues', () => {
4
+ let data;
5
+ let range;
6
+ let model;
7
+ let onChange;
8
+
9
+ beforeEach(() => {
10
+ range = { min: 0, max: 10, step: 1 };
11
+ data = [
12
+ { value: 2 },
13
+ { value: 11 },
14
+ { value: 5.5 },
15
+ { value: 2.0000000001 }, // A float close to an integer
16
+ { value: 2.9999999999 }, // Another float close to an integer
17
+ ];
18
+ model = { someField: 'someValue', data };
19
+ onChange = jest.fn();
20
+ });
21
+
22
+ it('should reset values greater than range.max to zero', () => {
23
+ resetValues(data, true, range, onChange, model);
24
+ expect(data[1].value).toBe(0);
25
+ });
26
+
27
+ it('should reset values that are not multiples of range.step to zero', () => {
28
+ resetValues(data, true, range, onChange, model);
29
+ expect(data[2].value).toBe(0);
30
+ });
31
+
32
+ it('should not reset values that are within range and multiples of range.step', () => {
33
+ resetValues(data, true, range, onChange, model);
34
+ expect(data[0].value).toBe(2);
35
+ });
36
+
37
+ it('should not reset floating point values that are close to multiples of range.step', () => {
38
+ resetValues(data, true, range, onChange, model);
39
+ expect(data[3].value).toBe(2.0000000001); // remains unchanged
40
+ expect(data[4].value).toBe(2.9999999999); // remains unchanged
41
+ });
42
+
43
+ it('should not call onChange when updateModel is false', () => {
44
+ resetValues(data, false, range, onChange, model);
45
+ expect(onChange).not.toHaveBeenCalled();
46
+ });
47
+ });
@@ -0,0 +1,29 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import ChartType from '../chart-type';
4
+
5
+ describe('ChartType', () => {
6
+ let wrapper;
7
+ let props;
8
+ const onChange = jest.fn();
9
+
10
+ beforeEach(() => {
11
+ props = {
12
+ classes: {},
13
+ value: 'bar',
14
+ onChange,
15
+ };
16
+
17
+ wrapper = (newProps) => {
18
+ const configureProps = { ...props, newProps };
19
+
20
+ return shallow(<ChartType {...configureProps} />);
21
+ };
22
+ });
23
+
24
+ describe('renders', () => {
25
+ it('snapshot', () => {
26
+ expect(wrapper()).toMatchSnapshot();
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,87 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { Chart } from '../chart';
4
+ import { graphProps } from './utils';
5
+
6
+ describe('ChartAxes', () => {
7
+ let onDataChange = jest.fn();
8
+ const wrapper = (extras) => {
9
+ const defaults = {
10
+ classes: {},
11
+ onDataChange,
12
+ className: 'className',
13
+ graphProps: graphProps(),
14
+ xBand: () => {
15
+ return {
16
+ bandwidth: () => {},
17
+ };
18
+ },
19
+ charts: [
20
+ {
21
+ type: 'bar',
22
+ Component: () => <div />,
23
+ },
24
+ ],
25
+ chartType: 'bar',
26
+ domain: {},
27
+ range: {
28
+ min: 0,
29
+ max: 10,
30
+ },
31
+ size: {
32
+ width: 100,
33
+ height: 100,
34
+ },
35
+ data: [],
36
+ };
37
+ const props = { ...defaults, ...extras };
38
+ return shallow(<Chart {...props} />);
39
+ };
40
+
41
+ describe('snapshot', () => {
42
+ it('renders', () => {
43
+ jest.spyOn(Chart.prototype, 'generateMaskId').mockReturnValue('chart-2645');
44
+ let w = wrapper();
45
+ expect(w).toMatchSnapshot();
46
+ });
47
+
48
+ it('renders if size is not defined', () => {
49
+ jest.spyOn(Chart.prototype, 'generateMaskId').mockReturnValue('chart-1553');
50
+ let w = wrapper({ size: undefined });
51
+ expect(w).toMatchSnapshot();
52
+ });
53
+
54
+ it('renders without chartType property', () => {
55
+ jest.spyOn(Chart.prototype, 'generateMaskId').mockReturnValue('chart-4286');
56
+ let w = wrapper({ chartType: null });
57
+ expect(w).toMatchSnapshot();
58
+ });
59
+
60
+ it('renders without chartType and charts properties', () =>
61
+ expect(wrapper({ chartType: null, charts: null })).toMatchSnapshot());
62
+
63
+ it('renders without chartType property and empty charts property', () =>
64
+ expect(wrapper({ chartType: null, charts: [] })).toMatchSnapshot());
65
+
66
+ it('renders with chartType property and empty charts property', () =>
67
+ expect(wrapper({ charts: [] })).toMatchSnapshot());
68
+ });
69
+
70
+ describe('logic', () => {
71
+ it('changeData', () => {
72
+ let w = wrapper();
73
+
74
+ w.instance().changeData();
75
+
76
+ expect(onDataChange).toHaveBeenCalled();
77
+ });
78
+
79
+ it('getChart', () => {
80
+ const w = wrapper();
81
+
82
+ const chart = w.instance().getChart();
83
+
84
+ expect(chart.type).toEqual('bar');
85
+ });
86
+ });
87
+ });
@@ -0,0 +1,25 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { Grid } from '../grid';
4
+ import { graphProps } from './utils';
5
+
6
+ describe('Grid', () => {
7
+ let w;
8
+ const wrapper = (extras) => {
9
+ const defaults = {
10
+ classes: {},
11
+ className: 'className',
12
+ graphProps: graphProps(),
13
+ xBand: {
14
+ bandwidth: () => {},
15
+ },
16
+ };
17
+ const props = { ...defaults, ...extras };
18
+ return shallow(<Grid {...props} />);
19
+ };
20
+ describe('snapshot', () => {
21
+ it('renders', () => expect(wrapper()).toMatchSnapshot());
22
+
23
+ it('renders if graphProps is not defined', () => expect(wrapper({ graphProps: undefined })).toMatchSnapshot());
24
+ });
25
+ });
@@ -0,0 +1,31 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import { MarkLabel } from '../mark-label';
4
+ import { graphProps as getGraphProps } from './utils';
5
+
6
+ describe('MarkLabel', () => {
7
+ let w;
8
+ let onChange = jest.fn();
9
+ const wrapper = (extras) => {
10
+ const defaults = {
11
+ classes: {},
12
+ defineChart: false,
13
+ className: 'className',
14
+ onChange,
15
+ mark: { x: 1, y: 1 },
16
+ graphProps: getGraphProps(0, 10, 0, 10),
17
+ };
18
+ const props = { ...defaults, ...extras };
19
+ return shallow(<MarkLabel {...props} />);
20
+ };
21
+ describe('snapshot', () => {
22
+ it('renders', () => {
23
+ w = wrapper();
24
+ expect(w).toMatchSnapshot();
25
+ });
26
+ it('renders', () => {
27
+ w = wrapper({ mark: { x: 10, y: 10 } });
28
+ expect(w).toMatchSnapshot();
29
+ });
30
+ });
31
+ });
@@ -0,0 +1,30 @@
1
+ export const scaleMock = () => {
2
+ const fn = jest.fn((n) => n);
3
+ fn.invert = jest.fn((n) => n);
4
+ return fn;
5
+ };
6
+
7
+ export const graphProps = (dmin = 0, dmax = 1, rmin = 0, rmax = 1) => ({
8
+ scale: {
9
+ x: scaleMock(),
10
+ y: scaleMock(),
11
+ },
12
+ snap: {
13
+ x: jest.fn((n) => n),
14
+ y: jest.fn((n) => n),
15
+ },
16
+ domain: {
17
+ min: dmin,
18
+ max: dmax,
19
+ step: 1,
20
+ },
21
+ range: {
22
+ min: rmin,
23
+ max: rmax,
24
+ step: 1,
25
+ },
26
+ size: {
27
+ width: 400,
28
+ height: 400,
29
+ },
30
+ });
@@ -0,0 +1,100 @@
1
+ import * as utils from '../utils';
2
+
3
+ const xy = (x, y) => ({ x, y });
4
+
5
+ describe('utils', () => {
6
+ describe('getTickValues', () => {
7
+ const assertGetTickValues = (range, points) => {
8
+ it(`converts ${range} -> ${points}`, () => {
9
+ const result = utils.getTickValues(range);
10
+ expect(result).toEqual(points);
11
+ });
12
+ };
13
+
14
+ assertGetTickValues({ min: 0, max: 5, step: 1 }, [0, 1, 2, 3, 4, 5]);
15
+ assertGetTickValues({ min: 0, max: 5, step: 0.5 }, [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]);
16
+ assertGetTickValues({ min: 0.4, max: 2, step: 0.3 }, [0.4, 0.7, 1, 1.3, 1.6, 1.9]);
17
+ });
18
+
19
+ describe('getDomainAndRangeByChartType', () => {
20
+ const assertGetDomainAndRangeByChartType = (domain, range, chartType, correctValues) => {
21
+ it('returns correct values for domain and range', () => {
22
+ const result = utils.getDomainAndRangeByChartType(domain, range, chartType);
23
+ expect(result).toEqual(correctValues);
24
+ });
25
+ };
26
+
27
+ assertGetDomainAndRangeByChartType({ min: -1, max: 4 }, { min: 1, max: 2, step: 1 }, 'line', {
28
+ domain: { min: 0, max: 1, step: 1, labelStep: 1 },
29
+ range: { min: 1, max: 2, step: 1, labelStep: 1 },
30
+ });
31
+ assertGetDomainAndRangeByChartType({ min: -1, max: 4 }, { min: 0.1, max: 2, labelStep: 0.1 }, 'line', {
32
+ domain: { min: 0, max: 1, step: 1, labelStep: 1 },
33
+ range: { min: 0.1, max: 2, step: 0.1, labelStep: 0.1 },
34
+ });
35
+ assertGetDomainAndRangeByChartType({ min: -1, max: 4 }, { min: 0.2, max: 2.4, step: 0.1 }, 'dotPlot', {
36
+ domain: { min: 0, max: 1, step: 1, labelStep: 1 },
37
+ range: { min: 0, max: 2, step: 1, labelStep: 0.1 },
38
+ });
39
+ });
40
+
41
+ describe('getGridLinesAndAxisByChartType', () => {
42
+ const assertGetGridLinesAndAxisByChartType = (range, chartType, gridLines) => {
43
+ it('returns proper grid values', () => {
44
+ const result = utils.getGridLinesAndAxisByChartType(range, chartType);
45
+ expect(result).toEqual(gridLines);
46
+ });
47
+ };
48
+
49
+ assertGetGridLinesAndAxisByChartType({ min: 0, max: 1, step: 1 }, 'lineDot', {
50
+ verticalLines: undefined,
51
+ horizontalLines: [0, 1],
52
+ leftAxis: true,
53
+ });
54
+
55
+ assertGetGridLinesAndAxisByChartType({ min: 0, max: 1, step: 1 }, 'lineCross', {
56
+ verticalLines: undefined,
57
+ horizontalLines: [0, 1],
58
+ leftAxis: true,
59
+ });
60
+
61
+ assertGetGridLinesAndAxisByChartType({ min: 0, max: 1, step: 1 }, 'bar', {
62
+ verticalLines: [],
63
+ horizontalLines: [0, 1],
64
+ leftAxis: true,
65
+ });
66
+
67
+ assertGetGridLinesAndAxisByChartType({ min: 0, max: 1, step: 1 }, 'dotPlot', {
68
+ verticalLines: [],
69
+ horizontalLines: [],
70
+ leftAxis: false,
71
+ });
72
+ });
73
+
74
+ describe('getTopPadding', () => {
75
+ const assertGetTopPadding = (barWidth, topPadding) => {
76
+ it('returns proper top padding', () => {
77
+ const result = utils.getTopPadding(barWidth);
78
+ expect(result).toEqual(topPadding);
79
+ });
80
+ };
81
+
82
+ assertGetTopPadding(20, 50);
83
+ assertGetTopPadding(35, 30);
84
+ assertGetTopPadding(55, 15);
85
+ assertGetTopPadding(65, 0);
86
+ });
87
+
88
+ describe('getRotateAngle', () => {
89
+ const assertGetRotateAngle = ({ fontSize, height }, rotateAngle) => {
90
+ it('returns proper rotate angle', () => {
91
+ const result = utils.getRotateAngle(fontSize, height);
92
+ expect(result).toEqual(rotateAngle);
93
+ });
94
+ };
95
+
96
+ assertGetRotateAngle({ fontSize: 14, height: 14 }, 0);
97
+ assertGetRotateAngle({ fontSize: 14, height: 28 }, 25);
98
+ assertGetRotateAngle({ fontSize: 14, height: 42 }, 25);
99
+ });
100
+ });
package/src/axes.jsx CHANGED
@@ -24,6 +24,12 @@ export class TickComponent extends React.Component {
24
24
  };
25
25
  }
26
26
 
27
+ componentDidUpdate(prevProps) {
28
+ if (this.props.autoFocus && !prevProps.autoFocus) {
29
+ this.props.onAutoFocusUsed();
30
+ }
31
+ }
32
+
27
33
  handleAlertDialog = (open, callback) =>
28
34
  this.setState(
29
35
  {
@@ -126,6 +132,8 @@ export class TickComponent extends React.Component {
126
132
  changeInteractiveEnabled,
127
133
  changeEditableEnabled,
128
134
  error,
135
+ autoFocus,
136
+ hiddenLabelRef,
129
137
  } = this.props;
130
138
 
131
139
  if (!formattedValue) {
@@ -136,7 +144,7 @@ export class TickComponent extends React.Component {
136
144
  const { changeEditable, changeInteractive } = chartingOptions || {};
137
145
  const index = parseInt(formattedValue.split('-')[0], 10);
138
146
  const category = categories[index];
139
- const { deletable, editable, interactive, label, correctness, autoFocus, inDefineChart } = category || {};
147
+ const { deletable, editable, interactive, label, correctness } = category || {};
140
148
  const barX = xBand(bandKey({ label }, index));
141
149
  const longestCategory = (categories || []).reduce((a, b) => {
142
150
  const lengthA = a && a.label ? a.label.length : 0;
@@ -144,8 +152,6 @@ export class TickComponent extends React.Component {
144
152
 
145
153
  return lengthA > lengthB ? a : b;
146
154
  });
147
-
148
- const longestLabel = (longestCategory && longestCategory.label) || '';
149
155
  const distinctMessages = error ? [...new Set(Object.values(error))].join(' ') : '';
150
156
 
151
157
  return (
@@ -158,23 +164,18 @@ export class TickComponent extends React.Component {
158
164
  style={{ pointerEvents: 'none', overflow: 'visible' }}
159
165
  >
160
166
  {index === 0 && (
161
- <div
162
- id="hiddenLabel"
163
- style={{
164
- position: 'absolute',
165
- visibility: 'hidden',
166
- wordBreak: 'break-word',
167
- overflow: 'visible',
168
- maxWidth: barWidth,
169
- display: 'block',
170
- }}
171
- >
172
- {longestLabel}
173
- </div>
167
+ <MarkLabel
168
+ isHiddenLabel={true}
169
+ inputRef={hiddenLabelRef}
170
+ disabled={true}
171
+ mark={longestCategory}
172
+ graphProps={graphProps}
173
+ barWidth={barWidth}
174
+ />
174
175
  )}
175
176
 
176
177
  <MarkLabel
177
- autoFocus={inDefineChart ? defineChart && autoFocus : autoFocus}
178
+ autoFocus={defineChart && autoFocus}
178
179
  inputRef={(r) => (this.input = r)}
179
180
  disabled={!defineChart && !editable}
180
181
  mark={category}
@@ -271,6 +272,7 @@ export class TickComponent extends React.Component {
271
272
  style={{ pointerEvents: 'visible', overflow: 'visible' }}
272
273
  >
273
274
  <Checkbox
275
+ className={classes.customColor}
274
276
  style={{ position: 'fixed' }}
275
277
  checked={interactive}
276
278
  onChange={(e) => this.changeInteractive(index, e.target.checked)}
@@ -287,6 +289,7 @@ export class TickComponent extends React.Component {
287
289
  style={{ pointerEvents: 'visible', overflow: 'visible' }}
288
290
  >
289
291
  <Checkbox
292
+ className={classes.customColor}
290
293
  style={{ position: 'fixed' }}
291
294
  checked={editable}
292
295
  onChange={(e) => this.changeEditable(index, e.target.checked)}
@@ -333,6 +336,8 @@ TickComponent.propTypes = {
333
336
  chartingOptions: PropTypes.object,
334
337
  changeInteractiveEnabled: PropTypes.bool,
335
338
  changeEditableEnabled: PropTypes.bool,
339
+ autoFocus: PropTypes.bool,
340
+ onAutoFocusUsed: PropTypes.func,
336
341
  };
337
342
 
338
343
  export class RawChartAxes extends React.Component {
@@ -352,14 +357,30 @@ export class RawChartAxes extends React.Component {
352
357
  chartingOptions: PropTypes.object,
353
358
  changeInteractiveEnabled: PropTypes.bool,
354
359
  changeEditableEnabled: PropTypes.bool,
360
+ autoFocus: PropTypes.bool,
361
+ onAutoFocusUsed: PropTypes.func,
355
362
  };
356
363
 
357
- state = { height: 0 };
364
+ state = { height: 0, width: 0 };
358
365
 
359
366
  componentDidMount() {
360
- const height = document.getElementById('hiddenLabel') ? document.getElementById('hiddenLabel').offsetHeight : 0;
367
+ if (this.hiddenLabelRef) {
368
+ const boundingClientRect = this.hiddenLabelRef.getBoundingClientRect();
369
+ this.setState({
370
+ height: Math.floor(boundingClientRect.height),
371
+ width: Math.floor(boundingClientRect.width),
372
+ });
373
+ }
374
+ }
361
375
 
362
- this.setState({ height });
376
+ componentDidUpdate(prevProps, prevState, snapshot) {
377
+ if (this.hiddenLabelRef) {
378
+ const width = Math.floor(this.hiddenLabelRef.getBoundingClientRect().width);
379
+
380
+ if (width !== this.state.width) {
381
+ this.setState({ width });
382
+ }
383
+ }
363
384
  }
364
385
 
365
386
  render() {
@@ -377,12 +398,14 @@ export class RawChartAxes extends React.Component {
377
398
  changeInteractiveEnabled,
378
399
  changeEditableEnabled,
379
400
  theme,
401
+ autoFocus,
402
+ onAutoFocusUsed,
380
403
  error,
381
404
  } = this.props;
382
405
 
383
406
  const { axis, axisLine, tick } = classes;
384
407
  const { scale = {}, range = {}, domain = {}, size = {} } = graphProps || {};
385
- const { height } = this.state;
408
+ const { height, width } = this.state;
386
409
 
387
410
  const bottomScale = xBand && typeof xBand.rangeRound === 'function' && xBand.rangeRound([0, size.width]);
388
411
 
@@ -392,7 +415,10 @@ export class RawChartAxes extends React.Component {
392
415
 
393
416
  const rowTickValues = getTickValues({ ...range, step: range.labelStep });
394
417
  const fontSize = theme && theme.typography ? theme.typography.fontSize : 14;
395
- const rotate = getRotateAngle(fontSize, height);
418
+ // this mostly applies for labels that are not editable
419
+ const rotateBecauseOfHeight = getRotateAngle(fontSize, height);
420
+ // this applies for labels that are editable
421
+ const rotateBecauseOfWidth = width > barWidth ? 25 : 0;
396
422
 
397
423
  const getTickLabelProps = (value) => ({
398
424
  dy: 4,
@@ -401,15 +427,20 @@ export class RawChartAxes extends React.Component {
401
427
 
402
428
  const getTickComponent = (props) => {
403
429
  const properties = {
430
+ hiddenLabelRef: (ref) => {
431
+ this.hiddenLabelRef = ref;
432
+ },
404
433
  classes,
405
434
  categories,
406
435
  xBand,
407
436
  bandWidth,
408
437
  barWidth,
409
- rotate,
438
+ rotate: rotateBecauseOfHeight || rotateBecauseOfWidth,
410
439
  top,
411
440
  defineChart,
412
441
  chartingOptions,
442
+ autoFocus,
443
+ onAutoFocusUsed,
413
444
  error,
414
445
  onChangeCategory,
415
446
  changeInteractiveEnabled,
@@ -447,6 +478,8 @@ export class RawChartAxes extends React.Component {
447
478
  textLabelProps={() => ({ textAnchor: 'middle' })}
448
479
  tickFormat={(count) => count}
449
480
  tickComponent={getTickComponent}
481
+ autoFocus={autoFocus}
482
+ onAutoFocusUsed={onAutoFocusUsed}
450
483
  />
451
484
  </React.Fragment>
452
485
  );
@@ -481,6 +514,9 @@ const ChartAxes = withStyles(
481
514
  fontSize: theme.typography.fontSize - 2,
482
515
  fill: theme.palette.error.main,
483
516
  },
517
+ customColor: {
518
+ color: `${color.tertiary()} !important`
519
+ },
484
520
  }),
485
521
  { withTheme: true },
486
522
  )(RawChartAxes);