Skip to content

Commit e420761

Browse files
authored
feat: 对称条形图(Bi-directional) (#1746)
* feat: 对称条形图(new) * feat: 完善小细节部分 * feat: 完整的实现和单测 * feat: 基本完善对称条形图 * fix: 优化几个小问题
1 parent ef7d201 commit e420761

File tree

14 files changed

+716
-0
lines changed

14 files changed

+716
-0
lines changed

__tests__/data/bi-directional.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export const data = [
2+
{ country: '乌拉圭', '2016年耕地总面积': 13.4, '2016年转基因种植面积': 12.3 },
3+
{ country: '巴拉圭', '2016年耕地总面积': 14.4, '2016年转基因种植面积': 6.3 },
4+
{ country: '南非', '2016年耕地总面积': 18.4, '2016年转基因种植面积': 8.3 },
5+
{ country: '巴基斯坦', '2016年耕地总面积': 34.4, '2016年转基因种植面积': 13.8 },
6+
{ country: '阿根廷', '2016年耕地总面积': 44.4, '2016年转基因种植面积': 19.5 },
7+
{ country: '巴西', '2016年耕地总面积': 24.4, '2016年转基因种植面积': 18.8 },
8+
{ country: '加拿大', '2016年耕地总面积': 54.4, '2016年转基因种植面积': 24.7 },
9+
{ country: '中国', '2016年耕地总面积': 104.4, '2016年转基因种植面积': 5.3 },
10+
{ country: '美国', '2016年耕地总面积': 165.2, '2016年转基因种植面积': 72.9 },
11+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { BidirectionalBar } from '../../../../src';
2+
import { data } from '../../../data/bi-directional';
3+
import { createDiv } from '../../../utils/dom';
4+
5+
describe('Bidirectional axis', () => {
6+
it('x*y*yAxis', () => {
7+
const bidirectional = new BidirectionalBar(createDiv('x*y*xAxis'), {
8+
width: 400,
9+
height: 400,
10+
data,
11+
xField: 'country',
12+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
13+
yAxis: {
14+
'2016年耕地总面积': {
15+
nice: true,
16+
},
17+
'2016年转基因种植面积': {
18+
nice: true,
19+
min: 0,
20+
max: 100,
21+
},
22+
},
23+
});
24+
bidirectional.render();
25+
26+
const firstView = bidirectional.chart.views[0];
27+
const secondView = bidirectional.chart.views[1];
28+
29+
//@ts-ignore
30+
expect(firstView.options.axes['2016年耕地总面积'].nice).toEqual(true);
31+
//@ts-ignore
32+
expect(secondView.options.axes['2016年转基因种植面积'].nice).toEqual(true);
33+
//@ts-ignore
34+
expect(secondView.options.axes['2016年转基因种植面积'].min).toEqual(0);
35+
//@ts-ignore
36+
expect(secondView.options.axes['2016年转基因种植面积'].max).toEqual(100);
37+
//@ts-ignore
38+
expect(secondView.options.axes.country).toEqual(false);
39+
});
40+
41+
it('x*y*xAxis*false', () => {
42+
const bidirectional = new BidirectionalBar(createDiv('x*y*xAxis*false'), {
43+
width: 400,
44+
height: 400,
45+
data,
46+
xField: 'country',
47+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
48+
xAxis: false,
49+
});
50+
bidirectional.render();
51+
52+
const firstView = bidirectional.chart.views[0];
53+
const secondView = bidirectional.chart.views[1];
54+
// @ts-ignore
55+
expect(firstView.options.axes.country).toEqual(false);
56+
//@ts-ignore
57+
expect(secondView.options.axes.country).toEqual(false);
58+
});
59+
it('x*y*yAxis*false', () => {
60+
const bidirectional = new BidirectionalBar(createDiv('x*y*yAxis*false'), {
61+
width: 400,
62+
height: 400,
63+
data,
64+
xField: 'country',
65+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
66+
yAxis: false,
67+
});
68+
bidirectional.render();
69+
70+
const firstView = bidirectional.chart.views[0];
71+
const secondView = bidirectional.chart.views[1];
72+
// @ts-ignore
73+
expect(firstView.options.axes['2016年耕地总面积']).toEqual(false);
74+
//@ts-ignore
75+
expect(secondView.options.axes['2016年转基因种植面积']).toEqual(false);
76+
});
77+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { transformData } from '../../../../src/plots/bidirectional-bar/utils';
2+
import { data } from '../../../data/bi-directional';
3+
4+
export const hopedata = [
5+
{ country: '乌拉圭', type: '2016年耕地总面积', '2016年耕地总面积': 13.4 },
6+
{ country: '巴拉圭', type: '2016年耕地总面积', '2016年耕地总面积': 14.4 },
7+
{ country: '南非', type: '2016年耕地总面积', '2016年耕地总面积': 18.4 },
8+
{ country: '巴基斯坦', type: '2016年耕地总面积', '2016年耕地总面积': 34.4 },
9+
{ country: '阿根廷', type: '2016年耕地总面积', '2016年耕地总面积': 44.4 },
10+
{ country: '巴西', type: '2016年耕地总面积', '2016年耕地总面积': 24.4 },
11+
{ country: '加拿大', type: '2016年耕地总面积', '2016年耕地总面积': 54.4 },
12+
{ country: '中国', type: '2016年耕地总面积', '2016年耕地总面积': 104.4 },
13+
{ country: '美国', type: '2016年耕地总面积', '2016年耕地总面积': 165.2 },
14+
15+
{ country: '乌拉圭', type: '2016年转基因种植面积', '2016年转基因种植面积': 12.3 },
16+
{ country: '巴拉圭', type: '2016年转基因种植面积', '2016年转基因种植面积': 6.3 },
17+
{ country: '南非', type: '2016年转基因种植面积', '2016年转基因种植面积': 8.3 },
18+
{ country: '巴基斯坦', type: '2016年转基因种植面积', '2016年转基因种植面积': 13.8 },
19+
{ country: '阿根廷', type: '2016年转基因种植面积', '2016年转基因种植面积': 19.5 },
20+
{ country: '巴西', type: '2016年转基因种植面积', '2016年转基因种植面积': 18.8 },
21+
{ country: '加拿大', type: '2016年转基因种植面积', '2016年转基因种植面积': 24.7 },
22+
{ country: '中国', type: '2016年转基因种植面积', '2016年转基因种植面积': 5.3 },
23+
{ country: '美国', type: '2016年转基因种植面积', '2016年转基因种植面积': 72.9 },
24+
];
25+
describe('bullet*data*transfrom', () => {
26+
it('data*transfrom', () => {
27+
// 校验数据转换
28+
const transDS = transformData('country', ['2016年耕地总面积', '2016年转基因种植面积'], data);
29+
expect(transDS).toEqual(hopedata);
30+
});
31+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { BidirectionalBar } from '../../../../src';
2+
import { data } from '../../../data/bi-directional';
3+
import { createDiv } from '../../../utils/dom';
4+
5+
describe('Bidirectional', () => {
6+
it('default', () => {
7+
const bidirectional = new BidirectionalBar(createDiv('default'), {
8+
width: 400,
9+
height: 400,
10+
data,
11+
xField: 'country',
12+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
13+
});
14+
bidirectional.render();
15+
16+
expect(bidirectional.type).toEqual('bidirectional-bar');
17+
18+
const leftView = bidirectional.chart.views[0];
19+
const rightView = bidirectional.chart.views[1];
20+
const leftG = bidirectional.chart.views[0].geometries[0];
21+
const rightG = bidirectional.chart.views[1].geometries[0];
22+
//@ts-ignore
23+
expect(leftView.options.axes.country.position).toEqual('top');
24+
//@ts-ignore
25+
expect(rightView.options.axes.country).toEqual(false);
26+
expect(bidirectional.chart.getOptions().scales.type.sync).toEqual(true);
27+
28+
// 类型
29+
expect(leftG.type).toBe('interval');
30+
expect(rightG.type).toBe('interval');
31+
32+
// x & y
33+
const LpositionFields = leftG.getAttribute('position').getFields();
34+
const RpositionFields = rightG.getAttribute('position').getFields();
35+
expect(LpositionFields).toHaveLength(2);
36+
expect(LpositionFields[0]).toBe('country');
37+
expect(LpositionFields[1]).toBe('2016年耕地总面积');
38+
39+
expect(RpositionFields).toHaveLength(2);
40+
expect(RpositionFields[0]).toBe('country');
41+
expect(RpositionFields[1]).toBe('2016年转基因种植面积');
42+
43+
const LcolorAttribute = leftG.getAttribute('color');
44+
const LseriesFields = LcolorAttribute.getFields();
45+
46+
expect(LseriesFields).toHaveLength(1);
47+
expect(LseriesFields[0]).toBe('type');
48+
49+
const RcolorAttribute = rightG.getAttribute('color');
50+
const RseriesFields = RcolorAttribute.getFields();
51+
52+
expect(RseriesFields).toHaveLength(1);
53+
expect(RseriesFields[0]).toBe('type');
54+
55+
expect(bidirectional.chart.getController('legend').visible).toEqual(true);
56+
57+
expect(bidirectional.chart.getController('legend').getComponents()[0].direction).toEqual('bottom');
58+
59+
expect(bidirectional.chart.getController('legend').getComponents()[0].extra.scale.field).toEqual('type');
60+
});
61+
it('x*y*color', () => {
62+
const bidirectional = new BidirectionalBar(createDiv('x*y*color'), {
63+
width: 400,
64+
height: 400,
65+
data,
66+
xField: 'country',
67+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
68+
});
69+
bidirectional.render();
70+
71+
const leftG = bidirectional.chart.views[0].geometries[0];
72+
const rightG = bidirectional.chart.views[1].geometries[0];
73+
const LseriesFields = leftG.getAttribute('color').getFields();
74+
const RseriesFields = rightG.getAttribute('color').getFields();
75+
76+
expect(LseriesFields).toHaveLength(1);
77+
expect(LseriesFields[0]).toBe('type');
78+
expect(RseriesFields).toHaveLength(1);
79+
expect(RseriesFields[0]).toBe('type');
80+
});
81+
82+
it('x*y*color with color', () => {
83+
const palette = ['red', 'green'];
84+
const bidirectional = new BidirectionalBar(createDiv('x*y*color with color'), {
85+
width: 400,
86+
height: 400,
87+
data,
88+
xField: 'country',
89+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
90+
color: palette,
91+
});
92+
bidirectional.render();
93+
94+
bidirectional.render();
95+
96+
const leftG = bidirectional.chart.views[0].geometries[0];
97+
const rightG = bidirectional.chart.views[1].geometries[0];
98+
99+
leftG.elements.forEach((element) => {
100+
const color = element.getModel().color;
101+
expect(color).toBe(palette[0]);
102+
});
103+
104+
rightG.elements.forEach((element) => {
105+
const color = element.getModel().color;
106+
expect(color).toBe(palette[1]);
107+
});
108+
});
109+
110+
it('widthRatio', () => {
111+
const bidirectional = new BidirectionalBar(createDiv('widthRatio'), {
112+
width: 400,
113+
height: 400,
114+
data,
115+
xField: 'country',
116+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
117+
widthRatio: 0.7,
118+
});
119+
bidirectional.render();
120+
121+
const leftG = bidirectional.chart.views[0].geometries[0];
122+
const rightG = bidirectional.chart.views[1].geometries[0];
123+
expect(leftG.theme.columnWidthRatio).toBe(0.7);
124+
expect(rightG.theme.columnWidthRatio).toBe(0.7);
125+
});
126+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { BidirectionalBar } from '../../../../src';
2+
import { data } from '../../../data/bi-directional';
3+
import { createDiv } from '../../../utils/dom';
4+
5+
describe('Bidirectional laebl', () => {
6+
it('x*y*label*true', () => {
7+
const bidirectional = new BidirectionalBar(createDiv(), {
8+
width: 400,
9+
height: 400,
10+
data,
11+
xField: 'country',
12+
yField: ['2016年转基因种植面积', '2016年耕地总面积'],
13+
label: {
14+
position: 'middle',
15+
style: {
16+
fill: '#fff',
17+
},
18+
},
19+
});
20+
bidirectional.render();
21+
22+
const leftG = bidirectional.chart.views[0].geometries[0];
23+
const rightG = bidirectional.chart.views[1].geometries[0];
24+
25+
// @ts-ignore
26+
expect(leftG.labelOption.cfg.position).toEqual('middle');
27+
// @ts-ignore
28+
expect(leftG.labelOption.cfg.style.fill).toEqual('#fff');
29+
30+
// @ts-ignore
31+
expect(rightG.labelOption.cfg.position).toEqual('middle');
32+
// @ts-ignore
33+
expect(rightG.labelOption.cfg.style.fill).toEqual('#fff');
34+
});
35+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { BidirectionalBar } from '../../../../src';
2+
import { data } from '../../../data/bi-directional';
3+
import { createDiv } from '../../../utils/dom';
4+
5+
describe('Bidirectional layout', () => {
6+
it('layout*default*horizontal', () => {
7+
const bidirectional = new BidirectionalBar(createDiv('x*y*horizontal'), {
8+
width: 400,
9+
height: 400,
10+
data,
11+
xField: 'country',
12+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
13+
});
14+
bidirectional.render();
15+
16+
const firstView = bidirectional.chart.views[0];
17+
const secondView = bidirectional.chart.views[1];
18+
expect(firstView.getCoordinate().isTransposed).toBe(true);
19+
expect(secondView.getCoordinate().isTransposed).toBe(true);
20+
//@ts-ignore
21+
expect(firstView.getCoordinate().isReflectX).toBe(true);
22+
});
23+
it('layout*default*vertical', () => {
24+
const bidirectional = new BidirectionalBar(createDiv('x*y*vertical'), {
25+
width: 400,
26+
height: 600,
27+
data,
28+
xField: 'country',
29+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
30+
layout: 'vertical',
31+
yAxis: {
32+
'2016年耕地总面积': {
33+
nice: true,
34+
},
35+
'2016年转基因种植面积': {
36+
min: 0,
37+
max: 100,
38+
},
39+
},
40+
});
41+
bidirectional.render();
42+
43+
const firstView = bidirectional.chart.views[0];
44+
const secondView = bidirectional.chart.views[1];
45+
46+
//@ts-ignore
47+
expect(firstView.options.axes.country.position).toEqual('bottom');
48+
49+
expect(firstView.getCoordinate().isTransposed).toBe(false);
50+
expect(secondView.getCoordinate().isTransposed).toBe(false);
51+
//@ts-ignore
52+
expect(secondView.getCoordinate().isReflectY).toBe(true);
53+
//@ts-ignore
54+
expect(secondView.options.axes['2016年转基因种植面积'].min).toEqual(0);
55+
//@ts-ignore
56+
expect(secondView.options.axes['2016年转基因种植面积'].max).toEqual(100);
57+
});
58+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { BidirectionalBar } from '../../../../src';
2+
import { data } from '../../../data/bi-directional';
3+
import { createDiv } from '../../../utils/dom';
4+
5+
describe('Bidirectional legend', () => {
6+
it('x*y*legend*top', () => {
7+
const bidirectional = new BidirectionalBar(createDiv(), {
8+
width: 400,
9+
height: 400,
10+
data,
11+
xField: 'country',
12+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
13+
legend: {
14+
position: 'top',
15+
},
16+
});
17+
bidirectional.render();
18+
expect(bidirectional.chart.getController('legend').getComponents()[0].direction).toEqual('top');
19+
});
20+
it('x*y*legend*false', () => {
21+
const bidirectional = new BidirectionalBar(createDiv(), {
22+
width: 400,
23+
height: 400,
24+
data,
25+
xField: 'country',
26+
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
27+
legend: false,
28+
});
29+
bidirectional.render();
30+
expect(bidirectional.chart.getController('legend').getComponents().length).toEqual(0);
31+
});
32+
});

0 commit comments

Comments
 (0)