vuejs+echarts实现x轴为时间轴且数据区域可缩放
1、效果图
2、具体功能描述
①选择的时间为时间轴的开始和结束时间;
②鼠标可以左右拖动x轴时间轴;
③鼠标放入图表中可以缩放数据,x轴会相应的更改当前坐标轴间隔值,最小间隔值为1分钟,最大间隔值为1年,且在缩放时可以获取到数据窗口范围的起始数值;
④点击y轴名称会对相应数据显示隐藏。
3、实现
①结构代码:
<div id="echart" style="width:100%;height: 240px;" ></div>
②配置图表
data () {
return {
option:{
grid: {
show: true,
top: 15,
left: 100,
right: 30,
bottom:30,
backgroundColor:{
image:require('../../../../../assets/image/default/echart_bg.png')
},
borderWidth:0,
},
tooltip: {
trigger: 'item',
formatter:function(params){
return params.data[2] == 'transparent'?'':`${params.name}<br/>${params.data[0]}`
},
},
xAxis: {
type: 'time',
maxInterval: 3600 * 1000 * 24 * 30 * 12,//设置间隔最大值
minInterval:1000 * 60 * 2,//设置间隔最小值
axisLine: {
// 轴线
show: true,
},
axisTick: {
// 轴刻度
show: true,
alignWithLabel: true,
},
},
yAxis: {
data: [],
axisLine: {
// 轴线
show: false,
},
axisTick: {
// 轴刻度
show: false,
},
splitLine: {
// 网格线
show: true,
alignWithLabel: true,
lineStyle:{
color:'#ccc'
}
},
triggerEvent:{
show: true,//点击事件
},
},
series: [
{
type: 'scatter',
smooth: true,
symbol: 'circle',
symbolSize: 20,
sampling: 'average',
itemStyle:{
color:(val)=>{
return val.data[2]
},
opacity:1
},
data: []
}
],
dataZoom: [
{
type: 'inside',//内置型数据区域缩放组件
xAxisIndex: 0,
filterMode: 'filter',//过滤掉窗口外的数据
realtime: true,
},
],
},
myChart:null,
dataList:[],//颜色集合
dataValue:[],//数据集合
};
},
③初始化图表
initEchart() {
let that = this;
let scale = '1年';//间隔值
let queryTimePeriodLimit = {
startTime:null,
endTime:null,
}
// 基于准备好的dom,初始化echarts实例
this.myChart = this.$echarts.init(document.getElementById("echart"));
//this.ruleForm.spatialTrajectoryTime为时间范围选择值,如何存在则为时间轴起始值否则开始值为当前-8年结束值为当前+2年
if(this.ruleForm.spatialTrajectoryTime && this.ruleForm.spatialTrajectoryTime.length > 0 && this.ruleForm.spatialTrajectoryTime[0].queryTimePeriodLimit){
this.option.xAxis.min = new Date(this.ruleForm.spatialTrajectoryTime[0].queryTimePeriodLimit[0]).getTime();
this.option.xAxis.max = new Date(this.ruleForm.spatialTrajectoryTime[0].queryTimePeriodLimit[1]).getTime();
}else{
this.option.xAxis.min = new Date().getTime()-8*12*30*24*60*60*1000;
this.option.xAxis.max = new Date().getTime()+2*12*30*24*60*60*1000;
}
//获取当前间隔值
scale = that.handleTimeAndScale(this.option.xAxis.min,this.option.xAxis.max,'init');
// 绘制图表
this.myChart.setOption(this.option,true);
window.addEventListener("resize", () => {
that.myChart.resize();
});
this.$emit('getScale',scale,'init');//调用接口获取当前值渲染图表
this.myChart.on('dataZoom',function(params){
let startValue = parseInt(that.myChart.getModel().option.dataZoom[0].startValue);
let endValue = parseInt(that.myChart.getModel().option.dataZoom[0].endValue);
queryTimePeriodLimit.startTime = that.dateFormatter('yyyy-MM-dd HH:mm:ss',new Date(startValue));
queryTimePeriodLimit.endTime = that.dateFormatter('yyyy-MM-dd HH:mm:ss',new Date(endValue));
scale = that.handleTimeAndScale(startValue,endValue);
//缩放、拖动时间轴后调用接口获取当前值渲染图表
})
that.myChart.off('click');//先移除,再点击
that.myChart.on('click', function (params) {
//点击y轴
if(params.componentType == 'yAxis'){
that.dataList[params.tickIndex].clicked = !that.dataList[params.tickIndex].clicked;
that.dataValue.map((value,key)=>{
if(value[3] == params.dataIndex){
if(that.dataList[params.tickIndex].clicked){
// 显示时间轴数据
value[2] = that.colorList[params.dataIndex];
}else{
// 隐藏时间轴数据
value[2] = 'transparent';
}
}
})
that.myChart.setOption({yAxis:that.setYaxisIcon(that.dataList)});//设置y轴样式
that.myChart.setOption({series:that.option.series[0]});
}
});
},
// 渲染数据
getEchartsData(dataList){
let that = this;
let data = [];
this.dataValue = [];
this.dataList = dataList;
this.dataList.map((item,index)=>{
data.push(item.entityName+'-'+item.propertyTypeName);
if(item.locus && item.locus.length > 0){
item.locus.map((list,pre)=>{
if(list.locus && list.locus.length > 0 ){
list.locus.map((value,key)=>{
//第一个值为x轴值,第一个值为y轴名称,第三个值为颜色,第四个值为索引...需要什么值可在此位置添加
that.dataValue.push([value.startTime,item.entityName+'-'+item.propertyTypeName,(item.clicked?(that.colorList[index]):'transparent'),index]);
})
}
})
}
})
that.option.yAxis.data = data;
that.setYaxisIcon(that.dataList);
that.option.series[0].data = that.dataValue;
that.myChart.setOption({yAxis:that.option.yAxis});
that.myChart.setOption({series:that.option.series[0]});
},
//在数据区域缩放时能获取数据窗口范围的起始数值,利用起始值可以获取到起始值的差值,根据差值的大小来设置当前的间隔值
//(由于x轴type为time所以x轴的scale值无效,获取不到比例尺所以想出此方法)
handleTimeAndScale(startValue,endValue,type){
let that = this;
let scale = '';
let intervalValue = null;
let interval = (endValue - startValue)/1000/60/60;
if(interval > 44336){
intervalValue = 3600 * 1000 * 24 * 30 * 12;
scale = '1年';
}else if(interval <= 44336 && interval > 27529){
intervalValue = 3600 * 1000 * 24 * 30 * 7;
scale = '6月';
}else if(interval <= 27529 && interval > 14127){
intervalValue = 3600 * 1000 * 24 * 30 * 4;
scale = '3月';
}else if(interval <= 14127 && interval > 8771){
intervalValue = 3600 * 1000 * 24 * 30 * 3;
scale = '2月';
}else if(interval <= 8771 && interval > 3381){
intervalValue = 3600 * 1000 * 24 * 30 * 1;
scale = '1月';
}else if(interval <= 3381 && interval > 2309){
intervalValue = 3600 * 1000 * 24 * 17;
scale = '16天';
}else if(interval <= 2309 && interval > 1095){
intervalValue = 3600 * 1000 * 24 * 8;
scale = '7天';
}else if(interval <= 1095 && interval > 511){
intervalValue = 3600 * 1000 * 24 * 5;
scale = '4天';
}else if(interval <= 511 && interval > 222){
intervalValue = 3600 * 1000 * 24 * 3;
scale = '2天';
}else if(interval <= 222 && interval > 125){
intervalValue = 3600 * 1000 * 24 * 1;
scale = '1天';
}else if(interval <= 125 && interval > 73){
intervalValue = 3600 * 1000 * 13;
scale = '12时';
}else if(interval <= 73 && interval > 37){
intervalValue = 3600 * 1000 * 7;
scale = '6时';
}else if(interval <= 37 && interval > 22){
intervalValue = 3600 * 1000 * 5;
scale = '4时';
}else if(interval <= 22 && interval > 12){
intervalValue = 3600 * 1000 * 3;
scale = '2时';
}else if(interval <= 12 && interval > 4.4){
intervalValue = 3600 * 1000 * 1;
scale = '1时';
}else if(interval <= 4.4 && interval > 3){
intervalValue = 1000 * 60 * 31;
scale = '30分钟';
}else if(interval <= 3 && interval > 2){
intervalValue = 1000 * 60 * 21;
scale = '20分钟';
}else if(interval <= 2 && interval > 1.5){
intervalValue = 1000 * 60 * 16;
scale = '15分钟';
}else if(interval <= 1.5 && interval > 1){
intervalValue = 1000 * 60 * 11;
scale = '10分钟';
}else if(interval <= 1 && interval > 0.5){
intervalValue = 1000 * 60 * 6;
scale = '5分钟';
}else if(interval <= 0.5 && interval > 0.2){
intervalValue = 1000 * 60 * 3;
scale = '2分钟';
}else if(interval <= 0.2){
intervalValue = 1000 * 60 * 2;
scale = '1分钟';
}
if(type && type == 'init'){
that.option.xAxis.interval = intervalValue;
}else{
that.myChart.setOption({xAxis:{interval:intervalValue}});
}
return scale
},
// 设置y轴图标
setYaxisIcon(nodes){
let that = this;
that.option.yAxis.axisLabel = {
formatter: function (value,index) {
return '{nodeName|' + (nodes[index].entityName.length>5?(nodes[index].entityName.slice(0,5)+'...'):nodes[index].entityName) + `}{${nodes[index].clicked?'image':'imageClicked'}|` + '}\n{propertyTypeName|' + (nodes[index].propertyTypeName.length>5?(nodes[index].propertyTypeName.slice(0,5)+'...'):nodes[index].propertyTypeName) + '}';
},
rich: {
nodeName:{
fontWeight:700,
padding: [0, 6 , 0 , 0],
align: 'left',
color:'#000'
},
image: {
width:14,
height: 14,
cursor: 'pointer',
backgroundColor: {
image: require('../../../../../assets/image/default/clickedEye.png'),
},
},
imageClicked: {
width:14,
height: 14,
cursor: 'pointer',
backgroundColor: {
image: require('../../../../../assets/image/default/clickEye.png'),
},
},
propertyTypeName: {
lineHeight: 30,
align: 'left',
},
},
}
},