2021-12-17更新
如上图所示,固定XY轴的功能也很简单只需要在options
里的markLine
里面的设置加上两个配置就行
2021-12-16更新
突然之间发现下面的洋洋洒洒一大堆代码其实毫无作用,
想要markLine跟着关系图一起移动,只需要在mouseup事件里加上this.echarsInstance.setOption({series:seriesData})
就行
如下
InitChart($event:echarts.ECharts){
this.echarsInstance = $event;//拿到echarts对象
this.echarsInstance.getZr().on('mouseup',params=>{
if(this.echarsInstance.containPixel({seriesIndex:[0]},[params.offsetX,params.offsetY])){
let series:any = this.echarsInstance.getOption()['series']
let seriesData = series[0];
this.echarsInstance.setOption({series:seriesData})//更新配置
}
})
}
吐血
如上图所示,公司现在给了需求,需要在移动garph
(关系图)的时候,markLine
做成的底图也要随之一起移动。
话不多说,直接开干
2021-12-15
首先需要明确的就是,在我接手的时候,底图是确定的,也就是这么个状态
可以看到整体都已经搭建起来了,也就是我并不需要从零开始搭建代码,也就是garph
的option
我是不用改什么的,但是问题就是移动关系图的时候,markLine
并不会随之一起移动。
当然,遇事不决查官方文档,很可惜,官方文档里并没有给出markLine
移动相关的API
似乎官方对markLine
定位就是一种定死的标线,不会移动也不会变化。那么,对此就毫无办法了吗?
那肯定是有办法的,
换个角度想既然可以生成固定的markLine
,那笨一点,我在鼠标按下去的时候记录一下点击的位置,抬起的时候把抬起的位置和按下去的时候位置比对,就可以得到计算后的位置,将其把markLine
中每一条线的坐标分别减去计算后的位置,然后再把echarts
的图刷新一下,不就得到了markLine
改变位置后的图吗?
纸上谈兵不如实际操练,必须立刻马上开始敲代码
首先,公司里没有直接使用echarts,而是使用了封装一层的ngx-echarts
,大家感兴趣可以去查一下,ngx-echarts
用起来很简单,也十分的好用,具体使用在此不表
首先上html代码
<div style="height: 700px;" (chartInit)="InitChart($event)"
echarts [options]="echartOptions"></div>
其中echarts
就是ngx-echarts
提供的指令了chartInit
是其暴露的方法,就是在图形加载以后触发的事件,其中$event
就是Echarts
实例对象了,options
当然就是echarts
图形需要的相关options
了,echartsOptions
大概的参数如下,想必使用过echarts
画过图形之类的朋友对这些配置应该很熟悉
然后就是ts
里面的代码了
//首先拿到echarts对象
InitChart($event:echarts.ECharts){
this.echarsInstance = $event;//拿到echats对象
}
为什么要拿到eccharts
对象呢,直接用echarts
官方的事件不就行了吗,比如ngx-charts里面提供的事件
笔者当然不是饭吃太多了多敲代码消化下
是因为这些事件针对的真的只是图形自身,敲重点,图形自身
我们来对比一下效果看看
//html
<div style="height: 700px;" echarts [options]="echartOptions"
(chartClick)="testClick($event)"></div>
//ts
testClick($event:any){
console.log('自带的点击事件',$event)
}
上面使用的是echarts
官方暴露的事件(虽然被ngx-echarts
包装了一层,方便调用)
可以看到,我的鼠标一直都是点击状态的,但是只有点击到关系图本身的时候,才会触发testClick
的点击事件,也即是图形节点本身。
换用实例触发事件来看看
//html
<div style="height: 700px;" echarts [options]="echartOptions"
(chartInit)="InitChart($event)"></div>
//ts
InitChart($event:echarts.ECharts){
this.echarsInstance = $event;
this.echarsInstance.getZr().on('mousedown',params=>{
console.log('利用echats对象的点击事件',params)
})
}
可以看到不论是点击到markLine
所画的底图上,还是关系图的节点上, 事件都能够正常触发。
所以,要拿到实例本身,然后进行事件的操作
继续上代码
InitChart($event:echarts.ECharts){
this.echarsInstance = $event;//拿到echarts对象
let xoffset:Array<number> = [0,0,0];//分别是鼠标按下时候的x位置,鼠标抬起时候的x值,两者的差值
let yoffset:Array<number> = [0,0,0];//如上,y轴相关的值
this.echarsInstance.getZr().on('mousedown',params=>{//echarts对象的鼠标按下事件
if(this.echarsInstance.containPixel({seriesIndex:[0]},[params.offsetX,params.offsetY])){//重要 判断鼠标点击的位置是否在图形内部
let transform = this.pixelToLocation([params.offsetX,params.offsetY]);//重要 将鼠标点击的像素点,转化为图形所在的坐标系,如果没有经过转换,移动以后就会有误差
xoffset[0] = transform[0];
yoffset[0] = transform[1]
console.log('利用echats对象的点击事件',params)
}
})
this.echarsInstance.getZr().on('mouseup',params=>{
if(this.echarsInstance.containPixel({seriesIndex:[0]},[params.offsetX,params.offsetY])){
let transform = this.pixelToLocation([params.offsetX,params.offsetY]);
xoffset[1] = transform[0];
yoffset[1] = transform[1];
xoffset[2] = xoffset[0] - xoffset[1];
yoffset[2] = yoffset[2] - yoffset[2];
let series:any = this.echarsInstance.getOption()['series']
let seriesData = series[0];
let markLineData = [];
if(seriesData.markLine){
markLineData = seriesData.markLine.data;
if(markLineData){
markLineData.forEach((item: any) => {
item[0].coord = [ item[0].coord[0]-xoffset[2] , item[0].coord[1]-yoffset[2] ];
item[1].coord = [ item[1].coord[0]-xoffset[2] , item[1].coord[1]-yoffset[2] ];
});
}
seriesData.markLine.data = markLineData;
}
// this.setEchartsOption({series:seriesData})
this.echarsInstance.setOption({series:seriesData})//将改变后的数据覆盖echarts的配置
}
})
}
解释下其中比较重要的代码
this.echarsInstance.containPixel({seriesIndex:[0]},[params.offsetX,params.offsetY]))
是官方文档里面的一个方法,描述如下
判断给定的点是否在指定的坐标系或者系列上
也就是判断你给定的xy的数据是否为第一个值的坐标系内,是就返回true
坐标转换方法
pixelToLocation(array:Array<number>){
return this.echartsInstance.convertFromPixel({seriesIndex:0},array)
}
官方文档里面的描述
转换像素坐标值到逻辑坐标系上的点。
也就是将鼠标的像素点,转换为坐标系上的位置。
经此一番操作,终于markLine能随着关系图的移动而移动啦,至于鼠标滚轮放大缩小,操作其实和鼠标按下松开的操作差不多,只多了一个请求节流的操作。在这里暂且不表,如果有各位朋友需要再写出。
希望各位看官不要吝啬手里的赞,有缘再见。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。