<template> <div :class="className" :style="{ height: height, width: width }" /> </template> <script> import * as echarts from "echarts" require("echarts/theme/macarons") // echarts theme import resize from "./mixins/resize" const animationDuration = 2600 export default { mixins: [resize], props: { className: { type: String, default: "chart" }, width: { type: String, default: "100%" }, height: { type: String, default: "100%" }, autoResize: { type: Boolean, default: true }, chartData: { type: Object, required: true }, chartConfig: { type: Object, default: () => { return {} } }, title: { type: String, default: "分布图" }, subTitle: { type: String, default: "--" } }, data() { return { chart: null, colorList: [ { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#2FC89C" // 0% 处的颜色 }, { offset: 1, color: "#5DF1BA" // 100% 处的颜色 } ] }, { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#2C71D8" // 0% 处的颜色 }, { offset: 1, color: "#4DA4F4" // 100% 处的颜色 } ] }, { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#576BF5" // 0% 处的颜色 }, { offset: 1, color: "#3234DB" // 100% 处的颜色 } ] }, { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#D78935" // 0% 处的颜色 }, { offset: 1, color: "#EFA75A" // 100% 处的颜色 } ] } ], opacityList: [ { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#5FF2BB" // 0% 处的颜色 }, { offset: 1, color: "#31CA9D" // 100% 处的颜色 } ] }, { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#4DA4F4" // 0% 处的颜色 }, { offset: 1, color: "#2C71D8" // 100% 处的颜色 } ] }, { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#3234DB" // 0% 处的颜色 }, { offset: 1, color: "#576BF5" // 100% 处的颜色 } ] }, { x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: "#EFA75A" // 0% 处的颜色 }, { offset: 1, color: "#D78935" // 100% 处的颜色 } ] } ], // opacityList: [ // "rgba(67, 215, 181, 0.2)", // "rgba(56, 131, 248, 0.2)", // "rgba(33, 81, 255, 0.2)", // "rgba(11, 234, 216, 0.2)", // ], pieConfig: {} } }, watch: { chartData: { deep: true, handler(val) { this.setOptions(val) } } }, mounted() { this.$nextTick(() => { this.initChart() }) }, beforeDestroy() { if (!this.chart) { return } this.chart.dispose() this.chart = null }, methods: { buildDataFuc(myChart) { this.pieConfig = { // color: ["#43d7b5", "#2151ff", "#97ead8", "#3883f8"], title: { text: "0", subtext: "--", x: '10%', y: "33%", textStyle: { color: "white", fontStyle: "italic", fontSize: 16, fontWeight: 500, align: "center" }, subtextStyle: { color: "rgba(255,255,255,0.4)", fontStyle: "italic", fontSize: 14, fontWeight: 500, align: "center" }, itemGap: 5 //主副标题间距 }, grid: { // left: '-50%', // // align: "left", // // right: 38, // // bottom: 30, // // top: "-10%", // // bottom:10, // containLabel: true, }, tooltip: { trigger: "item", borderWidth: 0, textStyle: { color: "#ffffff" }, formatter: "{b} : {c} ({d}%)" }, legend: { right: "right", // y: "center", align: "left", // right:'-30%', // bottom: 5, itemGap: 1, icon: "circle", orient: "vertical", itemHeight: 8, itemWidth: 8, textStyle: { color: "rgba(255,255,255,0.4)", // padding: [0, 0, -10, 0], fontStyle: "Arial Normal" }, show: true, data: [] }, series: [ { title: {}, type: "pie", zlevel: 3, left: 0, showEmptyCircle: true, //无数据占位圆 // color: [ // "rgba(67, 215, 181, 1)", // "rgba(56, 131, 248, 1)", // "rgba(33, 81, 255, 1)" // // "rgba(11, 234, 216, 0.2)", // ], center: ["30%", "45%"], radius: ["48%", "62%"], // avoidLabelOverlap: false, //防止标签重叠策略 animationEasing: "cubicInOut", animationDuration, itemStyle: { normal: { //发光 // shadowBlur: 5, // shadowColor: "rgba(255,255,255,0.3)", // borderColor: '#19202f', // borderWidth: 4, // borderJoin:'round' } }, label: { alignTo: "labelLine", //label line 的末端对齐 position: "outer", margin: 10, formatter: function(params) { if (params.value > 0) { return ( "{number|" + params.data.count + "} {percent|(" + params.value + "%)}\n\n {name|" + params.name + "}" ) } else { return "" } }, // padding: [0, -110, 0, -110], // padding: [0, -155, 0, -155], // minMargin: 5, // edgeDistance: "10%",//label.alignTo 为 'edge' 时有效 // distanceToLabelLine:10, lineHeight: 15, rich: { number: { align: "center", fontSize: 36, color: "#fff", // fontWeight:600, padding: [0, -10, 0, -20] }, percent: { align: "center", fontSize: 12, color: "#fff", // padding: [5, -10, 0, 20], padding: [0, -20, 0, 10] }, name: { align: "center", fontSize: 16, color: "#fff", padding: [10, -30, 10, -20] // fontStyle: "monospace", // padding: [0,100, 0, 100] } }, rotate: 0, show: false, overflow: "truncate", //超出宽度截断 ellipsis: "...", //在overflow配置为'truncate'的时候,可以通过该属性配置末尾显示的文本。 position: "outer", //饼图扇区外侧 bleedMargin: 10, distanceToLabelLine: 5 }, labelLine: { show: false }, // labelLine: { // // normal: { // // length: 20, // // length2: 120, // minTurnAngle: 90, //两线夹角 // length: 15, // length2: 120, // maxSurfaceAngle: 80 //通过调整第二段线的长度,限制引导线与扇区法线的最大夹角。设置为小于 90 度的值保证引导线不会和扇区交叉。 // // } // }, // labelLayout: function(params) { // // const isLeft = params.labelRect.x < myChart.getWidth() / 2; // const isRight = params.labelRect.x>400 // if (params.text&&isRight) { // return label.text="isRight" // // const isLeft = true; // // const points = params.labelLinePoints; // // // Update the end point. // // points[2][0] = isLeft // // ? params.labelRect.x // // : params.labelRect.x + params.labelRect.width; // // return { // // labelLinePoints: points, // // }; // } // }, data: [] }, //嵌套 放第一个覆盖下层 { name: "人员类型", type: "pie", zlevel: 2, hoverAnimation: false, legendHoverLink: false, animationEasing: "cubicInOut", animationDuration, cursor: "default", // color: [ // "rgba(67, 215, 181, 0.2)", // "rgba(56, 131, 248, 0.2)", // "rgba(33, 81, 255, 0.2)" // // "rgba(11, 234, 216, 0.2)", // ], center: ["30%", "45%"], radius: ["43%", "49%"], label: { normal: { show: false, position: "inner" } }, labelLine: { normal: { show: false } }, tooltip: { show: false }, itemStyle: { normal: { //发光 // borderColor: 'white', // borderWidth: 1, } }, data: [ // { // value: 100, // name: "" // }, // { // value: 100, // name: "" // } ] } // //边框环 // { // name: "人员类型", // type: "pie", // hoverAnimation: false, // legendHoverLink: false, // animationEasing: "cubicInOut", // animationDuration, // cursor: "default", // color: ["white"], // center: ['25%', '45%'], // radius: ["48.1%", "48.6%"], // itemStyle: { // normal: { // color: " rgba(255,255,255,0.2)", // }, // }, // label: { // normal: { // show: false, // position: "inner", // }, // }, // labelLine: { // normal: { // show: false, // }, // }, // tooltip: { // show: false, // }, // data: [ // { // value: 100, // name: "", // }, // ], // }, ] } }, initChart() { this.chart = echarts.init(this.$el, "macarons") this.setOptions(this.chartData) this.$nextTick(() => { this.buildDataFuc(this.chart) // console.log("取到宽高", this.chart); }) }, setOptions(chartData) { if (!chartData.data) return this.buildDataFuc() let option = {} let length = 0 option = Object.assign(this.pieConfig, this.chartConfig) const series = chartData.data.map((v) => { if (Number(v.value) != 0) { return { name: v.name, value: Number(v.value), count: v.count || "--", labelLine: { show: false, //不显示标签线条 // normal: { length: 20, length2: 145, minTurnAngle: 120, //两线夹角 // length: 15, // length2: 120, maxSurfaceAngle: 80, //通过调整第二段线的长度,限制引导线与扇区法线的最大夹角。设置为小于 90 度的值保证引导线不会和扇区交叉。 lineStyle: { width: 2 } // } } } } else { return { name: v.name, count: v.count || "--", value: Number(v.value), lableLine: { show: false } } } }) const dataList = chartData.data.map((v) => { // if (Number(v.value) != 0) { return { value: Number(v.value) } // } }) if (option.legend.show) { option.legend.data = series.map((_) => _.name) } option.series[0].data = series option.series[1].data = dataList option.title.text = this.title option.title.subtext = this.subTitle //颜色设置 length = series.length option.series[0].color = this.colorList.slice(0, length) option.series[1].color = this.opacityList.slice(0, length) // if(option.series[0].labelLayout){ // option.series[0].labelLine={show:false} // } //引导线设置 // this.$nextTick(() => { // option.series[0].labelLayout = function(params) { // if(params.text){ // console.log("执行?", params, this.chart,chartData); // const isLeft = params.labelRect.x <script this.chart.getWidth() / 2; // const points = params.labelLinePoints; // // Update the end point. // points[2][0] = isLeft // ? params.labelRect.x // : params.labelRect.x + params.labelRect.width; // return { // labelLinePoints: points // }; // } // }; // }); this.chart && this.chart.setOption(option) } } } </script>