需求:页面展示几个关键单位信息,之后其他所有单位都放到其他里面汇总,鼠标划入其他显示所有单位的数据以及信息。
效果图: 即拿即用 直接CV代码即可出现如图效果
代码实现:
html
<template>
<div class="rightTopCompont">
<div id="rightPieEchart"></div>
</div>
</template>
js
<script>
import * as echarts from "echarts";
export default {
data() {
return { total: 0 };
},
mounted() {
this.init();
},
methods: {
init() {
var data = [
{
projectNum: "10",
provinceName: "中国XXX单位",
stageNumThree: "8",
stageNumTwo: "2"
},
{
projectNum: "19",
provinceName: "中国XXX单位1",
stageNumThree: "10",
stageNumTwo: "9"
},
{
projectNum: "5",
provinceName: "中国XXX单位2",
stageNumThree: "0",
stageNumTwo: "5"
},
{
projectNum: "9",
provinceName: "中国XXX单位3",
stageNumThree: "9",
stageNumTwo: "0"
},
{
projectNum: "5",
provinceName: "中国XXX单位5",
stageNumThree: "3",
stageNumTwo: "2"
},
{
projectNum: "15",
provinceName: "其他",
stageNumThree: "7",
stageNumTwo: "9",
projectAccountVOS: [
{
projectNum: "10",
provinceName: "中国XXX单位中国XXX单位中国XXX单位中国XXX单位中国XXX单位",
stageNumThree: "8",
stageNumTwo: "2"
},
{
projectNum: "19",
provinceName: "中国XXX单位1",
stageNumThree: "10",
stageNumTwo: "9"
},
{
projectNum: "5",
provinceName: "中国XXX单位2",
stageNumThree: "0",
stageNumTwo: "5"
},
{
projectNum: "9",
provinceName: "中国XXX单位3",
stageNumThree: "9",
stageNumTwo: "0"
},
{
projectNum: "5",
provinceName: "中国XXX单位5",
stageNumThree: "3",
stageNumTwo: "2"
},
{
projectNum: "10",
provinceName: "中国XXX单位",
stageNumThree: "8",
stageNumTwo: "2"
},
{
projectNum: "19",
provinceName: "中国XXX单位1",
stageNumThree: "10",
stageNumTwo: "9"
},
{
projectNum: "5",
provinceName: "中国XXX单位2",
stageNumThree: "0",
stageNumTwo: "5"
},
{
projectNum: "9",
provinceName: "中国XXX单位3",
stageNumThree: "9",
stageNumTwo: "0"
},
{
projectNum: "5",
provinceName: "中国XXX单位5",
stageNumThree: "3",
stageNumTwo: "2"
},
{
projectNum: "10",
provinceName: "中国XXX单位",
stageNumThree: "8",
stageNumTwo: "2"
},
{
projectNum: "19",
provinceName: "中国XXX单位1",
stageNumThree: "10",
stageNumTwo: "9"
},
{
projectNum: "5",
provinceName: "中国XXX单位2",
stageNumThree: "0",
stageNumTwo: "5"
},
{
projectNum: "9",
provinceName: "中国XXX单位3",
stageNumThree: "9",
stageNumTwo: "0"
},
{
projectNum: "5",
provinceName: "中国XXX单位5",
stageNumThree: "3",
stageNumTwo: "2"
}
]
}
];
this.pieEcharts(data);
},
pieEcharts(data) {
var myChart = echarts.init(document.getElementById("rightPieEchart"));
let title = "单位";
var color = [
{
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#25E0C8" },
{ offset: 1, color: "#16C5AF " }
])
},
{
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#FAB280" },
{ offset: 1, color: "#ECA06C " }
])
},
{
// 颜色渐变
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#62BFFA" },
{ offset: 1, color: "#47B0F3 " }
])
},
{
// 颜色渐变
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#8BEFAB" },
{ offset: 1, color: "#6ADD8F " }
])
},
{
// 颜色渐变
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#008D81" },
{ offset: 1, color: "#008D91 " }
])
},
{
// 颜色渐变
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#6ADDF2" },
{ offset: 1, color: "#6ADDF9 " }
])
},
{
// 颜色渐变
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#EB905C" },
{ offset: 1, color: "#EB907C " }
])
}
];
let echartData = [];
var formatNumber = null;
if (data.length > 0) {
data.forEach((item, index) => {
echartData.push({
name: item.provinceName,
value: item.projectNum,
data: {
supervisor: item.stageNumTwo,
construction: item.stageNumThree
},
itemStyle: {
// 颜色渐变
normal: color[index]
},
projectAccountVOS: [
{
name: item.provinceName,
value: item.projectNum,
data: {
supervisor: item.stageNumTwo,
construction: item.stageNumThree
},
itemStyle: {
// 颜色渐变
normal: color[index]
}
}
]
});
if (item.projectAccountVOS) {
if (item.provinceName == "其他") {
echartData[index].projectAccountVOS = [];
}
item.projectAccountVOS.forEach(it => {
echartData[index].projectAccountVOS.push({
name: it.provinceName,
value: it.projectNum,
data: {
supervisor: it.stageNumTwo,
construction: it.stageNumThree
}
});
});
}
});
formatNumber = num =>
num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
this.total = echartData.reduce((a, b) => a + +b.value, 0);
}
var option;
// 指定图表的配置项和数据
if (data.length == 0) {
//暂无数据
option = {
title: {
text: "暂无数据",
x: "center",
y: "center",
textStyle: {
fontSize: 14,
color: "#ccc",
fontWeight: "normal"
}
}
};
} else {
option = {
title: [
{
text:
"{val|" +
formatNumber(this.total) +
"}{unit|个" +
"}\n {name|" +
title +
"}",
textAlign: "center",
top: "center",
x: "24%",
textStyle: {
rich: {
name: {
fontSize: this.$fontChart(0.14),
fontWeight: "400",
color: "#000000",
fontFamily: "PingFangSC-Regular, PingFang SC"
},
unit: {
fontSize: this.$fontChart(0.12),
fontWeight: "400",
color: "#666666",
fontFamily: "Source Han Sans CN-Regular, Source Han Sans CN"
},
val: {
fontSize: this.$fontChart(0.3),
fontFamily: "DIN Alternate-Bold, DIN Alternate",
fontWeight: "bold",
color: "#000000"
}
}
}
}
],
tooltip: {
trigger: "item",
confine: true,
backgroundColor: "rgba(0,0,0,0)", // 提示框浮层的背景颜色。
position: function(point, params, dom, rect, size) {
var x = 0; // x坐标位置
var y = 0; // y坐标位置
// 当前鼠标位置
var pointX = point[0];
var pointY = point[1];
// 提示框大小
var boxWidth = size.contentSize[0];
var boxHeight = size.contentSize[1];
// boxWidth > pointX 说明鼠标左边放不下提示框
if (boxWidth > pointX) {
x = pointX + 10;
} else {
// 左边放的下
x = pointX - boxWidth - 10;
}
// boxHeight > pointY 说明鼠标上边放不下提示框
if (boxHeight > pointY) {
y = 5;
} else {
// 上边放得下
y = pointY - boxHeight;
}
if (params.name == "其他") {
return [30, point[1]];
} else {
return [x, y];
}
},
formatter: params => {
var res = "";
res += `
<div
class="Box"
style="
background: #fff;
width: 150px;
height: auto;
max-height: 500px;
box-shadow: 0px 0px 6px 1px rgba(106, 106, 106, 0.16);
border-radius: 5px 5px 5px 5px;
padding: 0 20px;
overflow-y:auto;
overflow-x:hidden
"
>
${params.data.projectAccountVOS.map(item => {
var totalData =
item.data.supervisor == 0 || item.data.construction == 0
? 146
: 130;
var oneWidthData = (
(Number(item.data.supervisor) / Number(item.value)) *
totalData
).toFixed(2);
var twoWidthData = (
(Number(item.data.construction) / Number(item.value)) *
totalData
).toFixed(2);
return `
<div
style="
padding-top: 5px;
font-size: 16px;
font-family: 'Source Han Sans CN-Medium, Source Han Sans CN';
font-weight: 500;
color: #333333;
word-wrap: break-word;
width:100%;
height:auto;
word-break: break-all;
overflow: hidden;
"
>
${String(item.name).replace(/(.{9})/g, "$1<br/>")}
</div>
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 12px;
"
>
<div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<img
style="width: 20px; height: 20px; margin-right: 9px"
src="${require("../assets/images/engineerProject/unitNumber.png")}"
/>
<div
style="
font-size: 14px;
font-family: 'Source Han Sans CN-Regular, Source Han Sans CN';
font-weight: 400;
color: #333333;
"
>
单位总数
</div>
</div>
<div
style="
font-size: 16px;
font-family: 'Source Han Sans CN-Medium, Source Han Sans CN';
font-weight: 500;
color: #333333;
"
>
${item.value}
</div>
</div>
<div style="display: flex; height: 8px; margin-top: 10px; width: 146px">
<div style="height: 8px; background: #16c5af; width: ${oneWidthData}px"></div>
<div style="display: ${
item.data.supervisor == 0 || item.data.construction == 0
? "none"
: "flex"
};">
<div
style="
height: 0;
background: #fff;
width: 0;
border-color: #16c5af transparent;
border-width: 0px 8px 8px 0px;
border-style: solid;
"
></div>
<div
style="
height: 0px;
background: #fff;
width: 0px;
border-color: rgba(22, 197, 175, 0.5) transparent;
border-width: 8px 0px 0px 8px;
border-style: solid;
"
></div>
</div>
<div
style="
height: 8px;
background: rgba(22, 197, 175, 0.5);
width: ${twoWidthData}px
"
></div>
</div>
<div style="display: flex; align-items: center">
<div>
<div style="display: flex; align-items: center; margin-top: 5px">
<div
style="
width: 6px;
height: 6px;
background: #16c5af;
margin-right: 5px;
"
></div>
<div style="color: #333; font-size: 12px">JL单位</div>
</div>
<div
style="
color: #333;
font-size: 14px;
font-weight: 500;
margin-top: 5px;
margin-left: 11px;
"
>
${item.data.supervisor}
</div>
</div>
<div style="margin-left: 25px">
<div style="display: flex; align-items: center; margin-top: 5px">
<div
style="
width: 6px;
height: 6px;
background: #16c5af;
margin-right: 5px;
"
></div>
<div style="color: #333; font-size: 12px">SG单位</div>
</div>
<div
style="
color: #333;
font-size: 14px;
font-weight: 500;
margin-top: 5px;
margin-left: 11px;
"
>
${item.data.construction}
</div>
</div>
</div>
`;
})}
</div>
`;
return res;
}
},
legend: {
// orient: "horizontal",
x: "45%",
y: "center",
// legend 添加滚动请用以下代码
orient: "vertical", //垂直方向滚
type: "scroll",
pageIcons: {
vertical: [
"path://M472.064 272.448l-399.232 399.232c-22.08 22.08-22.08 57.792 0 79.872 22.016 22.016 57.792 22.08 79.872 0L512 392.256l359.296 359.296c22.016 22.016 57.792 22.08 79.872 0 22.08-22.08 22.016-57.792 0-79.872L551.936 272.448C529.856 250.432 494.144 250.432 472.064 272.448z",
"path://M472.064 751.552 72.832 352.32c-22.08-22.08-22.08-57.792 0-79.872 22.016-22.016 57.792-22.08 79.872 0L512 631.744l359.296-359.296c22.016-22.016 57.792-22.08 79.872 0 22.08 22.08 22.016 57.792 0 79.872l-399.232 399.232C529.856 773.568 494.144 773.568 472.064 751.552z"
]
},
pageButtonPosition: "end", // 翻页的位置。'start':控制块在左或上,end控制块在右或下。
pageIconColor: "#29bca8", // 可以点击的翻页按钮颜色
pageIconInactiveColor: "#7f7f7f", // 禁用的按钮颜色
pageIconSize: 14, //这当然就是按钮的大小
itemWidth: this.$fontChart(0.1),
itemHeight: this.$fontChart(0.1),
align: "left",
textStyle: {
rich: {
nameStyle: {
fontSize: this.$fontChart(0.14),
width: this.$fontChart(0.9),
color: "#333",
fontWeight: 400
},
rate: {
width: this.$fontChart(0.3),
fontSize: this.$fontChart(0.14),
color: "#333",
fontWeight: 400
},
supervisor: {
width: this.$fontChart(0.6),
fontSize: this.$fontChart(0.14),
color: "#666",
fontWeight: 400
},
construction: {
width: this.$fontChart(0.6),
fontSize: this.$fontChart(0.14),
color: "#666",
fontWeight: 400
}
}
},
formatter: function(name) {
let res = echartData.filter(v => v.name === name);
res = res[0] || {};
var str = "";
var strData = res.name;
if (strData) {
strData =
strData.length > 4
? strData.substring(0, 4) + "..."
: strData;
} else {
strData = "无";
}
str =
"{nameStyle|" +
strData +
" }" +
"{rate|" +
res.value +
" }" +
"{supervisor|" +
"(JL:" +
res.data.supervisor +
"}" +
"{construction|" +
"SG:" +
res.data.construction +
")}";
return str;
}
},
series: [
{
type: "pie",
radius: ["55%", "75%"],
center: ["25%", "50%"],
data: echartData,
name: "工单总数",
hoverAnimation: true,
itemStyle: {
normal: {
borderColor: "#fff",
borderWidth: 3
}
},
labelLine: {
show: false
},
label: {
show: false
}
}
]
};
}
myChart.setOption(option);
myChart.on("legendselectchanged", params => {
var echartsArr = []; //将点击后的数组设为空(每点击一次就重新判断添加)
// 循环点击图例后获取到的名字
for (let key in params.selected) {
// 判断值是否为true 将值为true的名字push到echartsArr数组当中保留起来
if (params.selected[key]) {
echartsArr.push(key);
}
}
var echartsNum = 0; //将总数的值设为0(每点击一次就重新计算)
// 循环判断数据的全部数据里的name值是否与我们点击图例后所剩数据的数组相等
// 相等的话就将其value值进行相加得出点击图例后所剩数据的总数
option.series[0].data.forEach(item => {
echartsArr.forEach(v => {
if (item.name === v) {
echartsNum += Number(item.value);
}
});
});
this.total = echartsNum; //最后将其赋值给主标题即可
myChart.setOption({
title: [
{
text:
"{val|" +
formatNumber(this.total) +
"}{unit|个" +
"}\n {name|" +
title +
"}",
textAlign: "center",
top: "center",
x: "24%",
textStyle: {
rich: {
name: {
fontSize: this.$fontChart(0.14),
fontWeight: "400",
color: "#000000",
fontFamily: "PingFangSC-Regular, PingFang SC"
},
unit: {
fontSize: this.$fontChart(0.12),
fontWeight: "400",
color: "#666666",
fontFamily: "Source Han Sans CN-Regular, Source Han Sans CN"
},
val: {
fontSize: this.$fontChart(0.3),
fontFamily: "DIN Alternate-Bold, DIN Alternate",
fontWeight: "bold",
color: "#000000"
}
}
}
}
]
});
});
myChart.resize();
window.addEventListener("resize", function() {
myChart.resize();
});
}
}
};
</script>
css
<style lang="scss" scoped>
.rightTopCompont {
height: 800px;
padding-top: 100px;
overflow: hidden;
margin-left: calc(100vw * 20 / 1920);
#rightPieEchart {
width: calc(100vw * 500 / 1920);
height: calc(100vh * 220 / 930);
}
}
</style>