echarts环形图,官方示例label的position为'outside'|'inside'|'inner'|'center',即环绕图形展示|展示在图形内部|在圆环图内部展示,然而,在需求中,环形图我们可能会需要满足label环绕展示的同时,中间也展示。如下图1所示,本文介绍两种方式实现如下效果:
图1
完整代码见:codesandbox.io/p/sandbox/v…
方法一:使用position:'outside'和position:'center'叠加两层图形
思考:position:'outside'可以满足label环绕图形展示,而position:'center'可以满足label在中心位置展示,既要环绕图形展示,又要在中间展示,我们为何不可把两种方式叠加起来呢? 于是,echarts的配置项写成了下面这样:
const option = {
tooltip: {
trigger: "item",
},
legend: {
top: "5%",
left: "center",
},
series: [
{
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: false,
label: {
show: true,
},
emphasis: {
label: {
show: true,
fontSize: 30,
fontWeight: "bold",
},
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: "Search" },
{ value: 735, name: "Direct" },
{ value: 580, name: "Email" },
{ value: 484, name: "Union" },
{ value: 300, name: "Video" },
],
},
{
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: false,
label: {
show: true,
position: "center",
},
emphasis: {
label: {
show: true,
fontSize: 30,
fontWeight: "bold",
},
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: "Search" },
{ value: 735, name: "Direct" },
{ value: 580, name: "Email" },
{ value: 484, name: "Union" },
{ value: 300, name: "Video" },
],
},
],
};
于是,我们得到如下图2效果:
图2
看着好像没啥问题,hover一下呢?诶,我们发现如图3:*中间部分居然出现了label的重叠*图3
这是怎么回事呢?首先,我们目前是两层图形叠加,position:'center'的图形处在series中的最后一条,那么它在最上层展示,鼠标进入时,展示它的hover效果:即emphasis中所配置的label样式。即图3中加粗放大的'Email'。同时,position:'center'时,label展示时,默认会展示出最大面积的占比name,即:小字search。由此,出现了重叠效果。既然如此,那我们label设置不展示,再设置个默认的highlight,鼠标hover切换highlight不就行了吗?代码如下: const option = {
...
series: [
...,
{
...
label: {
show: false,
position: "center",
},
...
},
],
};
myChart.setOption(option);
function setHighLight(seriesIndex, dataIndex) {
myChart.dispatchAction({
type: "downplay",
seriesIndex: [0, 1],
dataIndex: [0, 1, 2, 3, 4],
});
myChart.dispatchAction({
type: "highlight",
seriesIndex: seriesIndex,
dataIndex: dataIndex,
});
}
// 设置高亮默认值
setHighLight(1, 0);
myChart.on("mouseover", ({ dataIndex }) => {
setHighLight(1, dataIndex);
});
const resizeFn = () => {
myChart.resize();
};
window.addEventListener("resize", resizeFn);
this.$on("hook:beforeDestroy", () => {
myChart.off("mouseover");
echarts.dispose(chartDom);
window.removeEventListener("resize", resizeFn);
});
大功告成看下效果图4:
图4
方法二:使用position:'outside'结合title实现
思考:使用title定位到圆环中间,通过hover切换样式实现。如果图本身有展示title的需求,可以使用subTitle实现,代码如下:
const chartDom = document.getElementById("chartTwo");
const myChart = echarts.init(chartDom);
const option = {
title: {
text: "Search",
left: "center",
top: "middle",
fontSize: 30,
fontWeight: "bold",
},
...
series: [
{
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: false,
label: {
show: true,
},
emphasis: {
label: {
show: true,
// fontSize: 30,
// fontWeight: "bold",
},
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: "Search" },
{ value: 735, name: "Direct" },
{ value: 580, name: "Email" },
{ value: 484, name: "Union" },
{ value: 300, name: "Video" },
],
},
],
};
myChart.setOption(option);
function setHighLight(seriesIndex, dataIndex) {
myChart.dispatchAction({
type: "downplay",
seriesIndex: [0],
dataIndex: [0, 1, 2, 3, 4],
});
myChart.dispatchAction({
type: "highlight",
seriesIndex: seriesIndex,
dataIndex: dataIndex,
});
}
setHighLight(0, 0);
myChart.on("mouseover", ({ data, seriesIndex, dataIndex }) => {
myChart.setOption({
title: {
text: data.name,
},
});
setHighLight(seriesIndex, dataIndex);
});
const resizeFn = () => {
myChart.resize();
};
window.addEventListener("resize", resizeFn);
this.$on("hook:beforeDestroy", () => {
myChart.off("mouseover");
echarts.dispose(chartDom);
window.removeEventListener("resize", resizeFn);
});
效果图5:
图5