<template>
<div class="alarmTotal" id="alarmTotal"></div>
</template>
<script>
let angle = 0; //角度,用来做简单的动画效果的
let value = 80;
var timerId;
let myChart = "";
var outerRidus1 = 0.8;
var outerRidus2 = 0.85;
//获取圆上面某点的坐标(x0,y0表示坐标,r半径,angle角度)
function getCirlPoint(x0, y0, r, angle) {
let x1 = x0 + r * Math.cos((angle * Math.PI) / 180);
let y1 = y0 + r * Math.sin((angle * Math.PI) / 180);
return {
x: x1,
y: y1,
};
}
function draw() {
angle = angle + 3;
}
//指示器颜色
let colorConstData = ["#FD1A0C", "#0064F9", "#FEDB65", "#7E55F3"];
//环的颜色
let colorStep = [
[
{
offset: 0,
color: "#FD1A0C", // 0% 处的颜色
},
{
offset: 1,
color: "#FF824D", // 100% 处的颜色
},
],
[
{
offset: 0,
color: "#0060FF", // 0% 处的颜色
},
{
offset: 1,
color: "#00EFFE", // 100% 处的颜色
},
],
[
{
offset: 0,
color: "#FFA600", // 0% 处的颜色
},
{
offset: 1,
color: "#FEDB65", // 100% 处的颜色
},
],
[
{
offset: 0,
color: "#7E55F3", // 0% 处的颜色
},
{
offset: 1,
color: "#7E55F3", // 100% 处的颜色
},
],
];
export default {
name: "alarmTotal",
props: ["alarmLevelData", "allNum"],
data() {
return {
option: {},
};
},
watch: {
alarmLevelData: function (val, old) {
this.refreshOpt();
},
},
mounted() {
myChart = this.$echarts.init(document.getElementById("alarmTotal"));
this.resizeFn = this.debounce(
() => {
this.refreshOpt();
// 通过捕获系统的onresize事件触发需要执行的事件
myChart.resize();
},
1000,
this.option
);
window.addEventListener("resize", this.resizeFn);
},
methods: {
debounce(fn, delay, option) {
let timer = null; //借助闭包
return function () {
if (timer) {
clearTimeout(timer); //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
timer = setTimeout(fn, delay);
} else {
timer = setTimeout(fn, delay); // 进入该分支说明当前并没有在计时,那么就开始一个计时
}
};
},
refreshOpt() {
let series = this.alarmLevelData.map((item, index) => {
return {
value: item.count,
name: item.value,
itemStyle: {
normal: {
color: {
// 完成的圆环的颜色
colorStops: colorStep[index],
},
label: {
textStyle: {
color: colorConstData[index],
},
},
},
},
label: {
show: true,
position: "outside",
formatter: `{b}:{c}个`,
color: colorConstData[index],
},
};
});
let series2 = this.alarmLevelData.map((item, index) => {
return {
value: item.count,
name: item.value,
itemStyle: {
normal: {
color: {
// 完成的圆环的颜色
colorStops: colorStep[index],
},
opacity: 0.5,
},
},
};
});
this.option = {
legend: {
orient: "vertical",
show: true,
right: "10",
top: 30,
y: "center",
icon: "pin",
itemGap: 30,
textStyle: {
fontSize: 12,
lineHeight: 20,
color: "#fft", //就是这个!超神奇
},
},
tooltip: {
show: true,
valueFormatter: `{b}:{c}个`,
},
series: [
// 最外层圆
{
type: "pie",
radius: ["69%", "55%"],
center: ["50%", "50%"],
hoverAnimation: false,
data: series,
labelLine: {
smooth: true,
normal: {
length: 35,
lineStyle: {
width: 1,
},
},
},
},
// 内圆 + 中间文字
{
type: "pie",
radius: ["60%", "40%"],
center: ["50%", "50%"],
hoverAnimation: false,
z: 10,
label: {
position: "center",
formatter: () => {
return `告警总数\r\n{total|${this.allNum}} 个`;
},
rich: {
total: {
fontSize: 24,
color: "#00ffcc",
fontWeight: 600,
},
},
color: "#FFFFFF",
fontSize: 16,
lineHeight: 30,
fontWeight: 500,
},
data: series2,
labelLine: {
show: false,
},
},
// 紫色线1 + 点
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
return {
type: "arc",
shape: {
cx: api.getWidth() / 2,
cy: api.getHeight() / 2,
r:
(Math.min(api.getWidth(), api.getHeight()) / 2) *
outerRidus1, // 180,
startAngle: ((0 + angle) * Math.PI) / 180,
endAngle: ((90 + angle) * Math.PI) / 180,
},
style: {
stroke: "#8383FA",
fill: "transparent",
lineWidth: 1.5,
},
silent: true,
};
},
data: [0],
},
// 紫色线1点
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
let x0 = api.getWidth() / 2;
let y0 = api.getHeight() / 2;
let r =
(Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus1;
let point = getCirlPoint(x0, y0, r, 0 + angle);
return {
type: "circle",
shape: {
cx: point.x,
cy: point.y,
r: 4,
},
style: {
stroke: "#8450F9", //绿
fill: "#8450F9",
},
silent: true,
};
},
data: [0],
},
// 蓝色
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
return {
type: "arc",
shape: {
cx: api.getWidth() / 2,
cy: api.getHeight() / 2,
r:
(Math.min(api.getWidth(), api.getHeight()) / 2) *
outerRidus1, // 180,
startAngle: ((180 + angle) * Math.PI) / 180,
endAngle: ((270 + angle) * Math.PI) / 180,
},
style: {
stroke: "#4386FA",
fill: "transparent",
lineWidth: 1.5,
},
silent: true,
};
},
data: [0],
},
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
let x0 = api.getWidth() / 2;
let y0 = api.getHeight() / 2;
let r =
(Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus1; // 180
let point = getCirlPoint(x0, y0, r, 180 + angle);
return {
type: "circle",
shape: {
cx: point.x,
cy: point.y,
r: 4,
},
style: {
stroke: "#4386FA", //绿
fill: "#4386FA",
},
silent: true,
};
},
data: [0],
},
// 橘色
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
return {
type: "arc",
shape: {
cx: api.getWidth() / 2,
cy: api.getHeight() / 2,
r:
(Math.min(api.getWidth(), api.getHeight()) / 2) *
outerRidus2, // 200,
startAngle: ((250 + -angle) * Math.PI) / 180,
endAngle: ((10 + -angle) * Math.PI) / 180,
},
style: {
stroke: "#0CD3DB",
fill: "transparent",
lineWidth: 1.5,
},
silent: true,
};
},
data: [0],
},
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
let x0 = api.getWidth() / 2;
let y0 = api.getHeight() / 2;
let r =
(Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus2; // 200;
let point = getCirlPoint(x0, y0, r, 250 + -angle);
return {
type: "circle",
shape: {
cx: point.x,
cy: point.y,
r: 4,
},
style: {
stroke: "#0CD3DB", //绿
fill: "#0CD3DB",
},
silent: true,
};
},
data: [0],
},
// 粉色
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
return {
type: "arc",
shape: {
cx: api.getWidth() / 2,
cy: api.getHeight() / 2,
r:
(Math.min(api.getWidth(), api.getHeight()) / 2) *
outerRidus2, // 200,,
startAngle: ((70 + -angle) * Math.PI) / 180,
endAngle: ((200 + -angle) * Math.PI) / 180,
},
style: {
stroke: "#FF8E89",
fill: "transparent",
lineWidth: 1.5,
},
silent: true,
};
},
data: [0],
},
//粉色点
{
type: "custom",
coordinateSystem: "none",
renderItem: function (params, api) {
let x0 = api.getWidth() / 2;
let y0 = api.getHeight() / 2;
let r =
(Math.min(api.getWidth(), api.getHeight()) / 2) * outerRidus2; // 200,;
let point = getCirlPoint(x0, y0, r, 70 + -angle);
return {
type: "circle",
shape: {
cx: point.x,
cy: point.y,
r: 4,
},
style: {
stroke: "#FF8E89", //粉
fill: "#FF8E89",
},
silent: true,
};
},
data: [0],
},
],
};
if (timerId) {
clearInterval(timerId);
}
timerId = setInterval(() => {
//用setInterval做动画感觉有问题
draw();
myChart.setOption(this.option, true);
}, 1000);
},
},
};
</script>
<style lang="less" scoped>
.alarmTotal {
width: 100%;
height: 230px;
}
</style>

版权声明:本文为weixin_38233449原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。