快速移动鼠标触发问题及解决方法(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 相关文章推荐
SWFObject 2.1以上版本语法介绍
Jul 10 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
Feb 27 Javascript
JS实现Select的option上下移动的方法
Mar 01 Javascript
js实现彩色条纹滚动条效果
Mar 15 Javascript
微信小程序页面间通信的5种方式
Mar 31 Javascript
jQuery+pjax简单示例汇总
Apr 21 jQuery
JavaScript高阶函数_动力节点Java学院整理
Jun 28 Javascript
JavaScript中的FileReader图片预览上传功能实现代码
Jul 24 Javascript
Vue的实例、生命周期与Vue脚手架(vue-cli)实例详解
Dec 27 Javascript
bootstrap+jquery项目引入文件报错的解决方法
Jan 22 jQuery
4个顶级JavaScript高级文本编辑器
Oct 10 Javascript
JavaScript享元模式原理与用法实例详解
Mar 09 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和ACCESS写聊天室(三)
2006/10/09 PHP
PHP下常用正则表达式整理
2010/10/26 PHP
PHP中SESSION使用中的一点经验总结
2012/03/30 PHP
PHP提示Notice: Undefined variable的解决办法
2012/11/24 PHP
PHP遍历目录并返回统计目录大小
2014/06/09 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
Yii扩展组件编写方法实例分析
2015/06/29 PHP
Yii2 输出xml格式数据的方法
2016/05/03 PHP
javascript学习笔记(九) js对象 设计模式
2012/06/19 Javascript
JS小功能(button选择颜色)简单实例
2013/11/29 Javascript
PHP PDO操作总结
2014/11/17 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
2015/08/20 Javascript
深入浅析JavaScript的API设计原则
2016/06/14 Javascript
jQuery实现的简单悬浮层功能完整实例
2017/01/23 Javascript
javascript数据结构之串的概念与用法分析
2017/04/12 Javascript
JS Object.preventExtensions(),Object.seal()与Object.freeze()用法实例分析
2018/08/25 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
js里面的变量范围分享
2020/07/18 Javascript
Python threading多线程编程实例
2014/09/18 Python
python判断字符串是否纯数字的方法
2014/11/19 Python
Python脚本文件打包成可执行文件的方法
2015/06/02 Python
浅析Python中return和finally共同挖的坑
2017/08/18 Python
python实现xlsx文件分析详解
2018/01/02 Python
python 解压pkl文件的方法
2018/10/25 Python
深入浅析python 协程与go协程的区别
2019/05/09 Python
Linux下远程连接Jupyter+pyspark部署教程
2019/06/21 Python
Python如何读写CSV文件
2020/08/13 Python
Clarks英国官方网站:全球领军鞋履品牌
2016/11/26 全球购物
办公室内勤工作职责
2013/12/11 职场文书
党支部公开承诺书
2014/03/28 职场文书
英语自我介绍演讲稿
2014/09/01 职场文书
2015社区精神文明建设工作总结
2015/04/21 职场文书
士兵突击观后感
2015/06/16 职场文书
呼啸山庄读书笔记
2015/06/29 职场文书
html+css实现滚动到元素位置显示加载动画效果
2021/08/02 HTML / CSS
Java字符串逆序方法详情
2022/03/21 Java/Android