Skip to content

Commit

Permalink
refactor(funnel): 支持尖底漏斗图以及样式设置 (#2634)
Browse files Browse the repository at this point in the history
* docs(funnel): 补充漏斗图动态高度的文档说明

* refactor(funnel): 漏斗图抽取 constant 以及暴露常用的字段作为静态属性

* feat(funnel): 基础漏斗图支持shape设置金字塔以及支持 funnelStyle 设置

* docs: 添加尖底漏斗图 demo

* feat(mix-plot): 多图层图表增加 funnel & 添加复合漏斗图 demo

* test(funnel): 增加漏斗图单测
  • Loading branch information
visiky committed Jun 15, 2021
1 parent 15b35ee commit 0882b32
Show file tree
Hide file tree
Showing 20 changed files with 433 additions and 79 deletions.
38 changes: 38 additions & 0 deletions __tests__/unit/plots/funnel/index-spec.ts
@@ -0,0 +1,38 @@
import { Funnel, FUNNEL_CONVERSATION_FIELD } from '../../../../src';
import { DEFAULT_OPTIONS } from '../../../../src/plots/funnel/constant';
import { createDiv } from '../../../utils/dom';

describe('funnel', () => {
const data = [
{ stage: '简历筛选', number: 253 },
{ stage: '初试人数', number: 151 },
{ stage: '复试人数', number: 113 },
{ stage: '录取人数', number: 87 },
{ stage: '入职人数', number: 59 },
];

const plot = new Funnel(createDiv(), {
data: data,
xField: 'stage',
yField: 'number',
legend: false,
});

plot.render();

it('defaultOptions', () => {
expect(plot.type).toBe('funnel');

expect(Funnel.getDefaultOptions()).toEqual(DEFAULT_OPTIONS);
// @ts-ignore
expect(plot.getDefaultOptions()).toEqual(DEFAULT_OPTIONS);
});

it('static properties', () => {
expect(Funnel.CONVERSATION_FIELD).toBeDefined();
// 兼容旧的
expect(Funnel.CONVERSATION_FIELD).toBe(FUNNEL_CONVERSATION_FIELD);
expect(Funnel.PERCENT_FIELD).toBeDefined();
expect(Funnel.TOTAL_PERCENT_FIELD).toBeDefined();
});
});
52 changes: 52 additions & 0 deletions __tests__/unit/plots/funnel/style-spec.ts
@@ -0,0 +1,52 @@
import { Funnel } from '../../../../src';
import { PV_DATA_COMPARE } from '../../../data/conversion';
import { createDiv } from '../../../utils/dom';

describe('funnel', () => {
const plot = new Funnel(createDiv(), {
data: PV_DATA_COMPARE,
autoFit: true,
xField: 'action',
yField: 'pv',
minSize: 0.3,
maxSize: 0.8,
funnelStyle: {
fill: 'red',
},
});

plot.render();

it('default', () => {
expect(plot.type).toBe('funnel');

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

plot.update({ funnelStyle: () => ({ fill: 'red', stroke: 'blue' }) });
expect(plot.chart.geometries[0].elements[0].shape.attr('stroke')).toEqual('blue');
});

it('对比漏斗图', () => {
plot.update({ compareField: 'quarter' });
expect(plot.chart.views.length).toEqual(2);

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

plot.update({ funnelStyle: undefined });
// 还原默认
expect(plot.chart.views[0].geometries[0].elements[0].shape.attr('stroke')).toEqual('#fff');

plot.update({ funnelStyle: { stroke: 'yellow' } });
expect(plot.chart.views[0].geometries[0].elements[0].shape.attr('stroke')).toEqual('yellow');

// function
plot.update({ funnelStyle: () => ({ stroke: 'blue' }) });
expect(plot.chart.views[0].geometries[0].elements[0].shape.attr('stroke')).toEqual('blue');
});
});
71 changes: 57 additions & 14 deletions docs/api/plots/funnel.en.md
Expand Up @@ -23,30 +23,38 @@ Configure the data source. The data source is a collection of objects. For examp

Field for comparing.


#### seriesField

<description>**optional** _string_</description>

Field for spliting.

#### meta

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

### Graphic Style

#### isTransposed

<description>**optional** _boolean_ _default:_ `false`</description>

Whether the plot is transposed.

#### meta
#### shape

`markdown:docs/common/meta.en.md`
<description>**optional** _string_ `'funnel' | 'pyramid'` </description>

### Graphic Style
漏斗图形状。shape 设置为 'pyramid' 时,漏斗图展示为尖底样式(形如:金字塔)。目前只在基础漏斗图中适用。不适用场景:

1. 在对比漏斗图(`compareField` 存在时)不适用
2. 设置 dynamicHeight: 'true' 时不适用,此时需要设置 shape 为空。

#### dynamicHeight

<description>**optional** _boolean_ _default:_ `false`</description>

Whether the height is dynamic.
Whether the height is dynamic. When set to `true`, the height of each elemnet in funnel plot is directly proportional to the corresponding value of yField.

#### maxSize

Expand All @@ -64,15 +72,13 @@ the min size of graphic,is between 0 and 1, default 0。

Tip: when set dynamicHeight to be true, this field is invalid

#### conversionTag
#### funnelStyle

<description>**optional** _false | object_</description>
<description>**optional** _object_</description>

Configure the conversion rate component.

Defalut: `{offsetX: 10, offsetY: 0, formatter: (datum) => '转化率' + datum.$$percentage$$ * 100 + '%',}`
Graphic style of funnel. You can either pass in the 'shapeStyle' structure directly, or you can use callbacks to return different styles for different data. For the ShapeStyle data structure, see:

`markdown:docs/common/color.en.md`
`markdown:docs/common/shape-style.en.md`

### Plot Components

Expand All @@ -84,6 +90,16 @@ Defalut: `{offsetX: 10, offsetY: 0, formatter: (datum) => '转化率' + datum.$$

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

#### conversionTag

<description>**optional** _false | object_</description>

Configure the conversion rate component.

Defalut: `{offsetX: 10, offsetY: 0, formatter: (datum) => '转化率' + datum.$$percentage$$ * 100 + '%',}`

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

#### 图例

`markdown:docs/common/legend.en.md`
Expand All @@ -105,21 +121,48 @@ Defalut: `{offsetX: 10, offsetY: 0, formatter: (datum) => '转化率' + datum.$$

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

### Static Properties

Funnel plot provides static properties, makes it easy to use.

#### Static variables

### Static Variables
| Field | Description |
| --- | --- |
| `CONVERSATION_FIELD` | The corresponding value of this field is an array, stores the current and previous values of the funnel, for example, [263, 151], from which the user can calculate the conversion rate |
| `PERCENT_FIELD` | The corresponding value of this field represents the `conversion percentage` between current value and previous value |
| `TOTAL_PERCENT_FIELD` | The corresponding value of this field represents the percentage of total conversion rate |

Funnel plot provides static variables, such as:
**Example:**

```javascript
import { Funnel } from '@antv/g2plot';

// usage
{
conversionTag: {
formatter: (datum) => {
return `${(datum[Funnel.CONVERSATION_FIELD][1] / datum[Funnel.CONVERSATION_FIELD][0] * 100).toFixed(2)}%`;
},
},
label: {
formatter: (datum) => {
return `${(datum[Funnel.PERCENT_FIELD] * 100).toFixed(2)}%`;
}
}
}
```

#### FUNNEL_CONVERSATION_FIELD

> Attention: you can use `Funnel.CONVERSATION_FIELD` to replace `FUNNEL_CONVERSATION_FIELD` in the latest version.
FUNNEL_CONVERSATION_FIELD is an array, stores the current and previous values of the funnel, for example, [263, 151], from which the user can calculate the conversion rate, for example:

```javascript
// 引用
import { FUNNEL_CONVERSATION_FIELD } from '@antv/g2plot';


// 使用
{
conversionTag: {
Expand Down
73 changes: 58 additions & 15 deletions docs/api/plots/funnel.zh.md
Expand Up @@ -29,24 +29,32 @@ order: 9

分组字段。声明此字段时会自动渲染为分组漏斗图

#### meta

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

### 图形样式

#### isTransposed

<description>**optional** _boolean_ _default:_ `false`</description>

是否转置。

#### meta
#### shape

`markdown:docs/common/meta.zh.md`
<description>**optional** _string_ `'funnel' | 'pyramid'` </description>

### 图形样式
漏斗图形状。shape 设置为 'pyramid' 时,漏斗图展示为尖底样式(形如:金字塔)。目前只在基础漏斗图中适用。不适用场景:

1. 在对比漏斗图(`compareField` 存在时)不适用
2. 设置 dynamicHeight: 'true' 时不适用,此时需要设置 shape 为空。

#### dynamicHeight

<description>**optional** _boolean_ _default:_ `false`</description>

是否映射为动态高度。

是否映射为动态高度。当设置为 'true' 时,漏斗图每个条目(图表元素)的高度和 y 轴字段对应数值成正比。

#### maxSize

Expand All @@ -56,23 +64,21 @@ order: 9

注:因动态高度漏斗图将值映射为高度,因此声明 dynamicHeight: true 时,该字段无效


#### minSize

<description>**optional** _number_ _default:_ `1`</description>

图形最小宽度,为 [0, 1] 之间小数,默认为 0。

注:因动态高度漏斗图将值映射为高度,因此声明 dynamicHeight: true 时,该字段无效
#### conversionTag

<description>**optional** _false | object_</description>
#### funnelStyle

配置转化率组件。
<description>**可选** _object_</description>

默认配置:`{offsetX: 10, offsetY: 0, formatter: (datum) => '转化率' + datum.$$percentage$$ * 100 + '%',}`
漏斗图样式。可以直接传入 `ShapeStyle` 结构,也可以使用回调函数的方式,针对不同的数据,来返回不同的样式。对于 ShapeStyle 的数据结构,可以参考:

`markdown:docs/common/color.zh.md`
`markdown:docs/common/shape-style.zh.md`

### 图表组件

Expand All @@ -84,6 +90,16 @@ order: 9

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

#### conversionTag

<description>**optional** _false | object_</description>

配置转化率组件。

默认配置:`{offsetX: 10, offsetY: 0, formatter: (datum) => '转化率' + datum.$$percentage$$ * 100 + '%',}`

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

#### 图例

`markdown:docs/common/legend.zh.md`
Expand All @@ -101,26 +117,53 @@ order: 9

`markdown:docs/common/chart-methods.zh.md`


### 图表主题

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

### 静态属性

### 静态变量
漏斗图提供静态属性,以方便用户在实际项目中的使用.

漏斗图提供静态变量,以方便用户在实际项目中的使用,包括
#### 静态变量

| 字段 key 值 | 说明 |
| --- | --- |
| `CONVERSATION_FIELD` | 该字段对应数值为数组,存储漏斗当前和上一项值,例如 [263, 151], 用户可由此计算转化率 |
| `PERCENT_FIELD` | 该字段对应数值代表的是当前数值和上一项值的转化率百分比 |
| `TOTAL_PERCENT_FIELD` | 该字段对应数值代表的总转化率百分比 |

**使用示例:**

```javascript
// 引用
import { Funnel } from '@antv/g2plot';

// 使用
{
conversionTag: {
formatter: (datum) => {
return `${(datum[Funnel.CONVERSATION_FIELD][1] / datum[Funnel.CONVERSATION_FIELD][0] * 100).toFixed(2)}%`;
},
},
label: {
formatter: (datum) => {
return `${(datum[Funnel.PERCENT_FIELD] * 100).toFixed(2)}%`;
}
}
}
```

#### FUNNEL_CONVERSATION_FIELD

> 注意:在最新版本中,您可以直接使用 `Funnel.CONVERSATION_FIELD` 来替代 `FUNNEL_CONVERSATION_FIELD`
FUNNEL_CONVERSATION_FIELD 为数组,存储漏斗当前和上一项值,例如 [263, 151], 用户可由此计算转化率,例如:

```javascript
// 引用
import { FUNNEL_CONVERSATION_FIELD } from '@antv/g2plot';


// 使用
{
conversionTag: {
Expand Down
2 changes: 1 addition & 1 deletion docs/common/plot-cfg.en.md
Expand Up @@ -6,7 +6,7 @@ plot 类型,通过传入指定 type 的 plot,可以在图层上渲染 G2Plot

目前开放的图表类型有以下类型:

- **基础图表**`'line' | 'pie' | 'column' | 'bar' | 'area' | 'gauge' | 'scatter' | 'histogram'`
- **基础图表**`'line' | 'pie' | 'column' | 'bar' | 'area' | 'gauge' | 'scatter' | 'histogram' | 'funnel`
- **迷你图表**`'tiny-line' | 'tiny-column' | 'tiny-area' | 'progress' | 'ring-progress'`

#### IPlot.options
Expand Down
2 changes: 1 addition & 1 deletion docs/common/plot-cfg.zh.md
Expand Up @@ -6,7 +6,7 @@ plot 类型,通过传入指定 type 的 plot,可以在图层上渲染 G2Plot

目前开放的图表类型有以下类型:

- **基础图表**`'line' | 'pie' | 'column' | 'bar' | 'area' | 'gauge' |'scatter' | 'histogram'`
- **基础图表**`'line' | 'pie' | 'column' | 'bar' | 'area' | 'gauge' |'scatter' | 'histogram' | 'funnel'`
- **迷你图表**`'tiny-line' | 'tiny-column' | 'tiny-area' | 'progress' | 'ring-progress'`

#### IPlot.options
Expand Down

0 comments on commit 0882b32

Please sign in to comment.