Skip to content

Commit

Permalink
feat: 双轴图新增 slider (#2287)
Browse files Browse the repository at this point in the history
* feat: 双轴图新增 slider

* feat: 补充 slider 单测

* fix: ci

* fix: isBetween 移入 number 中

* fix: reolve conversation

* docs: 补充文档

* fix: confict

Co-authored-by: liufu.lf <liufu.lf@antfin.com>
  • Loading branch information
lxfu1 and liufu.lf authored Feb 3, 2021
1 parent 947889b commit 0276528
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 30 deletions.
31 changes: 31 additions & 0 deletions __tests__/data/pv-uv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,34 @@ export const UV_DATA_MULTI = [
{ date: '0608', uv: 3431, site: 'c' },
{ date: '0609', uv: 4054, site: 'c' },
];

export const uvBillData = [
{ time: '2019-03', value: 350, type: 'uv' },
{ time: '2019-04', value: 900, type: 'uv' },
{ time: '2019-05', value: 300, type: 'uv' },
{ time: '2019-06', value: 450, type: 'uv' },
{ time: '2019-07', value: 470, type: 'uv' },
{ time: '2019-03', value: 220, type: 'bill' },
{ time: '2019-04', value: 300, type: 'bill' },
{ time: '2019-05', value: 250, type: 'bill' },
{ time: '2019-06', value: 220, type: 'bill' },
{ time: '2019-07', value: 362, type: 'bill' },
];

export const transformData = [
{ time: '2019-03', count: 800, name: 'a' },
{ time: '2019-04', count: 600, name: 'a' },
{ time: '2019-05', count: 400, name: 'a' },
{ time: '2019-06', count: 380, name: 'a' },
{ time: '2019-07', count: 220, name: 'a' },
{ time: '2019-03', count: 750, name: 'b' },
{ time: '2019-04', count: 650, name: 'b' },
{ time: '2019-05', count: 450, name: 'b' },
{ time: '2019-06', count: 400, name: 'b' },
{ time: '2019-07', count: 320, name: 'b' },
{ time: '2019-03', count: 900, name: 'c' },
{ time: '2019-04', count: 600, name: 'c' },
{ time: '2019-05', count: 450, name: 'c' },
{ time: '2019-06', count: 300, name: 'c' },
{ time: '2019-07', count: 200, name: 'c' },
];
148 changes: 148 additions & 0 deletions __tests__/unit/plots/dual-axes/slider-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { DualAxes } from '../../../../src';
import { delay } from '../../../utils/delay';
import { PV_DATA_MULTI, UV_DATA_MULTI, uvBillData, transformData } from '../../../data/pv-uv';
import { createDiv } from '../../../utils/dom';

describe('slider', () => {
it('type cat', async () => {
const dualAxes = new DualAxes(createDiv('test DualAxes doubal line'), {
data: [PV_DATA_MULTI, UV_DATA_MULTI],
xField: 'date',
yField: ['pv', 'uv'],
limitInPlot: false,
meta: {
date: {
sync: false,
},
},
slider: {
start: 0,
end: 0.5,
},
padding: [20, 40, 60, 40],
geometryOptions: [
{
geometry: 'column',
seriesField: 'site',
isStack: true,
},
{
geometry: 'line',
seriesField: 'site',
isStack: true,
},
],
});

dualAxes.render();
expect(dualAxes.chart.views[0].getOptions().slider).toEqual({
start: 0,
end: 0.5,
});
await delay(500);
// 需要去重, 存在双轴数据
expect(Array.from(new Set(dualAxes.chart.views[0].filterData(PV_DATA_MULTI).map((item) => item.date)))).toEqual([
'0601',
'0602',
'0603',
'0604',
'0605',
]);
expect(dualAxes.chart.getController('slider')).toBeDefined();
expect(dualAxes.chart.views[0].getController('slider').getComponents().length).toBe(1);
expect(dualAxes.chart.views[1].getController('slider').getComponents().length).toBe(0);
const [slider] = dualAxes.chart.views[0].getComponents().filter((co) => co.type === 'slider');
expect(slider.component.get('minText')).toBe('0601');
dualAxes.update({
slider: {
start: 0,
end: 1,
},
});
expect(dualAxes.chart.views[0].getOptions().slider).toEqual({
start: 0,
end: 1,
});
expect(Array.from(new Set(dualAxes.chart.views[0].filterData(PV_DATA_MULTI).map((item) => item.date)))).toEqual([
'0601',
'0602',
'0603',
'0604',
'0605',
'0606',
'0607',
'0608',
'0609',
]);
dualAxes.destroy();
});
it('type time', async () => {
const dualAxes = new DualAxes(createDiv('test DualAxes doubal line'), {
data: [uvBillData, transformData],
xField: 'time',
yField: ['value', 'count'],
geometryOptions: [
{
geometry: 'line',
seriesField: 'type',
lineStyle: {
lineWidth: 3,
lineDash: [5, 5],
},
smooth: true,
},
{
geometry: 'line',
seriesField: 'name',
point: {},
},
],
limitInPlot: false,
meta: {
time: {
type: 'time',
sync: false,
},
},
slider: {
start: 0,
end: 1,
},
padding: [20, 40, 60, 40],
});

dualAxes.render();
expect(dualAxes.chart.views[0].getOptions().slider).toEqual({
start: 0,
end: 1,
});
expect(dualAxes.chart.getController('slider')).toBeDefined();
expect(dualAxes.chart.views[0].getController('slider').getComponents().length).toBe(1);
expect(dualAxes.chart.views[1].getController('slider').getComponents().length).toBe(0);
const [slider] = dualAxes.chart.views[0].getComponents().filter((co) => co.type === 'slider');
expect(slider.component.get('minText')).toBe('2019-03');
dualAxes.update({
meta: {
time: {
type: 'timeCat',
sync: false,
},
},
});

expect(dualAxes.chart.views[0].getOptions().slider).toEqual({
start: 0,
end: 1,
});
expect(dualAxes.chart.getController('slider')).toBeDefined();
dualAxes.changeData([uvBillData.slice(2, 8), transformData.slice(2, 8)]);
const [changedSlider] = dualAxes.chart.views[0].getComponents().filter((co) => co.type === 'slider');
expect(changedSlider.component.get('minText')).toBe('2019-05');
dualAxes.update({
slider: false,
});
await delay(500);
expect(dualAxes.chart.views[0].getController('slider').getComponents().length).toBe(0);
dualAxes.destroy();
});
});
12 changes: 12 additions & 0 deletions __tests__/unit/utils/is-between-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { isBetween } from '../../../src/utils';

describe('isBetween', () => {
it('isBetween', () => {
expect(isBetween(2, 1, 3)).toBeTruthy();
expect(isBetween(2, 3, 1)).toBeTruthy();
expect(isBetween(1, 3, 1)).toBeTruthy();
expect(isBetween(3, 3, 1)).toBeTruthy();
expect(isBetween(0, 3, 1)).toBeFalsy();
expect(isBetween(5, 3, 1)).toBeFalsy();
});
});
4 changes: 4 additions & 0 deletions docs/api/plots/dual-axes.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ The configuration for Xaxis and Yaxis is the same, since DualAxes are biaxes, an

`markdown:docs/common/theme.en.md`

#### slider

`markdown:docs/common/slider.en.md`

### Plot Events

`markdown:docs/common/events.en.md`
Expand Down
58 changes: 31 additions & 27 deletions docs/api/plots/dual-axes.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ order: 6
const data = [[{ time: '1991'value: 20 }], [{ time: '1992', count: 20 }]];
```

#### xField
#### xField

<description>**required** _string_</description>

点形状在 x 方向位置映射对应的数据字段名,一般对应一个连续字段。例如`{xField: 'time'}`

#### yField
#### yField

<description>**required** _string[]_</description>

Expand All @@ -41,39 +41,40 @@ const data = [[{ time: '1991',value: 20 }], [{ time: '1992', count: 20 }]];

<description>**optional** _array object_</description>

指定了双轴各自对应的图形配置,形式为[左轴图形配置,右轴图形配置]。每一个配置应为 Line 或 Column 类型的 Config。通过指定双轴对应图形,来实现混合图表功能:
指定了双轴各自对应的图形配置,形式为[左轴图形配置,右轴图形配置]。每一个配置应为 Line 或 Column 类型的 Config。通过指定双轴对应图形,来实现混合图表功能:

- 双轴折线图: [Line, Line], 参考 [DEMO](../../../examples/dual-axes/dual-line)
- 柱线混合图: [Column, Line], 参考 [DEMO](http://localhost:8080/zh/examples/dual-axes/column-line)

你还可以通过配置 Line 或 Column 的相关配置(见下文),形成双轴多折线图([DEMO](../../../examples/dual-axes/dual-line#dual-multi-line)), 堆叠柱+折线图([DEMO](../../../examples/dual-axes/stacked-column-line)), 分组柱+折线图([DEMO](../../../examples/dual-axes/grouped-column-line))

折线对应的图形配置为:

| 细分配置项名称 | 类型 | 功能描述 | 默认值 |
| ----------- | -------------------------------- | ----------------------------------------------- | ------ |
| geometry | _string_ | 图形类型,指定为'line' | 'line' |
| seriesField | _string_ | 拆分字段, 若存在则为多折线,具体用法同[折线图 seriesfield](./line#seriesfield) |
| smooth | _boolean_ | 是否平滑,具体用法同[折线图 smooth](./line#smooth) | false |
| connectNulls | _boolean_ | 是否连接空数据,具体用法同[折线图 connectnulls](./line#connectnulls) | true |
| lineStyle | _StyleAttr \| Function_ | 折线图形样式,具体用法同[折线图 lineStyle](./line#linestyle) | |
| point | _pointStyle_ | 线数据点图形样式,具体用法同[折线图 point](./line#point) | |
| label | _ContinueLegendLabelCfg_ | 折线图 label,具体用法同[折线图 label](./line#label) |
| color | _string \| string[] \| Function_ | 指定点的颜色。具体用法同[折线图 color](./line#color) |
| 细分配置项名称 | 类型 | 功能描述 | 默认值 |
| -------------- | -------------------------------- | ------------------------------------------------------------------------------ | ------ |
| geometry | _string_ | 图形类型,指定为'line' | 'line' |
| seriesField | _string_ | 拆分字段, 若存在则为多折线,具体用法同[折线图 seriesfield](./line#seriesfield) |
| smooth | _boolean_ | 是否平滑,具体用法同[折线图 smooth](./line#smooth) | false |
| connectNulls | _boolean_ | 是否连接空数据,具体用法同[折线图 connectnulls](./line#connectnulls) | true |
| lineStyle | _StyleAttr \| Function_ | 折线图形样式,具体用法同[折线图 lineStyle](./line#linestyle) | |
| point | _pointStyle_ | 线数据点图形样式,具体用法同[折线图 point](./line#point) | |
| label | _ContinueLegendLabelCfg_ | 折线图 label,具体用法同[折线图 label](./line#label) |
| color | _string \| string[] \| Function_ | 指定点的颜色。具体用法同[折线图 color](./line#color) |

柱形对应的图形配置为:

| 细分配置项名称 | 类型 | 功能描述 | 默认值 |
| ----------- | -------------------------------- | ----------------------------------------------- | ------ |
| geometry | _string_ | 图形类型,应指定为'column' | |
| seriesField | _string_ | 拆分字段, 在分组柱状图下同 groupField、colorField,在堆积柱状图下同 stackField、colorField ,具体参考[柱形图 seriesfield](./column#seriesfield) |
| isGroup | _boolean_ | 是否分组柱形图,具体用法同[柱形图 isGroup](./column#isgroup) | false |
| isStack | _boolean_ | 是否堆积柱状图,具体用法同[柱形图 isStack](./column#isstack) | false |
| columnWidthRatio | _number_ | 柱状图宽度占比 [0-1] ,具体用法同[柱形图 columnWidthRatio](./column#columnwidthratio) | |
| marginRatio | _number_ | 分组中柱子之间的间距 [0-1],仅对分组柱状图适用,具体用法同[柱形图 marginRatio](./column#marginratio) | |
| columnStyle | _StyleAttr \| Function_ | 柱子样式配置,具体用法同[柱形图 columnStyle](./column#columnstyle) | |
| label | _ContinueLegendLabelCfg_ | 柱形图 label,具体用法同[柱线图 label](./column#label) |
| color | _string \| string[] \| Function_ | 指定点的颜色。具体用法同[折线图 color](./column#color) |
| groupField | _string_ | 拆分字段,用于堆叠+分组柱图,拆分优先级高于 seriesField,isGroup: true 时会根据 groupField 进行分组。 | - |
| 细分配置项名称 | 类型 | 功能描述 | 默认值 |
| ---------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| geometry | _string_ | 图形类型,应指定为'column' | |
| seriesField | _string_ | 拆分字段, 在分组柱状图下同 groupField、colorField,在堆积柱状图下同 stackField、colorField ,具体参考[柱形图 seriesfield](./column#seriesfield) |
| isGroup | _boolean_ | 是否分组柱形图,具体用法同[柱形图 isGroup](./column#isgroup) | false |
| isStack | _boolean_ | 是否堆积柱状图,具体用法同[柱形图 isStack](./column#isstack) | false |
| columnWidthRatio | _number_ | 柱状图宽度占比 [0-1] ,具体用法同[柱形图 columnWidthRatio](./column#columnwidthratio) | |
| marginRatio | _number_ | 分组中柱子之间的间距 [0-1],仅对分组柱状图适用,具体用法同[柱形图 marginRatio](./column#marginratio) | |
| columnStyle | _StyleAttr \| Function_ | 柱子样式配置,具体用法同[柱形图 columnStyle](./column#columnstyle) | |
| label | _ContinueLegendLabelCfg_ | 柱形图 label,具体用法同[柱线图 label](./column#label) |
| color | _string \| string[] \| Function_ | 指定点的颜色。具体用法同[折线图 color](./column#color) |
| groupField | _string_ | 拆分字段,用于堆叠+分组柱图,拆分优先级高于 seriesField,isGroup: true 时会根据 groupField 进行分组。 | - |

### 图表组件

Expand Down Expand Up @@ -144,18 +145,21 @@ xAxis、yAxis 配置相同,由于 DualAxes 是双轴, annotations 类型是
}
}
```

`markdown:docs/common/annotations.zh.md`

#### legend

`markdown:docs/common/legend.zh.md`


#### 主题
### 图表主题

`markdown:docs/common/theme.zh.md`

#### 滚动条

`markdown:docs/common/slider.zh.md`

### 图表事件

`markdown:docs/common/events.zh.md`
Expand Down
8 changes: 8 additions & 0 deletions examples/dual-axes/column-line/demo/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
"en": "Other column line"
},
"screenshot": "https://gw.alipayobjects.com/mdn/rms_d314dd/afts/img/A*_-QESLpPhPcAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "slider-column-line.ts",
"title": {
"zh": "柱线混合图表-滑块",
"en": "Slider with column line"
},
"screenshot": "https://gw.alipayobjects.com/zos/antfincdn/fxukGXuXfg/89ea37e5-e00d-4424-b75e-1aba3ff8b633.png"
}
]
}
58 changes: 58 additions & 0 deletions examples/dual-axes/column-line/demo/slider-culumn-line.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { DualAxes } from '@antv/g2plot';

