記錄兩個項目開發中遇到的問題,一個是ECharts外部調用保存為圖片操作,一個是workflow工作流連接曲線onmouseenter和onmouseleave事件由於鼠標移動過快觸發問題。
一、外部按鈕調用ECharts圖表的保存為圖片操作
最近使用ECharts庫繪制圖表,依據需求希望可以把圖表設置的保存為圖片操作可以在圖表外部調用,主要是希望可以和項目之前的下載圖片操作界面保持一致。然后上網找了一些方法,看了看也沒遇到一個可以滿意的。后來,突然想到了echart開放了源碼,可以看看源碼,找到下載的方法,然后調用不就可以了(可能是我技術忒次,看了看不只到如何直接調用方法,所以把源方法copy下來,改了改,只需要傳遞圖表的容器id即可)
echart圖表示例(工具欄中有下載圖片按鈕)
附上代碼記錄一下
//傳遞圖表容器id
function 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移動速度過快導致不能正確的時機觸發事件機制
上圖說明一下
希望鼠標在曲線上移動時不僅可以高亮展示曲線,還要在鼠標位置增加剪刀圖標,按下剪刀時可以刪除曲線。之前就直接在曲線上使用的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有沖突。因為刪除曲線的觸發元素是剪刀圖標。
以上,記錄兩個開發中遇到的問題,方便以后可以直接拿來使用或明白換個方式解決問題一些沖突問題。
感謝閱讀。