in src/Wsunburst/index.tsx [169:366]
init(chart: Chart, config: WsunburstConfig, data: ChartData) {
const { source, total } = computeData(data, config, this);
this.totalData = numberDecimal(total, config?.legend?.decimal ?? config?.tooltip?.decimal ?? 2);
chart.data(source);
const thetaConfig: Types.CoordinateCfg = {
radius: Math.max(Math.min(config.outerRadius, 1), 0.01),
};
if (config.startAngle !== undefined) {
thetaConfig.startAngle = config.startAngle;
}
if (config.endAngle !== undefined) {
thetaConfig.endAngle = config.endAngle;
}
if (config.cycle) {
thetaConfig.innerRadius = Math.max(Math.min(config.innerRadius, 1), 0);
}
chart.coordinate('polar', thetaConfig);
chart.axis(false);
// 多重圆环默认开启分组,这里通过自定义图例实现
// 自定义图例会有更新问题
const newItems: G2Dependents.ListItem[] = dodgeItems(source, config);
rectLegend(
this,
chart,
config,
{
items: newItems,
},
'single',
null,
true,
);
// tooltip
rectTooltip(
this,
chart,
config,
{
showTitle: false,
showMarkers: false,
showCrosshairs: false,
shared: false,
},
(ev: any) => {
const { items } = ev.data;
items.forEach((item: any, index: number) => {
if (typeof config.tooltip === 'boolean') {
return;
}
const pointData = item.data;
const rootNode = pointData?.parentList?.[0];
const percent = numberDecimal(item.value / rootNode.value, 4);
if (config.tooltip.valueFormatter) {
item.value = config.tooltip.valueFormatter(
item.value,
{
percent,
...pointData,
},
index,
items,
);
}
if (config.tooltip.nameFormatter) {
item.name = config.tooltip.nameFormatter(
item.name,
{
percent,
...pointData,
},
index,
items,
);
}
});
},
{
showTitle: false,
showMarkers: false,
showCrosshairs: false,
shared: false,
},
);
const geom = chart
.polygon({
// TODO 控制每一层的宽度占比
// 多层饼图配置不生效
// multiplePieWidthRatio: 1
})
.position('x*y')
// 暂不支持自定义颜色
.color('name*color', (xVal, yVal) => {
return yVal;
})
.tooltip('name*value*rawValue*depth', (name, value) => {
return {
name,
value,
};
});
geomStyle(
geom,
config.geomStyle,
(...args: any) => {
const value = args[1] || args[2];
const deep = args[3];
const percent = args[4];
return {
// 增加圆环边线装饰
stroke: themes['widgets-color-background'],
lineWidth: config.showSpacing && value !== 0 && percent > 0.005 ? 1 : 0,
cursor: config.select && deep === 1 && !this.isEmpty ? 'pointer' : 'default',
}
},
'name*value*rawValue*depth*percent',
);
polarLegendLayout(chart);
// 环图中心内容
if (
config.cycle &&
config.innerContent &&
!this.props.children &&
!this.isEmpty &&
!this.props.loading &&
!this.props.errorInfo
) {
const container = deleteChildren(this.chartDom);
container.className = `${FullCrossName}-children`;
const firstChild = this.chartDom.firstChild;
this.chartDom.insertBefore(container, firstChild);
const content = (
<Wnumber
bottomTitle={config?.innerContent?.title ?? this.rawData?.name}
unit={config?.innerContent?.unit ?? ''}
>
{config?.innerContent?.value ?? this.totalData}
</Wnumber>
);
ReactDOM.render(content, container);
} else if (!this.props.children) {
// 删去中心内容
deleteChildren(this.chartDom);
}
chart.on('afterpaint', () => {
updateChildrenPosition(chart, this.chartDom);
});
drillDown(chart, (context: any, isCenter?: boolean) => {
const { view } = context;
const filterData = view.filteredData ?? [];
const eventData = get(context, ['event', 'data', 'data']);
if (!this.isEmpty) {
let sum = 0;
if (isCenter) {
sum = this.totalData;
} else {
filterData.forEach((el: any) => {
if (!el?.children) {
sum += el?.value ?? 0;
}
})
}
const newContainer = deleteChildren(this.chartDom);
newContainer.className = `${FullCrossName}-children`;
const firstChild = this.chartDom.firstChild;
this.chartDom.insertBefore(newContainer, firstChild);
const content = (
<Wnumber
bottomTitle={config?.innerContent?.title ?? eventData?.name ?? this?.rawData?.name}
unit={config?.innerContent?.unit ?? ''}
>
{config?.innerContent?.value ?? sum}
</Wnumber>
);
ReactDOM.render(content, newContainer);
updateChildrenPosition(chart, this.chartDom);
}
});
}