摘要:如果你嫌上面太瑣碎,可以直接取看我的試驗源碼,文件是歡迎本文后續從開始擼一個支持單軸輪播的雷達圖之末篇本文首發于
在線示例
如果你還不了解canvas,還不知道要講啥,建議從首篇看起:從0開始寫一個支持單軸輪播的雷達圖
在首篇我們已經講了怎么實現輪播,在這里我們將要用這一篇文章來說一下雷達圖的單軸hover效果的實現,也是我寫這篇文章的原因,因為echarts只支持單個series的hover。而我想要的是支持下面的效果:單軸hover。如果你只想知道怎么解決Echarts單軸輪播問題,并且你足夠機智,你可以直接看最后一節。
如果你用過Echarts的radar圖,如果你去看過生成雷達圖形成的dom結構,你hover后會發現如下圖所示
有沒有一種恍然大悟的感覺,其實就是在這畫布的容器(我們稱其為target)里里,添加了一個dom元素,來顯示提示詞。而這個dom元素的定位是絕對定位,定位點是根據hover捕獲點在畫布上的left和top計算值,然后顯示生成的tooltip值;所以我們可以思考,要達到前面這幾句話,我們需要提前做以下幾步:
1、綁定一個鼠標移動事件,并試圖捕捉畫布上的拐點;
2、根據捕捉的點,獲取相應的數據(標簽,數值);
3:生成一個div元素(也可以是label這些元素),并設定位置,樣式,及顯示值,并添加到容器中,大功告成;
原諒我用了個英文單詞,我確實不知道該用個什么標題。
如果你細心看過首篇的每一個實現步驟,并且理解整體思路,那接下來,事情會簡單很多。因為無論哪個js插件畫雷達圖,前面的幾步都是必須的,其核心除了canvas,其實就是計算和坐標轉換,即將一塊高為width,寬為height的dom元素變成一張擁有直角坐標系的畫布,就像下面這個簡圖:
我們為這個target元素綁定一個click事件,然后
const draw = document.getElementById("canvas"); const ctx = draw.getContext("2d"); /*獲取鼠標在canvas畫布上的位置(**不是瀏覽器窗口的鼠標位置) * clientX獲取的相對瀏覽器窗口左上角的位置,適用于所有瀏覽器 * 在chrome瀏覽器中,有一個zrX屬性,是相對于元素本身的相對位置 * getBoundingClientRect()函數是獲取元素邊框相對于瀏覽器窗口的位置 * */ function getMousePos(canvas, event) { var rect = canvas.getBoundingClientRect(); return { x: event.clientX - rect.left , y: event.clientY - rect.top } } draw.addEventListener("click",function(event){ console.log(getMousePos(draw,event)); //打印得到的,就是鼠標點擊位置相對于canvas容器元素左上角的坐標值,而不是相對于瀏覽器窗口。 });
如果你還不明白,你可以試著拷貝代碼,建立一個html頁面嘗試一下
根據獲取的坐標點,判斷是不是需要捕捉的點你有可能會疑問,就算捕捉了這個點,那怎么才能判斷這個點是不是需要捕捉的拐點呢?答案是,前面繪制這個拐點的時候,我們已經記錄下了這個拐點在坐標位置,所以我們只需要將點擊獲取到的像素(px)值,轉化為建立的坐標系坐標,我們就能輕易判斷是不是拐點了,當然為了實現的靈敏度,我們需要給其配一個誤差值,保證在拐點某個面積內都能觸發這個hover。代碼中有較多注釋,具體看代碼實現:
function addListener(dom,canvas,pointData){ //獲取鼠標在canvas畫布上的位置(**不是瀏覽器窗口的鼠標位置) function getMousePos(canvas, evt) { //canvas就是dom中的canvas元素 var rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left * (canvas.width / rect.width), y: evt.clientY - rect.top * (canvas.height / rect.height) } } dom.addEventListener("click",function (evt) { //開始測試建議用點擊,后面弄清楚了改成mousemove事件就ok const mouse = getMousePos(canvas, evt); let point={}; let text = ""; let index =-1; const r =5; //這個r就是那個允許的誤差值,值越大,越容易觸發hover point.x=mouse.x-offset.x/2; //offset的值就是畫布的長和寬值,利用他們的中心點,可以計算鼠標點擊位置在坐標系中的坐標值; point.y=mouse.y-offset.y/2;//同上 for(let i=0;i生成一個div元素,顯示相應展示的輪播值(item[0] - r) && point.x < (item[0] + r) && point.y > (item[1] - r) && point.y < (item[1] + r)) { index = i; //滿足條件,就記錄下這個值,用于后面單軸顯示 break; } } if(index!==-1){ hoverLabel(dom,mouse,index); //在下一步,我們將實現這個方法 }else{ removeLabel(dom);//當然,我們也將順便實現這個方法 } })
當我們生成一個div,并試圖定位將其添加到畫布容器中顯示出來時,你需要明白下面兩點:
1:這個div需要絕對定位,裝他的容器需要一個非static定位;
2:裝這個div的元素是裝canvas容器的元素,而不是canvas,添加到canvas中 ,你將什么也看不到;
這個實現較簡單,就直接看源碼吧
/*dom 即要添加div的容器,point即觸發hover事件的位置,是位置,不是變換后的坐標,text即要顯示的值*/ function hoverLabel(dom,point,text){ removeLabel(dom);//生成前先判斷有無,有就移除這個顯示標簽 let label =document.createElement("div"); label.style.position="absolute"; label.style.top=point.y+"px"; label.style.left=point.x+"px"; label.style.border="1px solid yellowgreen"; label.style.background = "gray"; label.style.zIndex = 999; label.innerHTML ="show:0999"+text; dom.appendChild(label); } function removeLabel(dom) { //移除這個顯示標簽 (dom.querySelectorAll("label").length)&&(dom.removeChild(dom.querySelector("label"))); //有就刪除,沒有就不動作 }
提示,我們也可以提前生成一個標簽元素,將其添加到畫布容器中,并不顯示它,后面我們只需動態改變它的位置和內容。
至此,我們已經完成了單軸的hover,也就是下面這種效果圖
到這里,似乎該告一段落了,但好戲才要真正開始,我們的標題是解決Echarts單軸輪播,我不是一個標題黨,所以接下來,將要討論這個有趣的話題。
通過上面我們已經自己實現了一個Radar圖,并對其實現了單軸輪播和hover,我們已經明白了其中的坐標變換,所以我們可否用Echarts生成一個radar圖,自己為其寫一個tooltip呢,答案是必須的,但前提是,這是個Radar圖只有一個系列,而且最好半徑是設定好的。其實現的核心思想就是,通過我們option中的設置,獲取畫布大小,獲取標簽和值,生成坐標系,算出目標點的坐標,然后添加上面說的hover事件,我們還是直接看他的具體實現,直接上源碼:
/*target 添加畫布的容器,option即為setOption中的Option,autoOption用于設定是否自動輪播,是否hover觸發,*/ function addHover(target,option,autoOption={autoShow:false,hoverEnable:true,time:1000}){ const m =Math; var center ={ //獲取畫布的中心偏離比,因為echarts支持百分數控制radar圖在畫布中的位置,所以我們需要計算這個點,當然我們也可以為了方便,不在option中設置,這樣我們就可以直接用畫布的中心點,即(0.5,0.5); pointx:(option.radar.center&&Number(option.radar.center[0].substr(0,option.radar.center[0].length-1))/100)||0.5, //計算X軸的偏離比例 pointy:(option.radar.center&&Number(option.radar.center[1].substr(0,option.radar.center[1].length-1))/100)||0.5, //計算y軸的偏離比例 }; var x=target.offsetWidth*center.pointx,y=target.offsetHeight*center.pointy; //計算radar中心點x的值,計算radar中心點x的值 var indicator = option.radar.indicator; //獲取option中radar的標簽 var data = option.series[0].data[0].value;//獲取option中radar的值,我們在這里只去第一個series的值; var length = indicator.length; //獲取標簽的長度,即雷達的拐點數,這個很重股 var step =-1; //輪播要用到的參數 var hovering =false ; //這個參數是控制輪播與hover同時觸發,顯示hover值,暫停輪播顯示 var radius=option.radar.radius,pointData=[]; //獲取radar的半徑 var style ={ //hover顯示的樣式 color:"#fff", border:"1px solid rgb(51,51,51)", borderRadius:"4px", backgroundColor:"rgba(50,50,50,0.7)" }; const single = 2*m.PI /length*(-1); for(let i = 0;i(item[0] - r) && point.x < (item[0] + r) && point.y > (item[1] - r) && point.y < (item[1] + r)) { index = i; break; } } if(index!==-1){ var tag =indicator[index] var text = tag.name+":"+m.round(data[index]*100/tag.max)+"%"; hovering =true; hoverLabel(label,mouse,text,style); }else{ hovering =false; removeLabel(label); } })) }
至于調用,那就簡單了
第一步: var ele = document.getElementById("chart"); var draw = echarts.init(ele); 第二步: 配置你的option var option ={}; 第三步畫出你的雷達圖 draw.setOption(option); 第四步:綁定事件: addHover(ele,option,{autoShow:true,hoverEnable:true});
至此,我們就 完全解決了Echarts單軸輪播問題。
如果你嫌上面太瑣碎,可以直接取github看我的試驗源碼,文件是mouse.html,歡迎star
本文后續:從0開始擼一個支持單軸輪播的雷達圖之末篇
本文首發于:http://closertb.site
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85057.html
摘要:今天要用到的理論在前兩篇都講過,如果你錯過了前兩篇,你應該先看看。但是我們可否用生成一個圖,自己為其寫一個呢答案是肯定的。但一切的一切前提是,要支持單軸輪播,這個圖只有一個系列。 今天要用到的理論在前兩篇都講過,如果你錯過了前兩篇,你應該先看看。從0開始寫一個支持單軸輪播的雷達圖之首篇從0開始寫一個支持單軸輪播的雷達圖之中篇 前言 通過前面我們自己實現了一個Radar圖,并對其實現了單...
摘要:引子最近做公司的數據展示項目,用的核心插件是,但在雷達圖的展示案列上,需求上出現了需要單軸輪播標簽和數據,在看完上的后,這個不支持,看了一下源碼,似乎有點復雜,改了改,只實現了多個的輪播,和需求還是有差距,周末反正無聊,何不自己動手擼一個。 引子 最近做公司的數據展示項目,用的核心插件是Echarts,但在雷達圖的展示案列上,需求上出現了需要單軸輪播標簽和數據,在看完github上的i...
摘要:以上三種動態樣式注入,不同的使用場景,各有利弊,至于你想用哪一種,需要你自己權衡,睡覺去啦。。。。 前言 作為一個前端,我們都聽過結構,樣式,行為分離;關于樣式,我們都聽過外聯樣式,內聯樣式和行內樣式;關于這三者,什么權重啊,啊,對了,這些都不會出現在這篇文章里,這篇文章就說一些那些我們不怎么使用的,動態引入css樣式的方法; 靜態樣式引入 前面說過外聯樣式,內聯樣式和行內樣式,所謂外...
摘要:其次父組件中負責通用的功能,以及輪播的整體架構,其結構如下。下面的是一種移動端的適配方案。接下來實現函數運用動畫切換到指定下標的子項到此為止,咱們就已經完成了一個初步的滑動切換輪播圖的功能了。 前言 昨天寫了一篇側邊菜單組件的文章,閱讀人數挺多的,內心很欣喜(偷著樂,第一篇文章有這么多人看)!乘著這股勁,今天在繼續寫一篇我們平時工作中更常用的滑動輪播組件的文章。 效果展示 老規矩,咱們...
閱讀 3196·2021-11-18 10:02
閱讀 1446·2021-10-12 10:08
閱讀 1239·2021-10-11 10:58
閱讀 1269·2021-10-11 10:57
閱讀 1167·2021-10-08 10:04
閱讀 2121·2021-09-29 09:35
閱讀 773·2021-09-22 15:44
閱讀 1269·2021-09-03 10:30