Skip to content

Commit

Permalink
feat(statistic): 中心统计文本支持 content 设置 (#2567)
Browse files Browse the repository at this point in the history
* feat(statistic): 中心统计文本支持 content 设置

* docs(statistic): 补全文档

* fix(pie): 饼图中心文本交互状态时,不使用 content

* docs(statistic): 完善文档

* feat(statistic): 修复水波图 & 进度环图设置统计文本 content 不生效 & 添加单测
  • Loading branch information
visiky committed May 20, 2021
1 parent 025446b commit b73b2c9
Show file tree
Hide file tree
Showing 19 changed files with 245 additions and 76 deletions.
6 changes: 6 additions & 0 deletions __tests__/unit/plots/gauge/statistic-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ describe('gauge statistic', () => {
expect((annotation as HTMLElement).innerText).toBe('65.00%');
});

it('设置 content', () => {
gauge.update({ statistic: { content: { content: 'ss' } } });
const annotation = document.body.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('ss');
});

it('statistic 配置的格式化方式, 优先级高于 meta', () => {
gauge.update({ statistic: { content: { formatter: ({ percent }) => `${percent * 100}.0%` } } });
const annotation = document.body.querySelector('.g2-html-annotation');
Expand Down
38 changes: 23 additions & 15 deletions __tests__/unit/plots/liquid/statistic-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { createDiv } from '../../../utils/dom';
import { delay } from '../../../utils/delay';

describe('liquid statistic', () => {
const liquid = new Liquid(createDiv(), {
const div = createDiv();
const liquid = new Liquid(div, {
width: 600,
height: 300,
autoFit: false,
Expand All @@ -14,39 +15,46 @@ describe('liquid statistic', () => {

it('默认展示', async () => {
await delay(50);
const annotations = document.body.querySelectorAll('.g2-html-annotation');
const annotations = div.querySelectorAll('.g2-html-annotation');
expect(annotations.length).toBe(1);
});

it('默认展示当前数值', () => {
liquid.update({ statistic: { content: {} } });
const annotation = document.body.querySelector('.g2-html-annotation');
const annotation = div.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('65.00%');
});

it('使用 content', () => {
liquid.chart.clear();
liquid.update({ statistic: { content: { content: 'ss' } } });
const annotation = div.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('ss');
});

it('使用 meta 格式化', () => {
liquid.update({
meta: { percent: { formatter: (v) => `${v * 100}.000%` } },
statistic: { content: { formatter: null } },
statistic: { content: { content: undefined } },
});
const annotation = document.body.querySelector('.g2-html-annotation');
const annotation = div.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('65.000%');
});

it('statistic 配置的格式化方式, 优先级高于 meta', () => {
liquid.update({ statistic: { content: { formatter: ({ percent }) => `${percent * 100}.0%` } } });
const annotation = document.body.querySelector('.g2-html-annotation');
const annotation = div.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('65.0%');
});

it('statistic 配置title', () => {
liquid.update({ statistic: { content: {}, title: {} } });
let annotations = document.body.querySelectorAll('.g2-html-annotation');
let annotations = div.querySelectorAll('.g2-html-annotation');
expect(annotations.length).toBe(2);
expect((annotations[0] as HTMLElement).innerText).toBe('');

liquid.update({ statistic: { content: {}, title: { formatter: () => '测试' } } });
annotations = document.body.querySelectorAll('.g2-html-annotation');
annotations = div.querySelectorAll('.g2-html-annotation');
expect((annotations[0] as HTMLElement).innerText).toBe('测试');
});

Expand All @@ -72,29 +80,29 @@ describe('liquid statistic', () => {

it('关闭 statistic', () => {
liquid.update({ statistic: { content: null } });
let annotations = document.body.querySelectorAll('.g2-html-annotation');
let annotations = div.querySelectorAll('.g2-html-annotation');
expect(annotations.length).toBe(1);
liquid.update({ statistic: { content: null, title: null } });
annotations = document.body.querySelectorAll('.g2-html-annotation');
annotations = div.querySelectorAll('.g2-html-annotation');
expect(annotations.length).toBe(0);
});

it('change data', () => {
liquid.update({ statistic: { title: {}, content: { formatter: ({ percent: v }) => `${v * 100}.0%` } } });
liquid.changeData(0.35);
const annotations = document.body.querySelectorAll('.g2-html-annotation');
const annotations = div.querySelectorAll('.g2-html-annotation');
expect(annotations.length).toBe(2);
expect((annotations[1] as HTMLElement).innerText).toBe('35.0%');

liquid.changeData(0.15);
expect((document.body.querySelectorAll('.g2-html-annotation')[1] as HTMLElement).innerText).toBe('15.0%');
expect((div.querySelectorAll('.g2-html-annotation')[1] as HTMLElement).innerText).toBe('15.0%');

liquid.update({ statistic: { content: {}, title: false } });
expect(document.body.querySelectorAll('.g2-html-annotation').length).toBe(1);
expect((document.body.querySelectorAll('.g2-html-annotation')[0] as HTMLElement).innerText).toBe('15.0%');
expect(div.querySelectorAll('.g2-html-annotation').length).toBe(1);
expect((div.querySelectorAll('.g2-html-annotation')[0] as HTMLElement).innerText).toBe('15.0%');

liquid.changeData(0.05);
expect((document.body.querySelectorAll('.g2-html-annotation')[0] as HTMLElement).innerText).toBe('5.0%');
expect((div.querySelectorAll('.g2-html-annotation')[0] as HTMLElement).innerText).toBe('5.0%');
});

afterAll(() => {
Expand Down
9 changes: 9 additions & 0 deletions __tests__/unit/plots/pie/statistic-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ describe('中心文本 - 指标卡', () => {
expect((htmlAnnotations[1] as HTMLElement).innerText).toBe(`${data.reduce((a, b) => a + b.value, 0)}`);
});

it('设置 content', () => {
// 清空所有配置
pie.update({ statistic: null });
pie.update({ statistic: { title: { content: 'TEST' }, content: { content: 'ss' } } });
const htmlAnnotations = document.querySelectorAll('.g2-html-annotation');
expect((htmlAnnotations[0] as HTMLElement).innerText).toBe('TEST');
expect((htmlAnnotations[1] as HTMLElement).innerText).toBe('ss');
});

it('自定义中心文本内容: update statistic title & content', () => {
pie.update({
...pie.options,
Expand Down
8 changes: 7 additions & 1 deletion __tests__/unit/plots/ring-progress/statistic-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ describe('ringProgress statistic', () => {
expect((annotation as HTMLElement).innerText).toBe('65.00%');
});

it('使用 content', () => {
ringProgress.update({ statistic: { content: { content: 'ss' } } });
const annotation = document.body.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('ss');
});

it('使用 meta 格式化', () => {
ringProgress.update({
meta: { percent: { formatter: (v) => `${v * 100}.000%` } },
statistic: { content: { formatter: null } },
statistic: { content: { content: null } },
});
const annotation = document.body.querySelector('.g2-html-annotation');
expect((annotation as HTMLElement).innerText).toBe('65.000%');
Expand Down
84 changes: 69 additions & 15 deletions __tests__/unit/utils/statistic-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
renderGaugeStatistic,
} from '../../../src/utils/statistic';
import { ShapeStyle } from '../../../src/types';
import { createDiv } from '../../utils/dom';
import { createDiv, removeDom } from '../../utils/dom';

describe('饼图 statistics 相关处理函数', () => {
it('adapteStyle', () => {
Expand Down Expand Up @@ -54,21 +54,20 @@ describe('饼图 statistics 相关处理函数', () => {
});
});

const container = createDiv();
it('设置statistics容器样式', () => {
const container = createDiv();
setStatisticContainerStyle(container, { color: '', fontSize: '12px' });
// 默认穿透
expect(container.style['pointerEvents']).toBe('none');
expect(container.style.color).toBe('');
expect(container.style.fontSize).toBe('12px');
});

const chart = new Chart({
container,
height: 200,
});
it('render-statistic', () => {
const div = createDiv();
const chart = new Chart({
container: div,
height: 200,
});
chart.coordinate({ type: 'theta', cfg: { innerRadius: 0.5, radius: 1 } });
renderStatistic(chart, { statistic: { title: false, content: false }, plotType: 'pie' });
expect(chart.getComponents().filter((c) => c.type === 'annotation').length).toBe(0);
Expand All @@ -86,22 +85,46 @@ describe('饼图 statistics 相关处理函数', () => {
expect(annotations[1].component.get('key')).toBe('bottom-statistic');

// @ts-ignore
expect(div.querySelector('.g2-html-annotation').style.width).toBe(`${chart.getCoordinate().getRadius()}px`);
expect(container.querySelector('.g2-html-annotation').style.width).toBe(`${chart.getCoordinate().getRadius()}px`);
chart.clear();

renderStatistic(chart, { statistic: { title: {}, content: {} }, plotType: 'xxx' });
chart.render();
// @ts-ignore
expect(div.querySelector('.g2-html-annotation').style.width).toBe(`${chart.getCoordinate().getWidth()}px`);
expect(container.querySelector('.g2-html-annotation').style.width).toBe(`${chart.getCoordinate().getWidth()}px`);
chart.clear();
});

it('render-gauge-statistic', async () => {
const div = createDiv();
const chart = new Chart({
container: div,
height: 200,
it('statistic 文本内容: customHtml > formatter > content', () => {
chart.coordinate({ type: 'theta', cfg: { innerRadius: 0.5, radius: 1 } });
renderStatistic(chart, { statistic: { title: { content: 'TEST' }, content: false }, plotType: 'pie' });
chart.render();
expect((container.querySelector('.g2-html-annotation') as HTMLElement).innerText).toBe('TEST');

chart.clear();

renderStatistic(chart, {
statistic: { title: { content: 'TEST', formatter: () => 'TEST formatter' }, content: false },
plotType: 'xxx',
});
chart.render();
expect((container.querySelector('.g2-html-annotation') as HTMLElement).innerText).toBe('TEST formatter');

chart.clear();

renderStatistic(chart, {
statistic: {
title: { content: 'TEST', formatter: () => 'TEST formatter', customHtml: () => '<div>custom html</div>' },
content: false,
},
plotType: 'xxx',
});
chart.render();
expect((container.querySelector('.g2-html-annotation') as HTMLElement).innerText).toBe('custom html');
chart.clear();
});

it('render-gauge-statistic', async () => {
chart.coordinate({ type: 'theta', cfg: { innerRadius: 0.5, radius: 1 } });
chart.createView();
renderGaugeStatistic(chart, { statistic: { title: false, content: false } });
Expand All @@ -123,7 +146,38 @@ describe('饼图 statistics 相关处理函数', () => {
chart.render();
expect(chart.getComponents().filter((c) => c.type === 'annotation').length).toBe(2);
// @ts-ignore
expect(div.querySelector('.g2-html-annotation').innerText).toBe('xxx');
expect(container.querySelector('.g2-html-annotation').innerText).toBe('xxx');
chart.clear();
});

it('statistic 文本内容: customHtml > formatter > content', () => {
chart.coordinate({ type: 'theta', cfg: { innerRadius: 0.5, radius: 1 } });
renderGaugeStatistic(chart, { statistic: { title: { content: 'TEST' }, content: false } });
chart.render();
expect((container.querySelector('.g2-html-annotation') as HTMLElement).innerText).toBe('TEST');

chart.clear();

renderGaugeStatistic(chart, {
statistic: { title: { content: 'TEST', formatter: () => 'TEST formatter' }, content: false },
});
chart.render();
expect((container.querySelector('.g2-html-annotation') as HTMLElement).innerText).toBe('TEST formatter');

chart.clear();

renderGaugeStatistic(chart, {
statistic: {
title: { content: 'TEST', formatter: () => 'TEST formatter', customHtml: () => '<div>custom html</div>' },
content: false,
},
});
chart.render();
expect((container.querySelector('.g2-html-annotation') as HTMLElement).innerText).toBe('custom html');
chart.clear();
});
afterAll(() => {
chart.destroy();
removeDom(container);
});
});
2 changes: 1 addition & 1 deletion docs/api/components/slider.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ order: 2

🎨 前往墨者学院 [AntV 设计 | 缩略轴 Axis Navigator](https://www.yuque.com/mo-college/vis-design/gs5ow9) 查看**设计指引**

#### 构成团苏
#### 构成元素

<img src="https://gw.alipayobjects.com/zos/antfincdn/A3UeXLPhhU/slider-intro.jpg" class="component-img" alt="slider" />

Expand Down
26 changes: 26 additions & 0 deletions docs/api/components/statistic.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Statistic Text
order: 7
contributors:
[
{
author: '新茗',
github: 'visiky',
avatar: 'https://gw.alipayobjects.com/zos/antfincdn/KAeYPA3TV0/avatar.jpeg',
},
]
---

`markdown:docs/styles/component.md`

#### Statistic

<img src="https://gw.alipayobjects.com/zos/antfincdn/YrJCRYNcAM/0dfb515f-5efd-4341-a5ec-bd1f988b5975.png" class="component-img" alt="slider" />

#### Properties - _Statistic_

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

Example:

<playground path="pie/donut/demo/basic.ts" rid="statistic"></playground>
26 changes: 26 additions & 0 deletions docs/api/components/statistic.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: 统计文本 - Statistic
order: 7
contributors:
[
{
author: '新茗',
github: 'visiky',
avatar: 'https://gw.alipayobjects.com/zos/antfincdn/KAeYPA3TV0/avatar.jpeg',
},
]
---

`markdown:docs/styles/component.md`

#### 构成元素

<img src="https://gw.alipayobjects.com/zos/antfincdn/YrJCRYNcAM/0dfb515f-5efd-4341-a5ec-bd1f988b5975.png" class="component-img" alt="slider" />

#### 配置属性 - _Statistic_

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

示例:

<playground path="pie/donut/demo/basic.ts" rid="statistic"></playground>
9 changes: 8 additions & 1 deletion docs/common/statistic.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ StatisticText
| Properties | Type | Description |
| ---------- | -------- | --------------------------------- |
| style | _CSSStyleDeclaration_ | Styles for statistical text (css styles) |
| customHtml | `(container: HTMLElement, view: View, datum: object, data: object[]) => string;` | custom content by using html,priority is higher than formatter |
| content | _string_ | Content of the text。Priority: `customHtml` > `formatter` > `content` |
| customHtml | _CustomHtml_ | custom content by using html,priority is higher than formatter |
| formatter | _Function_ | The formatted content of the text |
| rotate | _number_ | Rotation Angle |
| offsetX | _number_ | X offset |
| offsetY | _number_ | Y offset |

Type of **CustomHtml** is as follow:

```ts
type CustomHtml = (container: HTMLElement, view: View, datum: object, data: object[]) => string;
```
9 changes: 8 additions & 1 deletion docs/common/statistic.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ StatisticText
| 配置项 | 类型 | 描述 |
| --------- | -------- | -------------------- |
| style | _CSSStyleDeclaration_ | 统计文本的样式 (css 样式) |
| customHtml | `(container: HTMLElement, view: View, datum: object, data: object[]) => string;` | 自定义主体文本的 html,优先级高于 formatter |
| content | _string_ | 主体文本内容。优先级: `customHtml` > `formatter` > `content` |
| customHtml | _CustomHtml_ | 自定义主体文本的 html,优先级高于 formatter |
| formatter | _Function_ | 主体文本的格式化内容 |
| rotate | _number_ | 旋转角度 |
| offsetX | _number_ | X 偏移值 |
| offsetY | _number_ | Y 偏移值 |

**CustomHtml** 类型定义如下:

```ts
type CustomHtml = (container: HTMLElement, view: View, datum: object, data: object[]) => string;
```
2 changes: 1 addition & 1 deletion examples/pie/donut/demo/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const piePlot = new Pie('container', {
overflow: 'hidden',
textOverflow: 'ellipsis',
},
formatter: () => 'AntV\nG2Plot',
content: 'AntV\nG2Plot',
},
},
});
Expand Down
Loading

0 comments on commit b73b2c9

Please sign in to comment.