头图

graph中使用markLine 能够随着graph图移动而一起移动(固定也行)

2021-12-17更新
QQ录屏20211215105815(4).gif

如上图所示,固定XY轴的功能也很简单只需要在options里的markLine里面的设置加上两个配置就行
image.png

image.png

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})//更新配置

            }
        })
    }

吐血


QQ录屏20211215105815(1).gif
如上图所示,公司现在给了需求,需要在移动garph(关系图)的时候,markLine做成的底图也要随之一起移动。

话不多说,直接开干


2021-12-15

首先需要明确的就是,在我接手的时候,底图是确定的,也就是这么个状态
QQ录屏20211215105815.gif

可以看到整体都已经搭建起来了,也就是我并不需要从零开始搭建代码,也就是garphoption我是不用改什么的,但是问题就是移动关系图的时候,markLine并不会随之一起移动。

当然,遇事不决查官方文档,很可惜,官方文档里并没有给出markLine移动相关的API
image.png

似乎官方对markLine定位就是一种定死的标线,不会移动也不会变化。那么,对此就毫无办法了吗?

那肯定是有办法的,

换个角度想既然可以生成固定的markLine,那笨一点,我在鼠标按下去的时候记录一下点击的位置,抬起的时候把抬起的位置和按下去的时候位置比对,就可以得到计算后的位置,将其把markLine中每一条线的坐标分别减去计算后的位置,然后再把echarts的图刷新一下,不就得到了markLine改变位置后的图吗?

纸上谈兵不如实际操练,必须立刻马上开始敲代码

首先,公司里没有直接使用echarts,而是使用了封装一层的ngx-echarts,大家感兴趣可以去查一下,ngx-echarts用起来很简单,也十分的好用,具体使用在此不表
image.png

首先上html代码

<div style="height: 700px;" (chartInit)="InitChart($event)"
echarts [options]="echartOptions"></div>

其中echarts就是ngx-echarts提供的指令了
chartInit是其暴露的方法,就是在图形加载以后触发的事件,其中$event就是Echarts实例对象了,options当然就是echarts图形需要的相关options了,echartsOptions大概的参数如下,想必使用过echarts画过图形之类的朋友对这些配置应该很熟悉
image.png

然后就是ts里面的代码了

//首先拿到echarts对象
InitChart($event:echarts.ECharts){
    this.echarsInstance = $event;//拿到echats对象
}

为什么要拿到eccharts对象呢,直接用echarts官方的事件不就行了吗,比如ngx-charts里面提供的事件
image.png

笔者当然不是饭吃太多了多敲代码消化下
是因为这些事件针对的真的只是图形自身,敲重点,图形自身

我们来对比一下效果看看

//html
<div style="height: 700px;"  echarts [options]="echartOptions"
(chartClick)="testClick($event)"></div>

//ts
testClick($event:any){
    console.log('自带的点击事件',$event)
}

上面使用的是echarts官方暴露的事件(虽然被ngx-echarts包装了一层,方便调用)

QQ录屏20211215105815(2).gif

可以看到,我的鼠标一直都是点击状态的,但是只有点击到关系图本身的时候,才会触发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)
    })
}

QQ录屏20211215105815(3).gif

可以看到不论是点击到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]))
是官方文档里面的一个方法,描述如下

判断给定的点是否在指定的坐标系或者系列上

image.png

也就是判断你给定的xy的数据是否为第一个值的坐标系内,是就返回true

坐标转换方法

pixelToLocation(array:Array<number>){
    return this.echartsInstance.convertFromPixel({seriesIndex:0},array)
}

官方文档里面的描述

转换像素坐标值到逻辑坐标系上的点。

也就是将鼠标的像素点,转换为坐标系上的位置。

经此一番操作,终于markLine能随着关系图的移动而移动啦,至于鼠标滚轮放大缩小,操作其实和鼠标按下松开的操作差不多,只多了一个请求节流的操作。在这里暂且不表,如果有各位朋友需要再写出。

希望各位看官不要吝啬手里的赞,有缘再见。


跌撞前进的菜鸟
胡乱学习前进中遇到的各种坑与解决办法

现在即是最好。

12 声望
2 粉丝
0 条评论
推荐阅读
git和TortoiseGit安装完成后在本地推送文件到github仓库报错的解决办法
然后在控制台输入ssh-keygen -t ed25519 -C &quot;邮箱&quot;注意,不要直接ssh-keygen -o了,因为github2020年3月开始就不支持rsa算法了,所以改用ed25519算法的秘钥,后面必须跟着双引号,里面填注册的邮箱

munergs阅读 516

使用springboot+angular实现web端微信扫码登陆
现在微信的使用用户越来越多,如果网站添加上微信登录,就能节省很多用户注册时间,极大缩小了注册流程。会让用户觉得特别方便。接下来我们就说一下怎么来实现Web端微信扫码登录。

郝泽龙_HZ6阅读 924

解决angular 报错 url unsafe
遇到报错使用的img 标签出现了报错 {代码...} 报错这个url 为 unsafeXSS首先先了解为什么会出现unsafe为了系统性的防范 XSS 问题,Angular 默认把所有值都当做不可信任的。即 unsafe跨站脚本(XSS)允许攻击者将恶...

weiweiyi3阅读 391

实现第三方登陆:微信扫码登录 (spring boot)
前言各种官方网站通常都会有app、微信公众号等。比如央视网,银行等。当我们关注公众号或者app后,这些应用就可以在移动端方便地将信息推送给用户。统一各产品线的账号体系,实现一个账号处处使用的目标是非常有...

weiweiyi4阅读 598

Async Pipe 以及Promise
前言之前在写项目的时候引用某个管道的时候 &lt;td&gt;{{ house | housePlace }}发现效果不是想要的, 而是如下图的效果,并没有显示出正确的地址!参考项目中的代码发现需要加上async管道 &lt;td&gt;{{ house | h...

weiweiyi2阅读 949

java/kotlin 生成 echarts 图片最优解
一. 方法探索后台生成图片的方法不多,根据我在网上的查找,有如下几种方法:前台服务提供接口,结合图表提供的生成图片,请求后返回图片数据。搭建服务,与第一点类似,同样是发送数据。若有配合的前端服务,可...

zxdposter1阅读 1.4k

记一个angular在路由配置中管理 Angular Material Dialog(实现动态组件的弹窗显示)
我们的目标正如标题所言:在路由配置中管理 Angular Material Dialog,从而更简便(代码量更少,可复用性,可拓展性、可维护性更强)地实现动态组件的弹窗显示。不难看出,我们的目标由两个部分组成,动态组件和...

HHepan5阅读 346评论 2

现在即是最好。

12 声望
2 粉丝
宣传栏