Skip to content

Commit

Permalink
feat(state): 支持多 view 的状态设置和获取 (#2773)
Browse files Browse the repository at this point in the history
* feat(state): 支持多 view 的状态设置和获取

* test(bidirectional-bar): 增加对称条形图 state 设置单测

* test(box): 增加箱型图 state 设置单测

* feat(violin): 小提琴图增加状态样式设置 & 增加文档和单测

* test(mix): 增加 mix 图表state状态设置的单测

* fix: 修复 ci 问题

* fix: 修复单测错误
  • Loading branch information
visiky authored Aug 11, 2021
1 parent 25fbe90 commit c64270e
Show file tree
Hide file tree
Showing 13 changed files with 26,397 additions and 129 deletions.
26,002 changes: 26,002 additions & 0 deletions __tests__/data/mix-data.ts

Large diffs are not rendered by default.

64 changes: 64 additions & 0 deletions __tests__/unit/plots/bidirectional-bar/state-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { BidirectionalBar } from '../../../../src';
import { data } from '../../../data/bi-directional';
import { createDiv } from '../../../utils/dom';

describe('Bidirectional', () => {
const plot = new BidirectionalBar(createDiv('default'), {
width: 400,
height: 400,
data,
xField: 'country',
yField: ['2016年耕地总面积', '2016年转基因种植面积'],
state: {
active: {
style: {
stroke: 'blue',
},
},
selected: {
style: {
fill: 'red',
},
},
},
});
plot.render();

it('setState & getState', () => {
plot.setState('selected', (data: any) => {
return data.country === '加拿大';
});

expect(plot.getStates().length).toBe(2);
expect(
plot.chart.views[0].geometries[0].elements
.find((ele) => (ele.getModel().data as any).country === '加拿大')
.shape.attr('fill')
).toBe('red');
expect(
plot.chart.views[1].geometries[0].elements
.find((ele) => (ele.getModel().data as any).country === '加拿大')
.shape.attr('fill')
).toBe('red');

plot.setState('active', (data: any) => {
return data.country === '巴西';
});

expect(plot.getStates().length).toBe(4);
expect(
plot.chart.views[0].geometries[0].elements
.find((ele) => (ele.getModel().data as any).country === '巴西')
.shape.attr('stroke')
).toBe('blue');
expect(
plot.chart.views[1].geometries[0].elements
.find((ele) => (ele.getModel().data as any).country === '巴西')
.shape.attr('stroke')
).toBe('blue');
});

afterAll(() => {
plot.destroy();
});
});
52 changes: 52 additions & 0 deletions __tests__/unit/plots/box/state-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Box } from '../../../../src';
import { boxData } from '../../../data/box';
import { createDiv } from '../../../utils/dom';

describe('box', () => {
it('setState', () => {
const plot = new Box(createDiv(), {
width: 400,
height: 500,
data: boxData,
xField: 'x',
yField: ['low', 'q1', 'median', 'q3', 'high'],
state: {
active: {
style: {
stroke: 'yellow',
},
},
selected: {
style: {
stroke: 'blue',
fill: 'red',
},
},
},
});

plot.render();

plot.setState('selected', (data) => {
// @ts-ignore
return data.x === 'Oceania';
});

expect(plot.getStates().length).toBe(1);

const geometry = plot.chart.geometries[0];
const elements = geometry.elements;
expect(elements[0].shape.attr('stroke')).toBe('blue');
expect(elements[0].shape.attr('fill')).toBe('red');

plot.setState('active', (data) => {
// @ts-ignore
return data.x === 'Oceania';
});

expect(plot.getStates().length).toBe(2);
expect(elements[0].shape.attr('stroke')).toBe('yellow');

plot.destroy();
});
});
153 changes: 153 additions & 0 deletions __tests__/unit/plots/multi-view/state-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { Mix } from '../../../../src';
import { createDiv } from '../../../utils/dom';
import { MIX_POINT_DATAS as data } from '../../../data/mix-data';

