由于项目是一个偏展示类的项目,(数据可视化),其中用到了echarts,并且用的图的种类比较多,所以单独将echarts部分拿出来 ,额外记录一下,下面来分类说明一下不同的图的配置,其实只要搞清楚里面的配置项的意思,基本能弄出来,写这个完全是方便以后自己快速找模板,节约时间。以下的图的种类,因为配置中含有柱状图和折线图的切换,所以我就拿柱状图来说明。
1.基础柱状图
this.chart1.title = res.data.data.title.text;
this.chart1.name = res.data.data.yAxis.name;
this.chart1.dataX = res.data.data.xAxis.data;
this.chart1.dataY = res.data.data.series.data;
let myChart = this.$echarts.init(document.getElementById("chart1"));
let option = {
title: {
text: this.chart1.title,
x: "center",
textStyle: {
color: "#000"
}
},
grid: {
left: 80
},
toolbox: {
right: 40,
show: true,
feature: {
magicType: { type: ["line", "bar"] },
saveAsImage: {}
}
},
tooltip: { show: true },
legend: {},
xAxis: {
type: "category",
data: this.chart1.dataX
},
yAxis: {
show: true,
position: "left",
offset: 0,
type: "value",
name: this.chart1.name,
nameLocation: "end",
minInterval: 1
},
series: [
{
type: "bar",
data: this.chart1.dataY
}
]
};
myChart.setOption(option);
window.onresize = function() {
myChart.resize();
};
2.双柱状图(不含多个Y轴)
this.chart2.name = res.data.data.yAxis.name;
for (let i = 0; i < res.data.data.serises.ActualEnergy.length; i++) {
this.chart2.dataY1.push(
Number(res.data.data.serises.ActualEnergy[i].data)
);
}
for (let j = 0; j < res.data.data.serises.Goalenergy.length; j++) {
this.chart2.dataY2.push(
Number(res.data.data.serises.Goalenergy[j].data)
);
}
for (let k = 0; k < res.data.data.serises.ActualEnergy.length; k++) {
this.chart2.dataX.push(res.data.data.serises.ActualEnergy[k].time);
}
let myChart = this.$echarts.init(document.getElementById("chart2"));
let option = {
title: {
text: this.chart2.title,
x: "center",
textStyle: {
color: "#000"
}
},
grid: {
left: 80
},
toolbox: {
right: 40,
show: true,
feature: {
magicType: { type: ["line", "bar"] },
saveAsImage: {}
}
},
legend: {
data: ["实际能耗", "目标能耗"],
bottom: 0
},
xAxis: {
type: "category",
data: this.chart2.dataX
},
yAxis: {
show: true,
position: "left",
offset: 0,
type: "value",
name: "kw/h",
nameLocation: "end",
minInterval: 1
},
series: [
{
type: "bar",
name: "实际能耗",
data: this.chart2.dataY1
},
{
type: "bar",
name: "目标能耗",
data: this.chart2.dataY2
}
]
};
myChart.setOption(option);
window.onresize = function() {
myChart.resize();
};
基础的柱状图和双柱状图其实是一样的,只不过是将双柱状的series配置项里面放两个数据,注意到里面的name的属性要和legend
配置项里面的属性名字要对应,不然是渲染不出来的,后面的图也是一样的需要配置好,必须两者要对应。
3.多柱状图(含有多个Y轴)
this.chart1.title = res.data.data.title.text;
this.chart1.subtext = res.data.data.title.subtext;
for (let i = 0; i < res.data.data.series.length; i++) {
this.chart1.legend.push(res.data.data.series[i].name);
}
for (let j = 0; j < res.data.data.series.length; j++) {
this.chart1.series.push({
name: res.data.data.series[j].name,
yAxisIndex: res.data.data.series[j].yAxisIndex,
data: res.data.data.series[j].data,
type: "bar"
});
}
for (let k = 0; k < res.data.data.yAxis.length; k++) {
this.chart1.dataY.push({
type: "value",
name: res.data.data.yAxis[k].name,
position: res.data.data.yAxis[k].position,
offset: res.data.data.yAxis[k].offset,
axisLabel: {
formatter: "{value} "
},
axisLine: {
lineStyle: {
color: "#675bba"
}
}
});
}
this.chart1.dataX = res.data.data.xAxis[0].data;
let myChart = this.$echarts.init(document.getElementById("chart1"));
let option = {
title: {
text: this.chart1.title,
x: "center",
textStyle: {
color: "#000"
},
subtext: this.chart1.subtext
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross"
}
},
grid: {
right: "20%"
},
toolbox: {
right: 40,
show: true,
feature: {
magicType: { type: ["line", "bar"] },
saveAsImage: {}
}
},
legend: {
type: "scroll",
data: this.chart1.legend,
bottom: 0
},
xAxis: [
{
type: "category",
axisTick: {
alignWithLabel: true
},
data: this.chart1.dataX
}
],
yAxis: this.chart1.dataY,
// yAxis: this.chart1.dataY,
series: this.chart1.series
};
myChart.setOption(option);
window.onresize = function() {
myChart.resize();
};
多个柱状图多个Y轴和多个柱状图单个Y轴的区别就是在设置series配置项里面的每一项的时候额外加一个position,name,offset
配置项,代表了每个Y轴的名字和位置,按照自己想要的位置去设置不同的position和offset值即可
4.折线面积图
for (let i = 0; i < res.data.data[0].series.length; i++) {
this.chart1.legend.push(res.data.data[0].series[i].name);
}
for (let j = 0; j < res.data.data[0].series.length; j++) {
this.chart1.series.push(res.data.data[0].series[j]);
}
this.chart1.title = res.data.data[0].title.text;
this.chart1.name = res.data.data[0].yAxis.text;
let myChart1 = this.$echarts.init(
document.getElementById("topchart")
);
let option1 = {
title: {
text: this.chart1.title,
x: "center",
textStyle: {
color: "#000"
}
},
legend: {
data: this.chart1.legend,
bottom: 0
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross"
}
},
toolbox: {
right: 100,
show: true,
feature: {
magicType: { type: ["line", "bar"] },
saveAsImage: {}
}
},
yAxis: {
show: true,
position: "left",
offset: 0,
type: "value",
name: this.chart1.name,
nameLocation: "end",
minInterval: 1
},
xAxis: {
type: "time"
},
series: this.chart1.series
};
myChart1.setOption(option1);
window.onresize = function() {
myChart1.resize();
};
这里给一个series配置项里面某一项的样子,如下,想要一个图上显示几个面积图就在series里面添加多少项,按照数据格式给定
series:[{
name:'a',
type:'line',
data:[
["2019/1/1 6:00:00", 191.23],
["2019/1/1 6:15:00", 197.17],
["2019/1/1 6:30:00", 182.2]
]
}]
一般来说面积图里面都含有一个基准线,基准线的数据格式如下,将该数据放入series配置项即可显示出基准线
[name:'b',
type:'line',
markLine:{
slient:true,
data:[yAxis:xxxx]
}
]
5.动态实时数据以及标注出最大值和最小值(折线图)
参考官网的实时数据案例,大概逻辑就是第一次请求固定条数的数据,渲染出来,然后开定时器,每隔一秒或者几秒,自己定,请
求一次数据,该数据为一个点,把这个点添加入折线图数据的最后一项,并且删掉上一次请求的数据的第一项,重复这一操作,从
而做到动态改变的效果,代码如下:
var app = {};
let option = null;
var data = [];
window.vm.$http
.get(
window.vm.$Api.globalUrl +
"/Api/DayCountReportAPI/GetDayCountValueNow",
{
params: {
CustomerId: localStorage.getItem("CustomerID"),
PlaceName: this.placeValue
}
}
)
.then(res => {
res.data.data[0].value.map(v => {
this.chart5.series.push(v);
});
res.data.data[0].time.map(v => {
this.chart5.dataX.push(v);
});
option = {
title: {
text: "每隔十五分钟的实时数据",
x: "center"
},
tooltip: {
trigger: "axis",
axisPointer: {
animation: false
}
},
xAxis: {
type: "category",
splitLine: {
show: false
},
data: this.chart5.dataX
},
yAxis: {
type: "value",
name: "kw/h",
boundaryGap: [0, "100%"],
splitLine: {
show: false
}
},
series: [
{
type: "line",
markPoint: {
data: [
{ type: "max", name: "最大值" },
{ type: "min", name: "最小值" }
]
},
data: this.chart5.series
}
]
};
let myChart = this.$echarts.init(document.getElementById("dayChart"));
myChart.setOption(option);
window.onresize = function() {
myChart.resize();
};
this.lastTime = option.xAxis.data[option.xAxis.data.length - 1];
});
这一部分为请求初始的几条数据,并且标注出最大值和最小值
function randomData() {
window.vm.$http
.get(
window.vm.$Api.globalUrl +
"/Api/DayCountReportAPI/GetDayCountValueNowOne",
{
params: {
CustomerId: localStorage.getItem("CustomerID"),
PlaceName: vm.placeValue,
lastTime: window.vm.lastTime
}
}
)
.then(res => {
console.log(res, "ppppp");
//记录时间
window.vm.lastTime = res.data.data[0].time.join("");
//去掉第一个点,并在最后面加上最新的点
option.xAxis.data.shift();
option.xAxis.data.push(res.data.data[0].time.join(""));
// console.log(option.xAxis.data, "6666");
option.series[0].data.shift();
option.series[0].data.push(Number(res.data.data[0].value.join("")));
// console.log(option.series[0].data, "9999");
let myChart = window.vm.$echarts.init(
document.getElementById("dayChart")
);
myChart.setOption(option);
});
}
setInterval(function() {
randomData();
}, 3000);
这一部分为开启定时器,每隔三秒请求一条数据放入上一次请求的数据最后面,并且删除上一次请求的第一条数据
6.树图
代码如下:
myChart.showLoading();
this.$http
.get(this.$Api.globalUrl + "/Api/MeterBranchAPI/GetMeterBranchNew", {
params: {
CustomerID: localStorage.getItem("CustomerID")
}
})
.then(res => {
myChart.hideLoading();
console.log(res, 333);
var data = res.data.data;
this.$echarts.util.each(data.children, function(datum, index) {
index % 2 === 0 && (datum.collapsed = true);
});
let options = {
tooltip: {
trigger: "item",
triggerOn: "mousemove"
},
series: [
{
type: "tree",
data: data,
top: "1%",
left: "7%",
bottom: "1%",
right: "20%",
symbolSize: 7,
label: {
normal: {
position: "left",
verticalAlign: "middle",
align: "right",
fontSize: 9
}
},
leaves: {
label: {
normal: {
position: "right",
verticalAlign: "middle",
align: "left"
}
}
},
expandAndCollapse: true,
animationDuration: 550,
animationDurationUpdate: 750
}
]
};
myChart.setOption(options);
window.onresize = function() {
myChart.resize();
};
数据格式为:name:'a',children:[
{name:'',children:[{name:'',value:''},{name:'',value:''}]},
{name:'',children:[]},
{name:'',children:[]}]
7.旭日图
代码如下:
var data = res.data.data;
var option = {
series: {
type: "sunburst",
highlightPolicy: "ancestor",
data: data,
radius: [0, "95%"],
sort: null,
avoidLabelOverlap: true,
levels: [
{},
{
r0: "5%",
r: "35%",
itemStyle: {
borderWidth: 2
},
label: {
align: "right",
fontStyle: "宋体",
normal: {
position: "inner"
},
align: "center"
}
},
{
r0: "35%",
r: "60%",
label: {
align: "right",
fontStyle: "宋体",
normal: {
position: "inner"
},
align: "center"
}
},
{
r0: "60%",
r: "65%",
label: {
align: "right",
fontStyle: "宋体",
normal: {
position: "inner"
},
align: "center"
},
itemStyle: {
borderWidth: 3
}
}
]
}
};
myChart.setOption(option);
所需的数据格式如下:
[{name:'',itemStyle:{},children:[
{name:'',itemStyle:{},value:'',children:[{name:'',value:'',itemStyle:{}}]}]
}]
8.桑基图
代码如下:
let option = {
title: {
text: res.data.data.title.text,
x: "center"
},
tooltip: res.data.data.tooltip,
series: [
{
type: "sankey",
data: res.data.data.series[0].data,
links: res.data.data.series[0].links,
focusNodeAdjacency: true,
levels: [
{
depth: 0,
itemStyle: {
color: "#fbb4ae"
},
lineStyle: {
color: "source",
opacity: 0.6
}
},
{
depth: 1,
itemStyle: {
color: "#b3cde3"
},
lineStyle: {
color: "source",
opacity: 0.6
}
},
{
depth: 2,
itemStyle: {
color: "#ccebc5"
},
lineStyle: {
color: "source",
opacity: 0.6
}
},
{
depth: 3,
itemStyle: {
color: "#decbe4"
},
lineStyle: {
color: "source",
opacity: 0.6
}
}
],
lineStyle: {
normal: {
curveness: 0.5
}
}
}
]
};
myChart.setOption(option);
window.onresize = function() {
myChart.resize();
};
数据格式为:(主要针对series配置项里面的数据)
[{
type: "sankey",
layout: "none",
focusNodeAdjacency: "allEdges",
data:[{name:'a'},{name:'b'},{name:'c'}],
links:[{source:'a',target:'',value:''},{source:'b',target:'',value:''},{source:'c',target:'',value:''}]
}]
这里必须注意data里面的name和links里面的source想对应,然后target是连接的下一个目标
9.堆叠柱状图,并且有计算所有值的累加值
option = {
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎', '百度', '谷歌', '必应', '其他']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '邮件营销',
type: 'bar',
stack: '广告',
data: [120, 132, 101, 134, 90, 230, 210],
label: {
show: true
},
},
{
name: '联盟广告',
type: 'bar',
stack: '广告',
data: [220, 182, 191, 234, 290, 330, 310],
label: {
show: true
},
},
{
name: '视频广告',
type: 'bar',
stack: '广告',
data: [150, 232, 201, 154, 190, 330, 410],
label: {
show: true
},
},
{
name: '总数', // 总数显示,生成一个总数的柱状图,将颜色设为透明,
type: 'bar', // label将位置设备内部底部,造成一个总数显示在
stack: '广告', // 柱状图上方的假象
label: {
normal: {
show: true,
position: 'insideBottom',
formatter: '{c}', // 显示的总数
textStyle: { color: '#000' }
}
},
itemStyle: {
normal: {
color: 'rgba(128, 128, 128, 0)' // 柱状图颜色设为透明
}
},
data: [20,20,20,20,20,20,20]
}
]
};
10.如果还有别的后期再补充,有时候会用到点击事件去获取到点击的图的信息,执行下一步操作,正常注册即可,例如
machart.on('click',function(params){}),其中params就是你点击的那部分的图的详细信息,还有就是可能会出现this指向问题,
提前在方法外部改变一下this的指向,即that = this,这样方便在点击事件中给vue里面的data数据赋值或者获取。
这里只是粗略的写了一下,一些额外的什么切换之类的,还有下载图片或者导出图表操作,局部区域的放大缩小等等等,去看看一些
配置参数即可,基本在toolbox配置项里面都可以解决,自定义自己想要的操作。
echarts官网地址:https://www.echartsjs.com/examples/zh/index.html