Skip to content

Commit 365fd0f

Browse files
committed
feat(pie): add tooltip and label percent
1 parent 895dd3d commit 365fd0f

File tree

2 files changed

+121
-1
lines changed

2 files changed

+121
-1
lines changed

demos/pie-labelPercent.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// 基础饼图 - 显示百分比
2+
3+
const data = [
4+
{
5+
type: '分类一',
6+
value: 27,
7+
},
8+
{
9+
type: '分类二',
10+
value: 25,
11+
},
12+
{
13+
type: '分类三',
14+
value: 18,
15+
},
16+
{
17+
type: '分类四',
18+
value: 15,
19+
},
20+
{
21+
type: '分类五',
22+
value: 10,
23+
},
24+
{
25+
type: 'Other',
26+
value: 5,
27+
},
28+
];
29+
30+
const piePlot = new g2plot.Pie(document.getElementById('canvas'), {
31+
padding: 'auto',
32+
data,
33+
angleField: 'value',
34+
colorField: 'type',
35+
label: {
36+
visible: true,
37+
formatter: (text, item, index) => {
38+
return `${(item.percent * 100).toFixed(2)}%`;
39+
},
40+
},
41+
tooltip: {
42+
visible: true,
43+
shared: false,
44+
htmlContent: (title, items) => {
45+
const item = items[0];
46+
return `<div class="g2-tooltip">
47+
<div class="g2-tooltip-title" style="margin-bottom: 4px;">显示百分比</div>
48+
<ul class="g2-tooltip-list" style="margin: 0px; list-style-type: none; padding: 0px;">
49+
<li data-index="0" style="margin: 0px 0px 4px; list-style-type: none; padding: 0px;">
50+
<span style="background-color: ${
51+
item.color
52+
}; width: 5px; height: 5px; border-radius: 50%; display: inline-block; margin-right: 8px;" class="g2-tooltip-marker"></span>
53+
${item.name}<span class="g2-tooltip-value" style="display: inline-block; float: right; margin-left: 30px;">${(
54+
item.percent * 100
55+
).toFixed(2)}%</span>
56+
</li>
57+
</ul>
58+
</div>`;
59+
},
60+
},
61+
});
62+
piePlot.render();
63+
64+
// 作为模块 避免变量冲突
65+
export {};

src/plots/pie/layer.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { LayerConfig } from '../../base/layer';
55
import ViewLayer, { ViewConfig } from '../../base/view-layer';
66
import { getComponent } from '../../components/factory';
77
import { getGeom } from '../../geoms/factory';
8-
import { Label, DataItem } from '../../interface/config';
8+
import { Label, DataItem, Tooltip } from '../../interface/config';
99
import { LooseMap } from '../../interface/types';
1010
import SpiderLabel from './component/label/spider-label';
1111
import './component/label/outer-label';
@@ -171,6 +171,9 @@ export default class PieLayer<T extends PieLayerConfig = PieLayerConfig> extends
171171
if (props.label) {
172172
this.label();
173173
}
174+
if (props.tooltip && props.tooltip.visible) {
175+
this.tooltip();
176+
}
174177
this.setConfig('element', pie);
175178
}
176179

@@ -189,6 +192,42 @@ export default class PieLayer<T extends PieLayerConfig = PieLayerConfig> extends
189192
super.parseEvents(EventParser);
190193
}
191194

195+
protected tooltip() {
196+
const props = this.options;
197+
if (props.tooltip.htmlContent) {
198+
const customHtmlContent = props.tooltip.htmlContent;
199+
this.setConfig('tooltip', {
200+
...this.options.tooltip,
201+
htmlContent: (title, items: any[]) => {
202+
if (items && items.length) {
203+
const { angleField } = this.options;
204+
const filteredSum = this.getFilteredSum();
205+
return customHtmlContent(
206+
title,
207+
items.map((item) => {
208+
const value = _.get(item, `point._origin.${angleField}`);
209+
const percent = value / filteredSum;
210+
return {
211+
...item,
212+
percent,
213+
};
214+
})
215+
);
216+
}
217+
return '<div></div>';
218+
},
219+
} as any);
220+
}
221+
}
222+
223+
private getFilteredSum() {
224+
const { angleField } = this.options;
225+
const filteredData = this.view.get('filteredData') || [];
226+
return filteredData.reduce((pre, filteredDataItem) => {
227+
return pre + filteredDataItem[angleField];
228+
}, 0);
229+
}
230+
192231
private label() {
193232
const props = this.options;
194233
const labelConfig = { ...props.label } as Label;
@@ -203,6 +242,22 @@ export default class PieLayer<T extends PieLayerConfig = PieLayerConfig> extends
203242
// @ts-ignore
204243
labelConfig.labelLine = true;
205244
}
245+
if (labelConfig.formatter) {
246+
const customFormatter = labelConfig.formatter;
247+
labelConfig.formatter = (text, item, index) => {
248+
const { angleField } = this.options;
249+
const filteredSum = this.getFilteredSum();
250+
const percent = item._origin[angleField] / filteredSum;
251+
return customFormatter(
252+
text,
253+
{
254+
...item,
255+
percent,
256+
},
257+
index
258+
);
259+
};
260+
}
206261

207262
// 此处做个 hack 操作, 防止g2 controller层找不到未注册的inner,outter,和spider Label
208263
let labelType = labelConfig.type;

0 commit comments

Comments
 (0)