From 0b3ed76d78b1b8a1641ca6c71159ce5b50a7717e Mon Sep 17 00:00:00 2001 From: Kasmine <736929286@qq.com> Date: Fri, 9 Oct 2020 15:48:58 +0800 Subject: [PATCH] fix(issue-1174): pie statistics content formatter does not work (#1693) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(issue-1174): pie statistics content formatter does not work * test(issue-1174): add testcases * fix: pie statistic 默认值设置 * fix(test): 修复测试用例 * feat(pie-demo): demo 增加statistic formatter 示范 --- __tests__/bugs/issue-1174-spec.ts | 65 +++++++++++++++++++ __tests__/unit/plots/pie/interaction-spec.ts | 6 +- examples/pie/donut/demo/statistics.ts | 5 +- src/plots/pie/adaptor.ts | 17 +++-- .../pie/interaction/pie-statistic-action.ts | 8 +-- 5 files changed, 84 insertions(+), 17 deletions(-) create mode 100644 __tests__/bugs/issue-1174-spec.ts diff --git a/__tests__/bugs/issue-1174-spec.ts b/__tests__/bugs/issue-1174-spec.ts new file mode 100644 index 0000000000..01a40a9743 --- /dev/null +++ b/__tests__/bugs/issue-1174-spec.ts @@ -0,0 +1,65 @@ +import { reduce } from '@antv/util'; +import { Pie } from '../../src'; +import { createDiv } from '.././utils/dom'; +import { simulateMouseEvent } from '../utils/event'; + +describe('donut plot', () => { + test('statistic content formatter', () => { + const data = [ + { + type: '分类一', + value: 27, + }, + { + type: '分类二', + value: 25, + }, + { + type: '分类三', + value: 18, + }, + { + type: '分类四', + value: 15, + }, + { + type: '分类五', + value: 10, + }, + { + type: '其它', + value: 5, + }, + ]; + + const donutPlot = new Pie(createDiv(), { + width: 400, + height: 400, + radius: 1, + innerRadius: 0.3, + padding: [0, 0, 0, 0], + data, + angleField: 'value', + colorField: 'type', + interactions: [{ type: 'element-active' }, { type: 'pie-statistic-active' }], + statistic: { + content: { + formatter: (datum, data) => { + return datum ? `${datum.value} 万` : `${reduce(data, (r, d) => r + d.value, 0)}万`; + }, + }, + }, + }); + + donutPlot.render(); + + const contentAnnotation = donutPlot.chart.getController('annotation').getComponents()[1]; + expect(contentAnnotation.component.get('content')).toBe(`${reduce(data, (r, d) => r + d.value, 0)}万`); + + setTimeout(() => { + const element = donutPlot.chart.geometries[0].elements[0]; + simulateMouseEvent(element.shape, 'mouseenter'); + expect(contentAnnotation.component.get('content')).toBe(`${data[0].value}万`); + }, 0); + }); +}); diff --git a/__tests__/unit/plots/pie/interaction-spec.ts b/__tests__/unit/plots/pie/interaction-spec.ts index 1b169e1384..118f905fd9 100644 --- a/__tests__/unit/plots/pie/interaction-spec.ts +++ b/__tests__/unit/plots/pie/interaction-spec.ts @@ -30,7 +30,7 @@ describe('register interaction', () => { radius: 0.8, innerRadius: 0.64, statistic: { - title: { formatter: (item, data) => (!Array.isArray(data) ? item.title : 'Total') }, + title: { formatter: (item) => (item ? item.type : 'Total') }, }, }); @@ -45,7 +45,7 @@ describe('register interaction', () => { const annotations = context.view.getComponents().filter((co) => co.type === 'annotation'); expect(annotations[0].extra.content).toBe('item3'); - expect(annotations[1].extra.content).toBe('13'); + expect(annotations[1].extra.content).toBe(13); }); it('触发 pie-statistic:reset', async () => { @@ -70,7 +70,7 @@ describe('G2 内置interactions', () => { radius: 0.8, innerRadius: 0.64, statistic: { - title: { formatter: (item, data) => (!Array.isArray(data) ? item.title : 'Total') }, + title: { formatter: (item) => (item ? item.type : 'Total') }, }, interactions: [{ type: 'pie-statistic-active' }], }); diff --git a/examples/pie/donut/demo/statistics.ts b/examples/pie/donut/demo/statistics.ts index 6ab2178c88..eec842fbeb 100644 --- a/examples/pie/donut/demo/statistics.ts +++ b/examples/pie/donut/demo/statistics.ts @@ -29,7 +29,10 @@ const piePlot = new Pie('container', { }, statistic: { title: { - formatter: () => '总计', + formatter: (datum) => (datum ? datum.type : '总计'), + }, + content: { + formatter: (datum, data) => (datum ? `¥ ${datum.value}` : `¥ ${data.reduce((r, d) => r + d.value, 0)}`), }, }, // 添加 中心统计文本 交互 diff --git a/src/plots/pie/adaptor.ts b/src/plots/pie/adaptor.ts index d77d147016..d9205bd5df 100644 --- a/src/plots/pie/adaptor.ts +++ b/src/plots/pie/adaptor.ts @@ -1,3 +1,4 @@ +import { Datum } from '@antv/g2/lib/interface'; import { deepMix, every, filter, get, isFunction, isString, isNil } from '@antv/util'; import { Params } from '../../core/adaptor'; import { legend, tooltip, interaction, animation, theme, state, annotation } from '../../adaptor/common'; @@ -174,7 +175,7 @@ function label(params: Params): Params { */ function statistic(params: Params): Params { const { chart, options } = params; - const { innerRadius, statistic, angleField } = options; + const { innerRadius, statistic, angleField, colorField } = options; const annotationOptions = []; @@ -189,6 +190,12 @@ function statistic(params: Params): Params { const { style, formatter, offsetX, offsetY, rotate } = option; const lineHeight = get(option, 'style.fontSize', 20); + const getDefaultContent = (data: Data, datum?: Datum) => { + if (index === 0) { + return datum ? datum[colorField] : '总计'; + } + return datum ? datum[angleField] : getTotalValue(data, angleField); + }; chart.annotation().text( deepMix( {}, @@ -200,12 +207,8 @@ function statistic(params: Params): Params { }, { position: ['50%', '50%'], - content: (filterData: Data) => { - return formatter - ? formatter(null, filterData) - : index === 0 - ? '总计' - : getTotalValue(filterData, angleField); + content: (filterData: Data, datum?: Datum) => { + return formatter ? formatter(datum, filterData) : getDefaultContent(filterData, datum); }, style, offsetX, diff --git a/src/plots/pie/interaction/pie-statistic-action.ts b/src/plots/pie/interaction/pie-statistic-action.ts index 40e7ca0997..869de48e77 100644 --- a/src/plots/pie/interaction/pie-statistic-action.ts +++ b/src/plots/pie/interaction/pie-statistic-action.ts @@ -1,6 +1,6 @@ import { Action } from '@antv/g2/lib/interaction'; import { ComponentOption } from '@antv/g2/lib/interface'; -import { each, get } from '@antv/util'; +import { each, get, isFunction } from '@antv/util'; /** * Pie 中心文本事件的 Action @@ -32,8 +32,6 @@ export class StatisticAction extends Action { const { data } = event.data; if (data) { const annotationController = view.getController('annotation'); - // todo remove ignore - // @ts-ignore annotationController.clear(true); // @ts-ignore const [, angleField, colorField] = view.getScaleFields(); @@ -54,7 +52,7 @@ export class StatisticAction extends Action { annotationOptions.push({ ...options, - content: options.formatter ? options.formatter(data, view.getData()) : value, + content: isFunction(options.content) ? options.content(view.getData(), data) : value, }); }); annotationOptions.forEach((opt) => { @@ -69,8 +67,6 @@ export class StatisticAction extends Action { public reset() { const { view } = this.context; const annotationController = view.getController('annotation'); - // todo remove ignore - // @ts-ignore annotationController.clear(true); const initialStatistic = this.getInitialAnnotation(); each(initialStatistic, (a) => {