快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)


Posted in Javascript onAugust 29, 2016

记录两个项目开发中遇到的问题,一个是ECharts外部调用保存为图片操作,一个是workflow工作流连接曲线onmouseenter和onmouseleave事件由于鼠标移动过快触发问题。

一、外部按钮调用ECharts图表的保存为图片操作

最近使用ECharts库绘制图表,依据需求希望可以把图表设置的保存为图片操作可以在图表外部调用,主要是希望可以和项目之前的下载图片操作界面保持一致。然后上网找了一些方法,看了看也没遇到一个可以满意的。后来,突然想到了echart开放了源码,可以看看源码,找到下载的方法,然后调用不就可以了(可能是我技术忒次,看了看不只到如何直接调用方法,所以把源方法copy下来,改了改,只需要传递图表的容器id即可)

echart图表示例(工具栏中有下载图片按钮)

快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)

附上代码记录一下

//传递图表容器idfunction downloadImpByChart(chartId){
var myChart = echarts.getInstanceByDom(document.getElementById(chartId));
var url = myChart.getConnectedDataURL({
pixelRatio: 5,//导出的图片分辨率比率,默认是1
backgroundColor: '#fff',
//图表背景色
excludeComponents:[
//保存图表时忽略的工具组件,默认忽略工具栏
'toolbox'
],
type:'png'
//图片类型支持png和jpeg
});
var $a = document.createElement('a');
var type = 'png';
$a.download = myChart.getOption().title[0].text + '.' + type;
$a.target = '_blank';
$a.href = url;
// Chrome and Firefox
if (typeof MouseEvent === 'function') {
var evt = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: false
});
$a.dispatchEvent(evt);
}
// IE
else {
var html = ''
+ '<body style="margin:0;">'
+ '<img src="' + url + '" style="max-width:100%;" title="' + myChart.getOption().title[0].text + '" />'
+ '</body>';
var tab = window.open();
tab.document.write(html);
}
};

这样,我们就可以不使用它自带的下载操作了,就可以在外部自定义按钮、超链接,直接调用上面的方法就可以实现外部调用保存图片功能了。

二、onmouseenter和onmouseleave移动速度过快导致不能正确的时机触发事件机制

上图说明一下

快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)

