import Common from "@/util/echatrs/common"; export default class Pie extends Common { constructor(el, option) { super(el, option); this.init(); } init() { this.myChart = this.$e.init(this.$el); this.setCharts(); this.myChart.setOption(this.chartOption, true); window.addEventListener("resize", () => { this.myChart.resize(); }); this.myChart.on("click", (a) => { if (this.option.click) { this.option.click(a); } }); } setCharts() { const field = this.setField(); this.chartOption = { tooltip: { trigger: "item" }, color: field.colors, title: { text: field.total + "个", top: "center", left: "center", textStyle: { color: "#FFF", fontSize: 13 }, }, legend: { show: false }, series: [ { type: "pie", data: field.valueData, label: { show: false, position: "outside", align: "center", verticalAlign: "middle", formatter(params) { return params.data.name; } }, labelLine: { show: true }, emphasis: { scale: true, scaleSize: 20, itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(255, 255, 255, 1)" // 鼠标移动到图上时,的阴影的颜色 } }, blur: { itemStyle: { opacity: 0.1 } }, radius: ["20%", "45%"], }, { type: "pie", startAngle: -360 * (field.itemReduced / 2 / field.valueTotal) + 90, radius: ["45%", "65%"], itemStyle: { opacity: 0.6, // 控制饼图最外层部分的透明度,颜色值是在new这个类的时候传入的值 }, label: { show: true, formatter(params) { return "{a|" + params.data.name + "}"; }, rich: { a: { lineHeight: 20, color: this.option.labelColor || "#000000", fontWeight: 900 } } }, labelLine: { show: false, length: 10, }, data: field.outValueData } ] }; } setField() { const colors = this.option.colors; const sourceData = this.option.data; const total = sourceData.reduce((num, item) => { num += item.value; return num; }, 0); // 内环间隔距离 const inSplitWidth = 3; // 为了实现内环间隔距离,需要额外插入的数值。200 只是个系数,值越大,单位间隔的距离越小。 const inSplitValue = Math.floor(total / (150 / inSplitWidth)); // 外环间隔比内环间隔大的值 const itemSplitWidth = 2; // 外环间隔距离 const outSplitWidth = inSplitWidth + itemSplitWidth; // 为了实现外环间隔距离,需要额外插入的数值。 const outSplitValue = Math.floor(total / (150 / outSplitWidth)); // 内环数据的总数 const valueTotal = total + inSplitValue * sourceData.length; function getTextAngle(currentAngle, angle) { currentAngle = currentAngle + angle; if (currentAngle <= 90) { return -currentAngle; } else if (currentAngle <= 180 && currentAngle > 90) { return 180 - currentAngle; } else if (currentAngle < 270 && currentAngle > 180) { return 180 - currentAngle; } else if (currentAngle < 360 && currentAngle >= 270) { return 360 - currentAngle; } } // 内环数据。在原数据的后面添加间隔数据(间隔块设置颜色透明) const valueData = sourceData.reduce((arr, item) => { const currentTotal = arr.reduce((total, item) => { total += item.value; return total; }, 0); const currentAngle = 360 * (currentTotal / valueTotal); const angle = 360 * (item.value / valueTotal) / 2; arr.push({ name: item.name, value: item.value, label: { lineHeight: 80, rotate: getTextAngle(currentAngle, angle) } }, { name: "", value: inSplitValue, itemStyle: { color: "transparent", opacity: 0 }, label: { show: false }, labelLine: { show: false } }); return arr; }, []); // 原数据需要减去的值(外环每块的数据都要比原数据少一点才能达到外环嵌在内环的效果) const itemReduced = outSplitValue - inSplitValue; // 外环数据 const outValueData = sourceData.reduce((arr, item) => { const currentTotal = arr.reduce((total, item) => { total += item.value; return total; }, 0); const currentAngle = 360 * (currentTotal / valueTotal); const angle = 360 * (item.value / valueTotal) / 2; arr.push({ name: item.name, value: item.value, label: { color: "#fff", position: "inside", align: "center", lineHeight: 10, // verticalAlign: 'top', rotate: getTextAngle(currentAngle, angle) } }, { name: "", value: outSplitValue, itemStyle: { color: "transparent", opacity: 0 }, label: { show: false, textStyle: { fontSize: 12, color: "#fff" } }, labelLine: { show: false } }); return arr; }, []); return { colors, total, valueData, itemReduced, valueTotal, outValueData }; } }