const data = [
{ time: '2020-08-20', consumeTime: 10868, completeTime: 649.483 },
{ time: '2020-08-21', consumeTime: 8786, completeTime: 1053.7 },
{ time: '2020-08-22', consumeTime: 10824, completeTime: 679.817 },
{ time: '2020-08-23', consumeTime: 7860, completeTime: 638.117 },
{ time: '2020-08-24', consumeTime: 13253, completeTime: 843.3 },
{ time: '2020-08-25', consumeTime: 17015, completeTime: 1092.983 },
{ time: '2020-08-26', consumeTime: 19298, completeTime: 1036.317 },
{ time: '2020-08-27', consumeTime: 13937, completeTime: 1031.9 },
{ time: '2020-08-28', consumeTime: 11541, completeTime: 803.467 },
{ time: '2020-08-29', consumeTime: 15244, completeTime: 830.733 },
{ time: '2020-08-30', consumeTime: 14247, completeTime: 709.867 },
{ time: '2020-08-31', consumeTime: 9402, completeTime: 665.233 },
{ time: '2020-09-01', consumeTime: 10440, completeTime: 696.367 },
{ time: '2020-09-02', consumeTime: 9345, completeTime: 692.867 },
{ time: '2020-09-03', consumeTime: 18459, completeTime: 936.017 },
{ time: '2020-09-04', consumeTime: 9763, completeTime: 782.867 },
{ time: '2020-09-05', consumeTime: 11074, completeTime: 653.8 },
{ time: '2020-09-06', consumeTime: 11770, completeTime: 856.683 },
{ time: '2020-09-07', consumeTime: 12206, completeTime: 777.15 },
{ time: '2020-09-08', consumeTime: 11434, completeTime: 773.283 },
{ time: '2020-09-09', consumeTime: 16218, completeTime: 833.3 },
{ time: '2020-09-10', consumeTime: 11914, completeTime: 793.517 },
{ time: '2020-09-11', consumeTime: 16781, completeTime: 894.45 },
{ time: '2020-09-12', consumeTime: 10555, completeTime: 725.55 },
{ time: '2020-09-13', consumeTime: 10899, completeTime: 709.967 },
{ time: '2020-09-14', consumeTime: 10713, completeTime: 787.6 },
{ time: '2020-09-15', consumeTime: 0, completeTime: 644.183 },
{ time: '2020-09-16', consumeTime: 0, completeTime: 1066.65 },
{ time: '2020-09-17', consumeTime: 20357, completeTime: 932.45 },
{ time: '2020-09-18', consumeTime: 10424, completeTime: 753.583 },
];

const dualAxes = new DualAxes('container', {
data: [data, data],
xField: 'time',
yField: ['consumeTime', 'completeTime'],
limitInPlot: false,
padding: [10, 20, 80, 30], // 需要设置底部 padding 值,同 css
slider: {},
meta: {
time: {
sync: false, // 开启之后 slider 无法重绘
},
},
geometryOptions: [
{
geometry: 'column',
},
{
geometry: 'line',
},
],
});

dualAxes.render();
2 changes: 2 additions & 0 deletions src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export const AXIS_META_CONFIG_KEYS = [
'exponent',
// time 类型的格式化
'mask',
// 是否同步
'sync',
];

/**
Expand Down
Loading

0 comments on commit 0276528

Please sign in to comment.