摘要:引子最近做公司的數據展示項目,用的核心插件是,但在雷達圖的展示案列上,需求上出現了需要單軸輪播標簽和數據,在看完上的后,這個不支持,看了一下源碼,似乎有點復雜,改了改,只實現了多個的輪播,和需求還是有差距,周末反正無聊,何不自己動手擼一個。
引子
最近做公司的數據展示項目,用的核心插件是Echarts,但在雷達圖的展示案列上,需求上出現了需要單軸輪播標簽和數據,在看完github上的issue后,這個Echarts3不支持,看了一下源碼,似乎有點復雜,改了改,只實現了多個series的輪播,和需求還是有差距,周末反正無聊,何不自己動手擼一個。
整理一下思路想實現如上圖這樣一個建議雷達圖,需要幾步?個人總結,需要:
初始化一個canvas對象;
以畫布中心,繪制三個同心圓;
根據輸入的點數,計算3根軸在外徑圓上的6個坐標點,并以中心點,繪制6根軸線;
根據輸入的標簽,集合前面6個坐標點,完成6個標簽在畫布的繪制;
根據輸入的數據,結合前面的6個坐標,計算得輸入數據的坐標點,連線完成輸入數據展示;
要實現輪播,主要解決的就是根據輸入數據坐標點計算此點在Dom元素的位置,然后輪播顯示;
如果想觸發echarts那種hover tooltip的效果,你只需要添加一個mousemove事件,獲取位置,并計算其相對應的坐標點。
好像要達到的效果就完成了,似乎不難,來吧,實現它。
分布實現 初始化一塊畫布首先引入一個canvas函數,并為其制定長高,然后獲取這個元素,并得到一塊平面畫布,代碼如下:
const draw = document.getElementById("canvas"); const ctx = draw.getContext("2d");
為了后面更方便的計算,我們需要把坐標原點從畫布的右上角移到畫布的中心,所以我們首先獲取畫布的長寬,接著使用translate方法,轉移坐標原點
const offset = { x:draw.offsetWidth, y:draw.offsetHeight }; ctx.translate(offset.x/2,offset.y/2);
這樣我們就初始化了一塊畫布,并將其坐標原點移到了畫布的中心.
這里提示兩點:
添加canvas為其指定寬高時,需要用width和height屬性直接指定,而不能用style的寬高指定其寬高,如果是樣式指定,畫出來的線或圓是模糊且變形的;
雖然上面變換了坐標原點,但是canvas坐標系默認是向下,向右為正,所以我們改變了坐標原點,但這個特點并未改變,所以像(0,120)這個點是位于坐標原點正下方的,而非通常我們認知的正上方;
畫同心圓在echarts中,圓的個數可通過splitNum配置,其實這個實現也不難,可通過下面的代碼實現:
const m = Math; const PI = m.PI;//這兩個參數后面經常會用,這里提前簡單申明 /* 輸入參數 *ctx 畫布 * radius 要畫的最外層圓的半徑 * spiltNum 要畫的圓的個數 * */ function drawArc(ctx,radius,splitNum){ ctx.beginPath(); //開始畫路徑 /*這個可通過stokeColor與fillColor設置圓邊的顏色和圓的填充色*/ const splitStep =radius/splitNum; for(let i=1;i<=splitNum;i++){ //按splitNum個數,計算并畫出相應的圓 ctx.moveTo(i*splitStep,0); //這一句很重要,你需要手動移動你的畫筆,而不是任其在畫布上連續移動,畫出不應該出現的線; ctx.arc(0,0,i*splitStep,0,2*PI,false); } ctx.stroke(); } drawArc(ctx,raduis,3);
這一步就提示一點:
ctx.beginPath()與ctx.stroke();總是成對成對出現,缺一個,這線必須出不來。
首先回憶一個高中數學知識,已知一個圓的大小,其一條線與O度角直徑成x度角,求其這條線沿Y軸正方向與圓的交點,好難,有沒有,久了不摸,知識瞬間回到幼兒園,答案是:(r*sin(x),r.cos(x)),答案怎么這么簡單,不信,不信你可以用三個和四個點驗證,我會說我就干過這事嘛。好了,進入正題,直接上函數,順便說一句,我們在計算這個點的同時,也可以把標簽的坐標點也一起算出來,直接上代碼:
let l = 6; //極坐標點的個數,也急速雷達的維度個數; const single = 2*PI /l ;//計算偏轉角度; let pointData=[],labelData=[];//聲明兩個數組,用于存儲計算所得的坐標點; for(let i = 0;i點計算好了,接下來我們需要連接每個點到圓心得連線
/*輸入畫布,和要連接的點*/ function drawLine(ctx,data){ ctx.beginPath(); ctx.strokeStyle = "blue"; for(let i= 0;i提示:其實繪制這幾根極坐標也可以采用坐標變換rotate API來執行,比如這樣
rotate(single); ctx.lingeTo(0,r);這樣也很簡單,但為了后面,我們需要知道這些極坐標也圓的交點,這在后面會很有用,但不得否認canvas的translate和retate是兩個很好用的方法.
根據前面標簽的計算點,繪制標簽canvas文字繪制,涉及到的屬性和方法有font(設置字體樣式),textAlign(設置左右對齊),textBaseline(設置基線,上下對齊),fillText(文字繪制)直接上代碼:
let label= ["衛生","安全","交通","住宿","景點","吃88喝"]; for(let i = 0;i=-1)&&(x<=1)){ //由于single值的問題,所以很多時候沒有x=0的出現,都是0.000001這種浮點數出現; ctx.textAlign ="center"; }else if(x>1){ ctx.textAlign ="left"; }else{ ctx.textAlign ="right"; } ctx.fillText(data[i].label,...data[i].position); } } drawText(ctx,label); 提示:strokeText與fillText都可以為文本描邊,但strokeText使用效果更好;另外使用fillText時,是使用fillStyle為文字設置顏色屬性,而strokeText是采用strokeStyle設置文字顏色屬性,很重要
根據輸入的點,繪制雷達閉合區域其實這一步也相當簡單,就是根據點計算在響應極坐標上的落點,然后一一連線,然后為封閉區域著色,直接上代碼:
let data = [120,50,150,80,100,140]; for(let i = 0;i也許拐點區域特殊處理,更有味道 Echarts怎么做的,Echarts可以配置拐點樣式,那我們也為我們的雷達圖加上拐點吧。
如果你想用繪制一個線,并根據拐點圓的大小和切入角度,然后計算出這條線的長度,再繪制這個拐點,然后再接著畫線,這樣真的很難,有沒有簡單點的,有,就是投機取巧,繪完線后再繪制拐點,并將這個拐點圓填充,這樣看起來就像是我們連著畫的啦,但這樣也有bug,如果我們沒有填充顏色,或者填充的顏色有透明度,那么拐點下兩條線相交就可見了,我們的連續繪制假象也就被自己拆穿了。還是上代碼把:function drawPoint(ctx,data) { const max = data.length; const r= 3; ctx.fillStyle="white"; //rgba(10,50,200,0.5) ctx.beginPath(); for(let i=0;i至此,我們基礎的圖形就畫完了,現在我們要做最重要的一步,也就是輪播了。
做一個簡單的自動輪播還是直接上代碼吧,下一篇文章再詳說:
let step =-1; function removeLabel(dom) { (dom.querySelectorAll("label").length)&&(dom.removeChild(dom.querySelector("label"))); } function autoLabel(point){ removeLabel(); let label =document.createElement("label"); label.innerHTML ="show:0999"; //這里先寫成定值,后面會詳述怎樣定制輪播值 label.style.position="absolute"; label.style.top=point[1]+offset.y/2 +"px"; label.style.left=point[0]+offset.x/2+"px" ; label.style.border="1px solid yellowgreen"; label.style.background = "gray"; label.style.opacity = "0.5" label.style.zIndex = 999; dom.appendChild(label); } setInterval(function(){ step = (step+1)%6; autoLabel(draw,pointData[step]); },1000)好了,至此我們就簡單的實現了一個暫時沒法定制的雷達輪播圖,在下一篇文章我們將會根據這里提到的思想,開發一個與簡易版的echarts radar插件。
如果發現有任何敘述不正確之處或有更好的想法,還請指正。
源碼地址本文系列:
從0開始擼一個支持單軸輪播的雷達圖(Ehcarts的單軸顯示問題)之中篇
從0開始擼一個支持單軸輪播的雷達圖(Ehcarts的單軸顯示問題)之末篇
本文首發于:http://closertb.site ,轉載請注明
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/84897.html
摘要:如果你嫌上面太瑣碎,可以直接取看我的試驗源碼,文件是歡迎本文后續從開始擼一個支持單軸輪播的雷達圖之末篇本文首發于 在線示例如果你還不了解canvas,還不知道要講啥,建議從首篇看起:從0開始寫一個支持單軸輪播的雷達圖在首篇我們已經講了怎么實現輪播,在這里我們將要用這一篇文章來說一下雷達圖的單軸hover效果的實現,也是我寫這篇文章的原因,因為echarts只支持單個series的hov...
摘要:今天要用到的理論在前兩篇都講過,如果你錯過了前兩篇,你應該先看看。但是我們可否用生成一個圖,自己為其寫一個呢答案是肯定的。但一切的一切前提是,要支持單軸輪播,這個圖只有一個系列。 今天要用到的理論在前兩篇都講過,如果你錯過了前兩篇,你應該先看看。從0開始寫一個支持單軸輪播的雷達圖之首篇從0開始寫一個支持單軸輪播的雷達圖之中篇 前言 通過前面我們自己實現了一個Radar圖,并對其實現了單...
摘要:科普動量是守恒量。動量守恒定律表示為一個系統不受外力或者所受外力之和為零,這個系統中所有物體的總動量保持不變。動量守恒定律可由機械能對空間平移對稱性推出。在可以忽略碰撞以外的因素時,動量是守恒的。 前言 一路沿著本系列教程學習的朋友可能會發現,前面教程中都盡量避免提及質量的概念,很多運動概念也時刻提醒大家這不是真實的物體運動。因為真實的物體運動其實跟質量都是密不可分的,而且質量的引入自...
摘要:科普動量是守恒量。動量守恒定律表示為一個系統不受外力或者所受外力之和為零,這個系統中所有物體的總動量保持不變。動量守恒定律可由機械能對空間平移對稱性推出。在可以忽略碰撞以外的因素時,動量是守恒的。 前言 一路沿著本系列教程學習的朋友可能會發現,前面教程中都盡量避免提及質量的概念,很多運動概念也時刻提醒大家這不是真實的物體運動。因為真實的物體運動其實跟質量都是密不可分的,而且質量的引入自...
閱讀 813·2023-04-25 22:57
閱讀 3062·2021-11-23 10:03
閱讀 624·2021-11-22 15:24
閱讀 3169·2021-11-02 14:47
閱讀 2912·2021-09-10 11:23
閱讀 3130·2021-09-06 15:00
閱讀 3953·2019-08-30 15:56
閱讀 3337·2019-08-30 15:52