<template>
|
<div class="e-chart-root" @dblclick="fullScreen" :class="{'full-screen': fullScreenState}">
|
<div class="e-chart-container">
|
<div class="e-chart" :id="id" :ref="id"></div>
|
<div class="e-chart-tools" v-if="showTools">
|
<i class="iconfont el-icon-yanjingkejian" :class="eleClass" @click="changeEyeState"></i>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
// 引入 ECharts 主模块
|
import ECharts from "echarts/lib/echarts";
|
//引入折线图
|
import "echarts/lib/chart/bar";
|
import "echarts/lib/chart/custom";
|
//引入提示框
|
import "echarts/lib/component/tooltip";
|
//引入标题
|
import "echarts/lib/component/title";
|
//引入图例标志
|
import "echarts/lib/component/legend";
|
//区域缩放
|
import "echarts/lib/component/dataZoom";
|
|
//markeline
|
import "echarts/lib/component/markLine"
|
|
|
// 引入自定义主题
|
import "./theme/transparent"
|
|
export default {
|
name: "BarChartThreeD",
|
chartOption: {},
|
props: {
|
id: {
|
type: String,
|
required: true,
|
},
|
unit: {
|
type: String,
|
default: '',
|
},
|
showTools: {
|
type: Boolean,
|
default: false,
|
},
|
showLabel: {
|
type: Boolean,
|
default: true,
|
},
|
maxColor: {
|
type: String,
|
default: 'green',
|
},
|
minColor: {
|
type: String,
|
default: 'red',
|
},
|
rightMenu: {
|
type: Boolean,
|
default: false,
|
}
|
},
|
data() {
|
return {
|
fullScreenState: false,
|
eye: true,
|
}
|
},
|
methods: {
|
getOption(opt) {
|
let unit = this.unit;
|
let alarmVol = this.getAlarmVal(opt);
|
// 整体配置项
|
let option = {
|
animation: false,
|
color: this.getColor(opt),
|
title: this.getTitle(opt),
|
tooltip: {
|
show: true,
|
},
|
grid: {
|
left: '1%',
|
right: '1%',
|
bottom: '2%',
|
containLabel: true
|
},
|
xAxis: [
|
{
|
type: 'category',
|
}
|
],
|
yAxis: [
|
{
|
type: 'value',
|
splitLine: {
|
show: true,
|
},
|
}
|
],
|
series: this.getSeries(opt),
|
};
|
return option;
|
},
|
setOption(opt) {
|
this.$options.chartOption = opt;
|
let option = this.getOption(opt);
|
// 清理画布
|
this.$G.chartManage.get(this.id).clear();
|
// 设置配置项
|
this.$G.chartManage.get(this.id).setOption(option);
|
},
|
getAlarmVal(opt) {
|
let result = {
|
low: false,
|
high: false
|
};
|
if (opt && opt.series) {
|
let markLine = opt.series[0].markLine;
|
if (opt.series && markLine && markLine.data) {
|
result.low = markLine.data[0].yAxis;
|
result.high = markLine.data[1].yAxis;
|
}
|
}
|
|
return result;
|
},
|
getColor(opt) { // 配置自定义颜色
|
// 未配置自定义颜色
|
if (!opt || !opt.color) {
|
return []
|
}
|
|
// 返回颜色
|
return opt.color;
|
},
|
getTitle(opt) { // 配置标题
|
// 未配置标题
|
if (!opt || !opt.title) {
|
return {
|
show: false,
|
};
|
}
|
|
// 返回标题
|
return opt.title;
|
},
|
getSeries(opt) { // 设置series
|
// 未配置series
|
if (!opt || !opt.series) {
|
return [];
|
}
|
let showLabel = this.showChartLabel;
|
const size = 12;
|
const CubeLeft = ECharts.graphic.extendShape({
|
shape: {
|
x: 0,
|
y: 0
|
},
|
buildPath: function (ctx, shape) {
|
const xAxisPoint = shape.xAxisPoint
|
const c0 = [shape.x, shape.y]
|
const c1 = [shape.x - size, shape.y - size]
|
const c2 = [xAxisPoint[0] - size, xAxisPoint[1] - size]
|
const c3 = [xAxisPoint[0], xAxisPoint[1]]
|
ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath()
|
}
|
});
|
const CubeRight = ECharts.graphic.extendShape({
|
shape: {
|
x: 0,
|
y: 0
|
},
|
buildPath: function (ctx, shape) {
|
const xAxisPoint = shape.xAxisPoint
|
const c1 = [shape.x, shape.y]
|
const c2 = [xAxisPoint[0], xAxisPoint[1]]
|
const c3 = [xAxisPoint[0] + size * 2, xAxisPoint[1] - size]
|
const c4 = [shape.x + size * 2, shape.y - size]
|
ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
|
}
|
});
|
const CubeTop = ECharts.graphic.extendShape({
|
shape: {
|
x: 0,
|
y: 0
|
},
|
buildPath: function (ctx, shape) {
|
const c1 = [shape.x, shape.y]
|
const c2 = [shape.x + size * 2, shape.y - size]
|
const c3 = [shape.x + size, shape.y - size * 2]
|
const c4 = [shape.x - size, shape.y - size]
|
ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
|
}
|
});
|
ECharts.graphic.registerShape('CubeLeft', CubeLeft);
|
ECharts.graphic.registerShape('CubeRight', CubeRight);
|
ECharts.graphic.registerShape('CubeTop', CubeTop);
|
// 设置颜色
|
let minColor = this.minColor;
|
let maxColor = this.maxColor;
|
// 设置配置项
|
let series = opt.series.map(item => {
|
let max = this.getMax(item.data);
|
let min = this.getMin(item.data);
|
if (item.markLine && item.markLine.data) {
|
let data = item.markLine.data;
|
min = data[0].yAxis;
|
max = data[1].yAxis;
|
}
|
item.type = "custom";
|
item.renderItem = (params, api) => {
|
let startColor = "#3B80E2";
|
let endColor = "#49BEE5";
|
let value = item.data[params.dataIndex][1];
|
if (value >= max) {
|
startColor = "#F83030";
|
endColor = "#f35959";
|
} else if (value <= min) {
|
startColor = "#f89c1e";
|
endColor = "#f6c163";
|
}
|
|
const location = api.coord([api.value(0), api.value(1)])
|
return {
|
type: 'group',
|
children: [{
|
type: 'CubeLeft',
|
shape: {
|
api,
|
xValue: api.value(0),
|
yValue: api.value(1),
|
x: location[0],
|
y: location[1],
|
xAxisPoint: api.coord([api.value(0), 0])
|
},
|
style: {
|
fill: new ECharts.graphic.LinearGradient(0, 0, 0, 1, [{
|
offset: 0,
|
color: startColor
|
},
|
{
|
offset: 1,
|
color: endColor
|
}
|
])
|
}
|
}, {
|
type: 'CubeRight',
|
shape: {
|
api,
|
xValue: api.value(0),
|
yValue: api.value(1),
|
x: location[0],
|
y: location[1],
|
xAxisPoint: api.coord([api.value(0), 0])
|
},
|
style: {
|
fill: new ECharts.graphic.LinearGradient(0, 0, 0, 1, [{
|
offset: 0,
|
color: startColor
|
},
|
{
|
offset: 1,
|
color: endColor
|
}
|
])
|
}
|
}, {
|
type: 'CubeTop',
|
shape: {
|
api,
|
xValue: api.value(0),
|
yValue: api.value(1),
|
x: location[0],
|
y: location[1],
|
xAxisPoint: api.coord([api.value(0), 0])
|
},
|
style: {
|
fill: new ECharts.graphic.LinearGradient(0, 0, 0, 1, [{
|
offset: 0,
|
color: startColor
|
},
|
{
|
offset: 1,
|
color: endColor
|
}
|
])
|
}
|
}]
|
}
|
};
|
return item;
|
});
|
let data = series[0].data.map(item=>{
|
return item;
|
});
|
|
series.push({
|
type: 'bar',
|
label: {
|
normal: {
|
show: showLabel,
|
position: 'top',
|
color: '#fff',
|
offset: [4, -size*3/2]
|
},
|
},
|
itemStyle: {
|
color: 'transparent'
|
},
|
data: data
|
});
|
// 返回
|
return series;
|
},
|
getMax(list) {
|
let arr = list.map(item => {
|
return item[1];
|
});
|
return Math.max.apply(null, arr);
|
},
|
getMin(list) {
|
let arr = list.map(item => {
|
return item[1];
|
});
|
return Math.min.apply(null, arr);
|
},
|
fullScreen() {
|
this.fullScreenState = this.fullScreenState ? false : true;
|
this.$nextTick(() => {
|
// 重置大小
|
this.$G.chartManage.get(this.id).resize();
|
});
|
},
|
resize() {
|
// 重置大小
|
this.$G.chartManage.get(this.id).resize();
|
},
|
changeEyeState() {
|
this.eye = this.eye ? false : true;
|
let option = this.$options.chartOption;
|
this.setOption(option);
|
}
|
},
|
computed: {
|
eleClass() {
|
return this.eye ? "el-icon-yanjingkejian" : "el-icon-yanjing-bukejian";
|
},
|
showChartLabel() {
|
return this.showLabel && this.eye ? true : false;
|
}
|
},
|
mounted() {
|
let self = this;
|
this.$refs[this.id].oncontextmenu = function () {
|
return false;
|
}
|
// 基于准备好的dom,初始化echarts实例
|
let chart = ECharts.init(this.$refs[this.id], 'transparent');
|
// 将图表添加到图表管理
|
this.$G.chartManage.set(this.id, chart);
|
// 设置配置项
|
this.setOption();
|
|
// 点击事件
|
chart.getZr().on('mousedown', function (params) {
|
if (params.which == 3) {
|
let pointInPixel = [params.offsetX, params.offsetY];
|
if (chart.containPixel('grid', pointInPixel)) {
|
/*单击图标X轴数据,打开详情*/
|
let xIndex = chart.convertFromPixel({seriesIndex: 0}, pointInPixel)[0];
|
self.$emit('right-click', {
|
x: params.event.clientX + 16,
|
y: params.event.clientY + 16,
|
xIndex: xIndex
|
});
|
}
|
}
|
|
});
|
|
// 根据功能屏蔽右键菜单
|
if (this.rightMenu) {
|
document.getElementById(this.id).oncontextmenu = function () {
|
return false;
|
};
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.e-chart-root,
|
.e-chart-container,
|
.e-chart {
|
height: 100%;
|
box-sizing: border-box;
|
}
|
|
.e-chart-root.full-screen .e-chart-container {
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background-size: 100% 100%;
|
z-index: 9999;
|
}
|
|
.e-chart-tools {
|
position: absolute;
|
top: 16px;
|
right: 16px;
|
z-index: 9;
|
}
|
|
.e-chart-tools .iconfont {
|
margin-left: 8px;
|
font-size: 24px;
|
cursor: pointer;
|
color: #00fefe;
|
}
|
|
.e-chart-tools .iconfont:hover {
|
color: #04b1b1;
|
}
|
|
.e-chart-tools .iconfont:active {
|
color: #FF0000;
|
}
|
</style>
|