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