3/4环形图实现
通过循环数据,把每一条数据放入一个环形图内,每一个环形图分为3块空间:
- 实际数据占据的空间
这里占据的空间需要转换成3/4比例:value * 0.75
- 虚拟的3/4环形图剩下的数据
这里是占据3/4空间内除了实际数据之后剩余空间:(总数据-value) * 0.75
- 1/4需要做成透明的数据
始终占据1/4空间:总数 * 0.25,颜色设置为transparent透明色
利用y轴上显现旁边的注释。注意x轴也必须写!
xAxis: [{ show: false }], yAxis: [ { type: "category", inverse: true, axisLine: { show: false, }, axisTick: { show: false, }, axisLabel: { }, data: lineYAxis, }, ],
效果图
优点:
通过这一系列计算保证了环形图数据量过大时不会溢出
缺点:
- 环形图数据项不能过多,因为内圈最小就是0%。
- 在缩放的时候放大基本没问题,缩小的时候会出现数据注释对应不上的问题。
因为这里是grid定位,y轴label来显示数据,考虑给grid设置一个高度,但是这个高度应该随着环形图的半径来变化,而环形缩放的时候resize方法是按照盒子给定的最小宽或高来设置大小,用来保持为一个圆。所以不知道怎么取这个高度才能为最小...
希望读者能解决这个问题,并评论补充!
js实现代码:
export default {
data() {
return {
ectOpts: {},
error: "",
loading: false,
latest: true,
data: [],
};
},
computed: {
total() {
let total = this.data.reduce((item1, item2) => {
return (typeof item1 === "number" ? item1 : item1.num) + item2.num;
});
return total;
},
},
created() {
this.getData();
},
mounted() {
this.initEchart();
},
methods: {
getData() {
this.data = [
{ name: "钱包支付", num: 13210 },
{ name: "现金支付", num: 42111 },
{ name: "记账支付", num: 81711 },
{ name: "移动支付", num: 121700 },
];
this.data.forEach((item) => {
item.percent = ((item.num / this.total) * 100).toFixed(1);
});
},
initEchart() {
let color = [
"rgba(255, 135, 0, 1)",
"rgba(255, 195, 0, 1)",
"rgba(0, 228, 115, 1)",
"rgba(0, 157, 255, 1)",
].reverse();
let pieSeries = [];
let lineYAxis = [];
this.data.forEach((item, index) => {
let iname = item.name;
let inum = item.num;
pieSeries.push({
name: iname,
type: "pie",
radius: [65 - 15 * index + "%", 57 - 15 * index + "%"],
// 关闭悬停动画
hoverAnimation: false,
// 是否顺时针旋转
clockwise: false,
center: ["35%", "50%"],
label: {
show: false,
},
data: [
{
// 只设置3/4的值,以用于3/4环形图
value: inum * 0.75,
name: iname,
tooltip: {
formatter: (item) => {
return `<div style="display:flex;font-size:12px;">
<div style="color:${item.color};margin-right:10px;">●</div>
<div>
<div>${item.seriesName}:${item.value} 辆</div>
<div>占比:${(item.percent / 0.75).toFixed(1) + "%"}</div>
</div>
</div>
`
},
}
},
{
// 这里的值+上面的值为总和,但是只占比75%
value: (this.total - inum) * 0.75,
itemStyle: {
color: "rgba(0, 132, 251, 0.2)",
},
tooltip: {
show: false
}
},
{
// 弃用25%的环形图不做显示
value: this.total * 0.25,
itemStyle: {
color: "rgba(0,0,0,0)",
},
tooltip: {
show: false
}
},
],
});
lineYAxis.push({
value: index,
textStyle: {
rich: {
circle: {
color: color[index],
padding: [0, 5],
},
},
},
});
});
this.ectOpts = {
tooltip: {
trigger: "item",
},
color,
grid: {
top: "15%",
bottom: "54%",
left: "35%",
containLabel: false,
},
// 有yAxis必须有xAxis
xAxis: [{ show: false }],
yAxis: [
{
type: "category",
// 反向坐标轴
inverse: true,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
axisLabel: {
formatter: (params) => {
let item = this.data[params];
return `{line|----------}{circle|●}{name|${item.name}:}{value|${item.num}辆,}{percent|占${item.percent}%}`;
},
interval: 0,
inside: true,
rich: {
line: {
// width: 50,
// height: 1,
color: "rgba(236, 236, 236, 1)",
// 当前echart版本不支持borderType用------代替
// borderType: "dashed",
// borderColor: "#D9DFEB",
// borderWidth: 1,
},
},
textStyle: {
color: "#fff",
fontSize: 12,
},
show: true,
},
data: lineYAxis,
},
],
series: pieSeries,
};
},
},
};