describe('mix', () => {
it('plots, setState', () => {
const plot = new Mix(createDiv(), {
appendPadding: 8,
tooltip: { shared: true },
syncViewPadding: true,
plots: [
{
type: 'column',
options: {
data: [
{ date: '2015-02', value: 160 },
{ date: '2015-08', value: 245 },
{ date: '2016-01', value: 487 },
{ date: '2017-02', value: 500 },
{ date: '2018-01', value: 503 },
{ date: '2018-08', value: 514 },
],
xField: 'date',
yField: 'value',
state: {
selected: {
style: {
fill: 'red',
},
},
active: {
style: {
stroke: 'green',
},
},
},
},
},
{
type: 'line',
options: {
data: [
{ date: '2015-02', value: null },
{ date: '2015-08', value: 0.029 },
{ date: '2016-01', value: 0.094 },
{ date: '2017-02', value: 0.148 },
{ date: '2018-01', value: 0.055 },
{ date: '2018-08', value: 0.045 },
],
xField: 'date',
yField: 'value',
},
},
],
});

plot.render();

plot.setState('selected', (data) => {
return Array.isArray(data) ? false : data.date === '2018-08';
});
expect(plot.getStates().length).toBe(1);
expect(plot.chart.views[0].geometries[0].elements[5].shape.attr('fill')).toBe('red');

plot.setState('active', (data) => {
return Array.isArray(data) ? false : data.date === '2018-08';
});
expect(plot.getStates().length).toBe(2);
expect(plot.chart.views[0].geometries[0].elements[5].shape.attr('stroke')).toBe('green');

plot.destroy();
});

it('views, setState', () => {
const plot = new Mix('container', {
tooltip: false,
views: [
{
region: {
start: { x: 0, y: 0 },
end: { x: 0.5, y: 1 },
},
data: data.slice(0, 400),
meta: {
price: { nice: true },
},
axes: {},
geometries: [
{
type: 'point',
xField: 'carat',
yField: 'price',
state: {
selected: {
style: {
stroke: 'red',
},
},
},
mapping: {},
},
],
},
{
region: {
start: { x: 0.5, y: 0 },
end: { x: 1, y: 1 },
},
data: data.slice(0, 400),
meta: {
x: { nice: true },
},
axes: { x: { min: 0, tickCount: 5 } },
geometries: [
{
type: 'point',
xField: 'depth',
yField: 'x',
state: {
selected: {
style: {
stroke: 'yellow',
},
},
},
mapping: { shape: 'circle' },
},
],
},
],
});

plot.render();
plot.setState('selected', (data) => {
// @ts-ignore
return data.cut === 'Fair';
});
// @ts-ignore
plot.chart.views[0].geometries[0].elements
.filter((ele) => (ele.getModel().data as any).cut === 'Fair')
.forEach((ele) => {
expect(ele.shape.attr('stroke')).toBe('red');
});
// @ts-ignore
plot.chart.views[1].geometries[0].elements
.filter((ele) => (ele.getModel().data as any).cut === 'Fair')
.forEach((ele) => {
expect(ele.shape.attr('stroke')).toBe('yellow');
});

plot.destroy();
});
});
75 changes: 75 additions & 0 deletions __tests__/unit/plots/violin/state-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { Violin } from '../../../../src';
import { BASE_VIOLIN_DATA } from '../../../data/violin';
import { createDiv } from '../../../utils/dom';

describe('violin', () => {
const plot = new Violin(createDiv(), {
width: 400,
height: 500,
data: BASE_VIOLIN_DATA,
xField: 'type',
yField: 'value',
state: {
selected: {
style: {
stroke: 'blue',
fill: 'red',
},
},
},
box: {
state: {
selected: {
style: {
stroke: 'green',
fill: 'red',
},
},
},
},
});

plot.render();

it('setState', () => {
plot.setState('selected', (data) => {
// @ts-ignore
return data.x === 'SepalLength';
});
expect(plot.getStates().length).toBe(plot.chart.views.length);
// @ts-ignore
expect(
plot.chart.views[0].geometries[0].elements
.find((ele) => (ele.getModel().data as any).x === 'SepalLength')
.shape.attr('stroke')
).toBe('blue');
// @ts-ignore
expect(
plot.chart.views[1].geometries[0].elements
.find((ele) => (ele.getModel().data as any).x === 'SepalLength')
.shape.attr('stroke')
).toBe('green');
// @ts-ignore
expect(
plot.chart.views[2].geometries[0].elements
.find((ele) => (ele.getModel().data as any).x === 'SepalLength')
.shape.attr('stroke')
).toBe('green');
// @ts-ignore
expect(
plot.chart.views[3].geometries[0].elements
.find((ele) => (ele.getModel().data as any).x === 'SepalLength')
.shape.attr('stroke')
).toBe('green');

plot.setState('active', (data) => {
// @ts-ignore
return data.x === 'SepalLength';
});
expect(plot.getStates().length).toBe(plot.chart.views.length * 2);
});

afterAll(() => {
plot.destroy();
});
});
17 changes: 15 additions & 2 deletions docs/api/plots/violin.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,16 @@ type KdeOptions = {

#### box

<description>**optional** _boolean_</description>
<description>**optional** _boolean | BoxOption_</description>

Whether to show box plot. Default show box plot, you could hide box plot by setting `box: false`.
Whether to show box plot. Default show box plot, you can custom box plot with _BoxOption_. In addition, you could also hide box plot by setting `box: false`.

```ts
type BoxOption = {
// configuration of state style of box, more detail to see: `state`
state: State;
}
```
#### shape
Expand All @@ -85,6 +92,12 @@ Violin graphic style.
`markdown:docs/common/color.en.md`
#### state
<description>**optional** _object_</description>
`markdown:docs/common/state-style.en.md`
### Plot Components
`markdown:docs/common/common-component.en.md`
Expand Down
Loading

0 comments on commit c64270e

Please sign in to comment.