希望鼠标在曲线上移动时不仅可以高亮展示曲线,还要在鼠标位置增加剪刀图标,按下剪刀时可以删除曲线。之前就直接在曲线上使用的mouseener和mouseleave方法,然后鼠标在多条曲线上快速移动时,就会出现诸多问题(剪刀不会在光标离开时消失,多条曲线都变为高亮效果)。试了多加上一些逻辑判定和换用mouseover和mouseout方法均不管用。后来突然想到,可以使用mousemove方法。判定鼠标是否在剪刀图表的区域范围内,若在则高亮该条曲线,不再,则所有曲线恢复默认样式。然后居然成功了。困扰了一整天的问题终于解决了。(由于mousemove在鼠标移动时需要不断的去监听和触发事件,所以最好可以有一个状态标识表明在该状态在再去调用高亮曲线和绘制剪刀的方法。图上的调用时机是,当鼠标进入曲线时,设定一个全局变量为true,此后的mousemove操作根据该变量判定

记录一下部分关键代码

鼠标就进入高亮及绘制剪刀图表

$(document).on("mouseenter","svg .curve",function(e){
//每次进入后都将恢复成原始状态
$("svg .node").each(function(){
this.setAttribute("opacity","1");
});
$.each(relation.links,function(l,link){
var in_node_id=link.input.nodeId;
var out_node_id=link.output.nodeId;
$("#"+out_node_id+link.output.pointName+in_node_id+link.input.pointName)[0].setAttribute("opacity","1");
$("#"+out_node_id+link.output.pointName+in_node_id+link.input.pointName).attr("class","curve");
});
//编辑状态下需要显示可操作图标
if(args.state=="edit"){
del_Curve.ref_Curve=this;
del_Curve.has_del_curve=true;
if($("#del-curve-icon").length>0){
$("#del-curve-icon").css({
position:"absolute",
top: e.pageY-obj.offset().top-10,
left: e.pageX-obj.offset().left-10,
color:"#ff0000"
}).show();
}else{
var del_icon=$("<i id='del-curve-icon' class='fa fa-scissors'></i>").css({
position:"absolute",
top: e.pageY-obj.offset().top-10,
left: e.pageX-obj.offset().left-10,
color:"#ff0000",
fontSize:"20px"
});
obj.parent().append(del_icon);
}
del_Curve.xAxis=$("#del-curve-icon").offset().left;
del_Curve.yAxis=$("#del-curve-icon").offset().top;
}
//然后高亮当前曲线
if($(this).attr("start")!=undefined && $(this).attr("end")!=undefined){
//设置透明度
$("svg .node").each(function(){
this.setAttribute("opacity","0.1");
});
$.each(relation.links,function(l,link){
var in_node_id=link.input.nodeId;
var out_node_id=link.output.nodeId;
$("#"+out_node_id+link.output.pointName+in_node_id+link.input.pointName)[0].setAttribute("opacity","0.1");
});
obj.children("g").eq(0).children("g").eq(0).before($(this));
$(this).attr("class","curve curve-hover");
var in_node=$("#"+$(this).attr("start")).children("g").eq(0).children("circle").eq(1);
in_node.attr("class",in_node.attr("class")+" node-hover");
$("#"+$(this).attr("start"))[0].setAttribute("opacity","1");
var out_node=$("#"+$(this).attr("end")).children("g").eq(0).children("circle").eq(1);
out_node.attr("class",out_node.attr("class")+" node-hover");
$("#"+$(this).attr("end"))[0].setAttribute("opacity","1");
}
});

移动鼠标判定触发操作

$(document).on("mousemove",function(e){if(del_Curve.has_del_curve){
var del_icon_width=$("#del-curve-icon").width();
var del_icon_height=$("#del-curve-icon").height()



//判定当前光标位置,若不在剪刀图表区域内则恢复默认样式
if(e.pageX<del_Curve.xAxis || e.pageX>(del_Curve.xAxis+del_icon_width) || e.pageY<del_Curve.yAxis || e.pageY>(del_Curve.yAxis+del_icon_height)){
del_Curve.has_del_curve=false;
$("svg .node").each(function(){
this.setAttribute("opacity","1");
});
$.each(relation.links,function(l,link){
var in_node_id=link.input.nodeId;
var out_node_id=link.output.nodeId;
$("#"+out_node_id+link.output.pointName+in_node_id+link.input.pointName)[0].setAttribute("opacity","1");
$("#"+out_node_id+link.output.pointName+in_node_id+link.input.pointName).attr("class","curve");
});
$(del_Curve.ref_Curve).attr("class","curve");
var in_node=$("#"+$(del_Curve.ref_Curve).attr("start")).children("g").eq(0).children("circle").eq(1);
in_node.attr("class",in_node.attr("class").replace("node-hover","").trim());
var out_node=$("#"+$(del_Curve.ref_Curve).attr("end")).children("g").eq(0).children("circle").eq(1);
out_node.attr("class",out_node.attr("class").replace("node-hover","").trim());
$("#del-curve-icon").hide();
}
}
})

okay,其实工作流的问题,如果单单只是高亮曲线,mouseenter和mouseleave的效果就足够了。不过示例中,需要在曲线上覆盖一个剪刀图标,这就会跟原来曲线的mouseenter和mouseleave有冲突。因为删除曲线的触发元素是剪刀图标。

Javascript 相关文章推荐
js调用打印机打印网页字体总是缩小一号的解决方法
Jan 24 Javascript
node.js操作mongodb学习小结
Apr 25 Javascript
javascript实现标签切换代码示例
May 22 Javascript
JS实现图文并茂的tab选项卡效果示例【附demo源码下载】
Sep 21 Javascript
javascript简单进制转换实现方法
Nov 24 Javascript
Js实现中国公民身份证号码有效性验证实例代码
May 03 Javascript
Three.js基础学习之场景对象
Sep 27 Javascript
详解vue项目的构建,打包,发布全过程
Nov 23 Javascript
webstorm和.vue中es6语法报错的解决方法
May 08 Javascript
js中的reduce()函数讲解
Jan 18 Javascript
如何在微信小程序里面退出小程序的方法
Apr 28 Javascript
了解javascript中let和var及const关键字的区别
May 24 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
Aug 29 #Javascript
jQuery EasyUI编辑DataGrid用combobox实现多级联动
Aug 29 #Javascript
对js中回调函数的一些看法
Aug 29 #Javascript
Web打印解决方案之普通报表打印功能
Aug 29 #Javascript
jQuery获取select选中的option的value值实现方法
Aug 29 #Javascript
js 判断各种数据类型的简单方法(推荐)
Aug 29 #Javascript
Web打印解决方案之证件套打的实现思路
Aug 29 #Javascript
You might like
PHP循环函数使用介绍之PHP基础入门教程
2013/09/21 PHP
用脚本调用样式的几种方法
2006/12/09 Javascript
IE 缓存策略的BUG的解决方法
2007/07/21 Javascript
使用jQuery实现的网页版的个人简历(可换肤)
2013/04/19 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
2013/06/28 Javascript
JavaScript转换二进制编码为ASCII码的方法
2015/04/16 Javascript
JavaScript控制网页平滑滚动到指定元素位置的方法
2015/04/17 Javascript
JavaScript模拟实现键盘打字效果
2015/06/29 Javascript
使用jquery插件qrcode生成二维码
2015/10/22 Javascript
javascript高级编程之函数表达式 递归和闭包函数
2015/11/29 Javascript
使用jQuery给input标签设置默认值
2016/06/20 Javascript
JavaScript数据结构链表知识详解
2016/11/21 Javascript
利用js+css+html实现固定table的列头不动
2016/12/08 Javascript
详解Vue生命周期的示例
2017/03/10 Javascript
angularjs实现首页轮播图效果
2017/04/14 Javascript
JS异步函数队列功能实例分析
2017/11/28 Javascript
浅析Visual Studio Code断点调试Vue
2018/02/27 Javascript
angular2模块和共享模块详解
2018/04/08 Javascript
vue项目实现github在线预览功能
2018/06/20 Javascript
JS+H5 Canvas实现时钟效果
2018/07/20 Javascript
详解从NodeJS搭建中间层再谈前后端分离
2018/11/13 NodeJs
vue 实现websocket发送消息并实时接收消息
2019/12/09 Javascript
Python实现提取文章摘要的方法
2015/04/21 Python
python实现寻找最长回文子序列的方法
2018/06/02 Python
详解Python打包分发工具setuptools
2019/08/05 Python
解决TensorFlow程序无限制占用GPU的方法
2020/06/30 Python
css3实现文字首尾衔接跑马灯的示例代码
2020/10/16 HTML / CSS
Html5基于canvas实现电子签名并生成PDF文档
2020/12/07 HTML / CSS
美国知名的百货清仓店:Neiman Marcus Last Call
2016/08/03 全球购物
澳大利亚便宜的家庭购物网站:CrazySales
2018/02/06 全球购物
Dr. Martens马汀博士法国官网:马丁靴鼻祖
2020/01/15 全球购物
干部现实表现材料
2014/02/13 职场文书
秋季运动会广播稿(30篇)
2014/09/13 职场文书
《鸟的天堂》教学反思
2016/02/19 职场文书
解决golang post文件时Content-Type出现的问题
2021/05/02 Golang
MySQL外键约束(FOREIGN KEY)案例讲解
2021/08/23 MySQL