@pie-lib/charting 5.15.7 → 5.16.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.
- package/CHANGELOG.md +32 -70
- package/NEXT.CHANGELOG.json +1 -0
- package/package.json +38 -5
- package/src/__tests__/__snapshots__/axes.test.jsx.snap +564 -0
- package/src/__tests__/__snapshots__/chart-type.test.jsx.snap +14 -0
- package/src/__tests__/__snapshots__/chart.test.jsx.snap +610 -0
- package/src/__tests__/__snapshots__/grid.test.jsx.snap +28 -0
- package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +67 -0
- package/src/__tests__/axes.test.jsx +146 -0
- package/src/__tests__/chart-setup.test.jsx +47 -0
- package/src/__tests__/chart-type.test.jsx +29 -0
- package/src/__tests__/chart.test.jsx +87 -0
- package/src/__tests__/grid.test.jsx +25 -0
- package/src/__tests__/mark-label.test.jsx +31 -0
- package/src/__tests__/utils.js +30 -0
- package/src/__tests__/utils.test.js +100 -0
- package/src/axes.jsx +59 -23
- package/src/bars/__tests__/__snapshots__/bar.test.jsx.snap +43 -0
- package/src/bars/__tests__/__snapshots__/histogram.test.jsx.snap +45 -0
- package/src/bars/__tests__/bar.test.jsx +37 -0
- package/src/bars/__tests__/histogram.test.jsx +38 -0
- package/src/bars/__tests__/utils.js +30 -0
- package/src/bars/common/__tests__/__snapshots__/bars.test.jsx.snap +110 -0
- package/src/bars/common/__tests__/bars.test.jsx +69 -0
- package/src/bars/common/__tests__/utils.js +30 -0
- package/src/bars/common/bars.jsx +37 -1
- package/src/chart-type.js +7 -3
- package/src/chart-types.js +2 -2
- package/src/chart.jsx +15 -5
- package/src/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +45 -0
- package/src/common/__tests__/drag-handle.test.jsx +88 -0
- package/src/common/__tests__/utils.js +30 -0
- package/src/common/drag-handle.jsx +18 -10
- package/src/common/drag-icon.jsx +6 -21
- package/src/line/__tests__/__snapshots__/line-cross.test.jsx.snap +45 -0
- package/src/line/__tests__/__snapshots__/line-dot.test.jsx.snap +45 -0
- package/src/line/__tests__/line-cross.test.jsx +38 -0
- package/src/line/__tests__/line-dot.test.jsx +38 -0
- package/src/line/__tests__/utils.js +30 -0
- package/src/line/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +44 -0
- package/src/line/common/__tests__/__snapshots__/line.test.jsx.snap +141 -0
- package/src/line/common/__tests__/drag-handle.test.jsx +88 -0
- package/src/line/common/__tests__/line.test.jsx +82 -0
- package/src/line/common/__tests__/utils.js +30 -0
- package/src/line/common/drag-handle.jsx +9 -4
- package/src/line/line-cross.js +4 -1
- package/src/line/line-dot.js +17 -7
- package/src/mark-label.jsx +19 -7
- package/src/plot/__tests__/__snapshots__/dot.test.jsx.snap +45 -0
- package/src/plot/__tests__/__snapshots__/line.test.jsx.snap +45 -0
- package/src/plot/__tests__/dot.test.jsx +38 -0
- package/src/plot/__tests__/line.test.jsx +38 -0
- package/src/plot/__tests__/utils.js +30 -0
- package/src/plot/common/__tests__/__snapshots__/plot.test.jsx.snap +96 -0
- package/src/plot/common/__tests__/plot.test.jsx +70 -0
- package/src/plot/common/__tests__/utils.js +30 -0
- package/src/plot/common/plot.jsx +6 -1
- package/src/plot/dot.js +1 -1
- package/src/plot/line.js +1 -1
- package/src/tool-menu.jsx +0 -4
- package/lib/axes.js +0 -598
- package/lib/axes.js.map +0 -1
- package/lib/bars/bar.js +0 -86
- package/lib/bars/bar.js.map +0 -1
- package/lib/bars/common/bars.js +0 -267
- package/lib/bars/common/bars.js.map +0 -1
- package/lib/bars/histogram.js +0 -87
- package/lib/bars/histogram.js.map +0 -1
- package/lib/chart-setup.js +0 -458
- package/lib/chart-setup.js.map +0 -1
- package/lib/chart-type.js +0 -71
- package/lib/chart-type.js.map +0 -1
- package/lib/chart-types.js +0 -31
- package/lib/chart-types.js.map +0 -1
- package/lib/chart.js +0 -423
- package/lib/chart.js.map +0 -1
- package/lib/common/drag-handle.js +0 -169
- package/lib/common/drag-handle.js.map +0 -1
- package/lib/common/drag-icon.js +0 -69
- package/lib/common/drag-icon.js.map +0 -1
- package/lib/common/styles.js +0 -40
- package/lib/common/styles.js.map +0 -1
- package/lib/grid.js +0 -104
- package/lib/grid.js.map +0 -1
- package/lib/index.js +0 -40
- package/lib/index.js.map +0 -1
- package/lib/line/common/drag-handle.js +0 -152
- package/lib/line/common/drag-handle.js.map +0 -1
- package/lib/line/common/line.js +0 -261
- package/lib/line/common/line.js.map +0 -1
- package/lib/line/line-cross.js +0 -157
- package/lib/line/line-cross.js.map +0 -1
- package/lib/line/line-dot.js +0 -123
- package/lib/line/line-dot.js.map +0 -1
- package/lib/mark-label.js +0 -246
- package/lib/mark-label.js.map +0 -1
- package/lib/plot/common/plot.js +0 -278
- package/lib/plot/common/plot.js.map +0 -1
- package/lib/plot/dot.js +0 -123
- package/lib/plot/dot.js.map +0 -1
- package/lib/plot/line.js +0 -152
- package/lib/plot/line.js.map +0 -1
- package/lib/tool-menu.js +0 -146
- package/lib/tool-menu.js.map +0 -1
- package/lib/utils.js +0 -244
- 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
|
|
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
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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={
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|