|
@@ -7,7 +7,8 @@ export default {
|
|
name: "ChartPie",
|
|
name: "ChartPie",
|
|
data() {
|
|
data() {
|
|
return {
|
|
return {
|
|
- myChart: null
|
|
|
|
|
|
+ myChart: null,
|
|
|
|
+ timer1: null
|
|
}
|
|
}
|
|
},
|
|
},
|
|
props: {
|
|
props: {
|
|
@@ -24,7 +25,8 @@ export default {
|
|
data: {
|
|
data: {
|
|
handler(newVal) {
|
|
handler(newVal) {
|
|
if(newVal) {
|
|
if(newVal) {
|
|
- this.myChart.clear();
|
|
|
|
|
|
+ console.log('watch')
|
|
|
|
+ this.myChart.clear()
|
|
this.init();
|
|
this.init();
|
|
}
|
|
}
|
|
},
|
|
},
|
|
@@ -33,14 +35,54 @@ export default {
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
init() {
|
|
init() {
|
|
|
|
+ var that = this;
|
|
let arr = [];
|
|
let arr = [];
|
|
let num = 0;
|
|
let num = 0;
|
|
- this.data.forEach(item => {
|
|
|
|
|
|
+ let data = this.data;
|
|
|
|
+ data.forEach(item => {
|
|
num+= Number(item.value)
|
|
num+= Number(item.value)
|
|
})
|
|
})
|
|
- this.data.forEach(item => {
|
|
|
|
|
|
+ data.forEach(item => {
|
|
arr.push({ name: item.name, percent: (parseFloat(item.value) / num * 100).toFixed(2) + '%', number: item.value})
|
|
arr.push({ name: item.name, percent: (parseFloat(item.value) / num * 100).toFixed(2) + '%', number: item.value})
|
|
})
|
|
})
|
|
|
|
+ let minAngle = 10;// 最小扇形区域为30
|
|
|
|
+ for ( let i = 0; i < data.length; i++ ) { //某项数据为0时,最小扇形区域为0
|
|
|
|
+ if ( data[ i ].value < 1 ) {
|
|
|
|
+ minAngle = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ const pieValue1 = data.map( v => {
|
|
|
|
+ return v.value;
|
|
|
|
+ })
|
|
|
|
+ const max = Math.max(...pieValue1);
|
|
|
|
+ const len = max.toString().length;
|
|
|
|
+ let diff = len - 3;
|
|
|
|
+ let pieValue = [];
|
|
|
|
+ if(diff > 0) {
|
|
|
|
+ pieValue = data.map( v => {
|
|
|
|
+ return v.value / (diff * 10);
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ pieValue = data.map( v => {
|
|
|
|
+ return v.value;
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ const sum = pieValue.reduce( ( prev, cur ) => {//数据值的总和
|
|
|
|
+ return prev + cur;
|
|
|
|
+ }, 0 );
|
|
|
|
+ const sum2 = pieValue.reduce( ( prev, cur ) => {
|
|
|
|
+ if ( cur < sum / 36 && cur > 0 ) {//某个值大于0小于总和的1/12即30时,按30计算和
|
|
|
|
+ return prev + sum / 36;
|
|
|
|
+ }
|
|
|
|
+ return prev + cur;
|
|
|
|
+ }, 0 );
|
|
|
|
+ let initPieValue = pieValue[ 0 ];// 初始值
|
|
|
|
+ if ( initPieValue < sum / 36 && initPieValue > 0 ) {
|
|
|
|
+ initPieValue = sum / 36;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
let options = {
|
|
let options = {
|
|
grid: {
|
|
grid: {
|
|
x: 100
|
|
x: 100
|
|
@@ -48,40 +90,50 @@ export default {
|
|
color: ['#3AA0FF', '#4DCB73', '#5470C6', '#9A60B4'],
|
|
color: ['#3AA0FF', '#4DCB73', '#5470C6', '#9A60B4'],
|
|
tooltip: {
|
|
tooltip: {
|
|
trigger: 'item',
|
|
trigger: 'item',
|
|
- formatter: function ({name, value, percent}) {
|
|
|
|
- return name + ':' + value + '条 ' + percent + '%'
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- legend: {
|
|
|
|
- top: '30%',
|
|
|
|
- left: '55%',
|
|
|
|
- orient: 'vertical',
|
|
|
|
- icon: "circle",
|
|
|
|
- selectedMode: false, // 取消右侧项选中
|
|
|
|
- itemGap: 20, // 各项间隔
|
|
|
|
- textStyle: {
|
|
|
|
- fontSize: 13,
|
|
|
|
- color: '#666'
|
|
|
|
|
|
+ position: function() {
|
|
|
|
+ return [ '60%', '30%'];
|
|
},
|
|
},
|
|
- formatter: function (name) {
|
|
|
|
- var legendIndex = 0;
|
|
|
|
- // var clientLabels = [
|
|
|
|
- // { name: '环境报警', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
- // { name: '断电报警', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
- // { name: '人员违规', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
- // { name: '环境监测', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
- // { name: '污水排放', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
- // { name: '设备异常', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
- // ]
|
|
|
|
- var clientLabels = arr
|
|
|
|
- clientLabels.forEach(function (value, i) {
|
|
|
|
- if (value.name == name) {
|
|
|
|
- legendIndex = i;
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- return name + " (" + clientLabels[legendIndex].percent + ', ' + clientLabels[legendIndex].number + '条' + ") ";
|
|
|
|
|
|
+ formatter: function ({name, value, percent}) {
|
|
|
|
+ var str = '';
|
|
|
|
+ str = '<div style="padding: 20px; text-align: center">'+
|
|
|
|
+ '<p style="font-size: 18px; margin: 0; line-height: 20px; color: white">' + name + '</p>' +
|
|
|
|
+ '<p style="font-size: 16px; margin: 0; color: white">' + '条数:' + value + '条' +'</p>' +
|
|
|
|
+ '<p style="font-size: 16px; margin: 0; color: white">' + '占比:' + percent + '%' +'</p>'
|
|
|
|
+ + '</div>'
|
|
|
|
+ return str
|
|
|
|
+ // return name + ':' + value + '条 ' + percent + '%'
|
|
}
|
|
}
|
|
},
|
|
},
|
|
|
|
+ // legend: {
|
|
|
|
+ // top: '30%',
|
|
|
|
+ // left: '55%',
|
|
|
|
+ // orient: 'vertical',
|
|
|
|
+ // icon: "circle",
|
|
|
|
+ // selectedMode: false, // 取消右侧项选中
|
|
|
|
+ // itemGap: 20, // 各项间隔
|
|
|
|
+ // textStyle: {
|
|
|
|
+ // fontSize: 13,
|
|
|
|
+ // color: '#666'
|
|
|
|
+ // },
|
|
|
|
+ // formatter: function (name) {
|
|
|
|
+ // var legendIndex = 0;
|
|
|
|
+ // // var clientLabels = [
|
|
|
|
+ // // { name: '环境报警', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
+ // // { name: '断电报警', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
+ // // { name: '人员违规', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
+ // // { name: '环境监测', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
+ // // { name: '污水排放', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
+ // // { name: '设备异常', percent: parseFloat(0.16)*100 + '%', number: 2 },
|
|
|
|
+ // // ]
|
|
|
|
+ // var clientLabels = arr
|
|
|
|
+ // clientLabels.forEach(function (value, i) {
|
|
|
|
+ // if (value.name == name) {
|
|
|
|
+ // legendIndex = i;
|
|
|
|
+ // }
|
|
|
|
+ // });
|
|
|
|
+ // return name + " (" + clientLabels[legendIndex].percent + ', ' + clientLabels[legendIndex].number + '条' + ") ";
|
|
|
|
+ // }
|
|
|
|
+ // },
|
|
graphic: [
|
|
graphic: [
|
|
{
|
|
{
|
|
type: 'text',
|
|
type: 'text',
|
|
@@ -107,22 +159,35 @@ export default {
|
|
],
|
|
],
|
|
series: [
|
|
series: [
|
|
{
|
|
{
|
|
- name: 'Access From',
|
|
|
|
|
|
+ name: '报警类型',
|
|
type: 'pie',
|
|
type: 'pie',
|
|
radius: ['60%', '80%'], // 半径
|
|
radius: ['60%', '80%'], // 半径
|
|
center: ['30%', '55%'],
|
|
center: ['30%', '55%'],
|
|
avoidLabelOverlap: false,
|
|
avoidLabelOverlap: false,
|
|
|
|
+ clockWise: false,
|
|
|
|
+ clickable: false,
|
|
|
|
+ startAngle: 360,
|
|
|
|
+ minAngle: minAngle,
|
|
label: {
|
|
label: {
|
|
show: false,
|
|
show: false,
|
|
// position: 'center'
|
|
// position: 'center'
|
|
},
|
|
},
|
|
- emphasis: {
|
|
|
|
- label: {
|
|
|
|
- show: false,
|
|
|
|
- fontSize: '40',
|
|
|
|
- fontWeight: 'bold'
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
|
|
+ // emphasis: {
|
|
|
|
+ // label: {
|
|
|
|
+ // show: false,
|
|
|
|
+ // fontSize: '40',
|
|
|
|
+ // fontWeight: 'bold'
|
|
|
|
+ // }
|
|
|
|
+ // },
|
|
|
|
+ // emphasis: {
|
|
|
|
+ // label: {
|
|
|
|
+ // show: true,
|
|
|
|
+ // formatter: "{a} \n{b}: {c} ({d}%)",
|
|
|
|
+ // color: '#fff',
|
|
|
|
+ // fontWeight: 'bold',
|
|
|
|
+ // fontSize: 18
|
|
|
|
+ // }
|
|
|
|
+ // },
|
|
labelLine: {
|
|
labelLine: {
|
|
show: false
|
|
show: false
|
|
},
|
|
},
|
|
@@ -133,24 +198,142 @@ export default {
|
|
return colorList[colors.dataIndex]
|
|
return colorList[colors.dataIndex]
|
|
},
|
|
},
|
|
borderWidth: 2, // 设置各项空隙
|
|
borderWidth: 2, // 设置各项空隙
|
|
- borderColor: '#fff'
|
|
|
|
|
|
+ borderColor: '#fff',
|
|
|
|
+ borderRadius: 5,
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- data: this.data
|
|
|
|
|
|
+ data: data
|
|
}
|
|
}
|
|
- ]
|
|
|
|
|
|
+ ],
|
|
|
|
+ animationDuration: 0,
|
|
|
|
+ animationDurationUpdate: 1000,
|
|
|
|
+ animationEasing: 'linear',
|
|
|
|
+ animationEasingUpdate: 'linear'
|
|
};
|
|
};
|
|
|
|
|
|
this.myChart.setOption(options)
|
|
this.myChart.setOption(options)
|
|
|
|
+
|
|
|
|
+ this.myChart.dispatchAction( { type: 'highlight', seriesIndex: 0, dataIndex: 0 } );
|
|
|
|
+ this.myChart.dispatchAction( { type: 'showTip', seriesIndex: 0, dataIndex: 0 } )
|
|
|
|
+ let preDataIndex = 0;
|
|
|
|
+ // 开始循环
|
|
|
|
+ this.timer1 = setInterval(() => {
|
|
|
|
+ if(preDataIndex > pieValue.length - 1 ) {
|
|
|
|
+ preDataIndex = 0;
|
|
|
|
+ }
|
|
|
|
+ const sum1 = pieValue.reduce( ( prev, cur, index ) => {
|
|
|
|
+ if ( index < preDataIndex ) {
|
|
|
|
+ if ( cur < sum / 36 && cur > 0 ) {
|
|
|
|
+ return prev + sum / 36; // 饼图的扇形最小角度设置为30,占圆的1/12
|
|
|
|
+ }
|
|
|
|
+ return prev + cur;
|
|
|
|
+ }
|
|
|
|
+ return prev;
|
|
|
|
+ }, 0 );
|
|
|
|
+ let curPieValue = pieValue[ preDataIndex ];
|
|
|
|
+ if ( curPieValue < sum / 36 && curPieValue > 0 ) {
|
|
|
|
+ curPieValue = sum / 36;
|
|
|
|
+ }
|
|
|
|
+ this.myChart.dispatchAction({ type: 'downplay', seriesIndex: 0 });
|
|
|
|
+ this.myChart.dispatchAction({ type: 'hideTip' })
|
|
|
|
+ options.series[ 0 ].startAngle = 360 - ( sum1 / sum2 * 360 + curPieValue / sum2 * 360 / 2 );// 开始渲染图形的角度
|
|
|
|
+ this.myChart.setOption( options );
|
|
|
|
+ window.setTimeout( () => {
|
|
|
|
+ this.myChart.dispatchAction( {
|
|
|
|
+ type: 'highlight',
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ dataIndex: preDataIndex
|
|
|
|
+ } );
|
|
|
|
+ this.myChart.dispatchAction({
|
|
|
|
+ type: 'showTip',
|
|
|
|
+ // 可选,系列 index,可以是一个数组指定多个系列
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ // 可选,数据的 index
|
|
|
|
+ dataIndex: preDataIndex,
|
|
|
|
+ })
|
|
|
|
+ preDataIndex++;
|
|
|
|
+
|
|
|
|
+ }, 1500);
|
|
|
|
+ }, 8000)
|
|
|
|
+ this.myChart.on('mouseover', (v) => {
|
|
|
|
+ this.myChart.dispatchAction({
|
|
|
|
+ type: 'downplay',
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ // dataIndex: preDataIndex === 0 ? 3 : preDataIndex - 1
|
|
|
|
+ });
|
|
|
|
+ preDataIndex = v.dataIndex;
|
|
|
|
+ this.myChart.dispatchAction( {
|
|
|
|
+ type: 'highlight',
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ dataIndex: preDataIndex
|
|
|
|
+ });
|
|
|
|
+ clearInterval(that.timer1);
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ this.myChart.on('mouseout', () => {
|
|
|
|
+ this.timer1 = setInterval(() => {
|
|
|
|
+ if(preDataIndex > pieValue.length - 1 ) {
|
|
|
|
+ preDataIndex = 0;
|
|
|
|
+ }
|
|
|
|
+ const sum1 = pieValue.reduce( ( prev, cur, index ) => {
|
|
|
|
+ if ( index < preDataIndex ) {
|
|
|
|
+ if ( cur < sum / 12 && cur > 0 ) {
|
|
|
|
+ return prev + sum / 12; // 饼图的扇形最小角度设置为30,占圆的1/12
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return prev + cur;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return prev;
|
|
|
|
+
|
|
|
|
+ }, 0 );
|
|
|
|
+
|
|
|
|
+ let curPieValue = pieValue[ preDataIndex ];
|
|
|
|
+
|
|
|
|
+ if ( curPieValue < sum / 12 && curPieValue > 0 ) {
|
|
|
|
+ curPieValue = sum / 12;
|
|
|
|
+ }
|
|
|
|
+ this.myChart.dispatchAction({
|
|
|
|
+ type: 'downplay',
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ // dataIndex: preDataIndex === 0 ? 3 : preDataIndex - 1
|
|
|
|
+ });
|
|
|
|
+ options.series[ 0 ].startAngle = 360 - ( sum1 / sum2 * 360 + curPieValue / sum2 * 360 / 2 );// 开始渲染图形的角度
|
|
|
|
+ //
|
|
|
|
+ this.myChart.setOption( options );
|
|
|
|
+
|
|
|
|
+ window.setTimeout( () => {
|
|
|
|
+ this.myChart.dispatchAction( {
|
|
|
|
+ type: 'highlight',
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ dataIndex: preDataIndex
|
|
|
|
+ } );
|
|
|
|
+ this.myChart.dispatchAction({
|
|
|
|
+ type: 'showTip',
|
|
|
|
+ // 可选,系列 index,可以是一个数组指定多个系列
|
|
|
|
+ seriesIndex: 0,
|
|
|
|
+ // 可选,数据的 index
|
|
|
|
+ dataIndex: preDataIndex,
|
|
|
|
+ })
|
|
|
|
+ preDataIndex++;
|
|
|
|
+
|
|
|
|
+ }, 1500);
|
|
|
|
+ }, 8000)
|
|
|
|
+ })
|
|
}
|
|
}
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
this.myChart = this.$echarts.init(document.getElementById('chartPie' + this.id));
|
|
this.myChart = this.$echarts.init(document.getElementById('chartPie' + this.id));
|
|
- this.init()
|
|
|
|
let that = this;
|
|
let that = this;
|
|
window.addEventListener("resize", function () {
|
|
window.addEventListener("resize", function () {
|
|
that.myChart.resize()
|
|
that.myChart.resize()
|
|
})
|
|
})
|
|
|
|
+ },
|
|
|
|
+ beforeDestroy() {
|
|
|
|
+ clearInterval(this.timer1);
|
|
|
|
+ this.timer1 = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</script>
|