快速移动鼠标触发问题及解决方法(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 相关文章推荐
表单项的name命名为submit、reset引起的问题
Dec 22 Javascript
javascript 哈希表(hashtable)的简单实现
Jan 20 Javascript
Javascript 类与静态类的实现
Apr 01 Javascript
javascript对中文按照拼音排序代码
Aug 20 Javascript
javascript制作坦克大战全纪录(2)
Nov 27 Javascript
jQuery学习笔记之jQuery中的$
Jan 19 Javascript
BootStrap创建响应式导航条实例代码
May 31 Javascript
headjs实现网站并行加载但顺序执行JS
Nov 29 Javascript
一个可复用的vue分页组件
May 15 Javascript
JS遍历DOM文档树的方法实例详解
Apr 03 Javascript
JavaScript实现放大镜效果代码示例
Apr 29 Javascript
插件导致ECharts被全量引入的坑示例解析
Sep 23 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
《星际争霸II》全新指挥官斯台特曼现已上线
2020/03/08 星际争霸
跟我一起学写jQuery插件开发方法(附完整实例及下载)
2010/04/01 Javascript
js 字符串转化成数字的代码
2011/06/29 Javascript
JS鼠标拖拽实例分析
2015/11/23 Javascript
前端框架Vue.js中Directive知识详解
2016/09/12 Javascript
JS如何设置iOS中微信浏览器的title
2016/11/22 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
2016/12/08 Javascript
微信小程序开发之map地图实现教程
2017/06/08 Javascript
JS实现移动端点击按钮复制文本内容
2019/07/28 Javascript
JS浏览器BOM常见操作实例详解
2020/04/27 Javascript
vue+echarts实现中国地图流动效果(步骤详解)
2021/01/27 Vue.js
python益智游戏计算汉诺塔问题示例
2014/03/05 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
2016/12/14 Python
django表单实现下拉框的示例讲解
2018/05/29 Python
Python3爬虫全国地址信息
2019/01/05 Python
python对列进行平移变换的方法(shift)
2019/01/10 Python
Django中提供的6种缓存方式详解
2019/08/05 Python
Python 实现自动导入缺失的库
2019/10/29 Python
Django通用类视图实现忘记密码重置密码功能示例
2019/12/17 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
2020/07/03 Python
Pycharm自动添加文件头注释和函数注释参数的方法
2020/10/23 Python
Html5跳转到APP指定页面的实现
2020/01/14 HTML / CSS
澳大利亚UGG工厂直销:Australian Ugg Boots
2017/10/14 全球购物
苏格兰销售女装、男装和童装的连锁店:M&Co
2018/03/16 全球购物
CHARLES & KEITH加拿大官网:新加坡时尚品牌
2020/03/26 全球购物
初中英语演讲稿
2014/04/29 职场文书
小学生倡议书范文
2014/05/13 职场文书
医院安全生产月活动总结
2014/07/05 职场文书
纪律教育学习心得体会
2014/09/02 职场文书
学生上课看漫画的检讨书
2014/09/26 职场文书
群众路线教育实践活动对照检查材料思想汇报(副处级领导)
2014/10/04 职场文书
应届毕业生求职信范文
2015/03/19 职场文书
劳动仲裁撤诉申请书
2015/05/18 职场文书
绿里奇迹观后感
2015/06/15 职场文书
Mysql数据库值的添加、修改、删除及清空操作实例
2021/06/20 MySQL
IDEA中sout快捷键无效问题的解决方法
2022/07/23 Java/Android