有這么個(gè)折線圖,如下所示
應(yīng)該怎么去實(shí)現(xiàn)它呢丧没,我在這個(gè)demo中分了兩步们拙,分別為畫(huà)坐標(biāo)軸和畫(huà)折線圖
1.畫(huà)坐標(biāo)圖
坐標(biāo)分為縱坐標(biāo)和橫坐標(biāo),我們先來(lái)定義一下坐標(biāo)原點(diǎn)劫瞳,默認(rèn)情況下倘潜,坐標(biāo)原點(diǎn)位于canvas的左上角,即(0志于,0)的位置涮因,如果我們以這個(gè)點(diǎn)來(lái)畫(huà)坐標(biāo),其實(shí)也可以伺绽,但是不太符合我們一般的邏輯思維蕊退,一般我們都是從左下角開(kāi)始畫(huà),所以我們需要通過(guò)使用translate變換坐標(biāo)的原點(diǎn)憔恳,如下
ctx.translate(40, 500)
把坐標(biāo)原點(diǎn)移到了距左40px的地方瓤荔,距頂500px的地方,然后我們?cè)購(gòu)倪@個(gè)點(diǎn)開(kāi)始畫(huà)钥组,首先输硝,畫(huà)出縱坐標(biāo),此時(shí)只需要把畫(huà)筆移到當(dāng)前坐標(biāo)的(0程梦,0)位置点把,然后向上畫(huà)一條豎線,再畫(huà)一下左邊的箭頭屿附,再畫(huà)一下右邊的箭頭郎逃,即可,代碼如下
// 畫(huà)y軸
ctx.moveTo(0, 0)
ctx.lineTo(0, -yaxisLength)
// y軸左邊箭頭
ctx.moveTo(0, -yaxisLength)
ctx.lineTo(-arrowLength, -(yaxisLength - arrowLength))
// y軸右邊箭頭
ctx.moveTo(0, -yaxisLength)
ctx.lineTo(arrowLength, -(yaxisLength - arrowLength))
接下來(lái)畫(huà)橫坐標(biāo)挺份,原理和畫(huà)縱坐標(biāo)一樣褒翰,直接上代碼吧
// 畫(huà)x軸
ctx.moveTo(0, 0)
ctx.lineTo(xaxisLength, 0)
// x軸上邊箭頭
ctx.moveTo(xaxisLength, 0)
ctx.lineTo(xaxisLength - arrowLength, -arrowLength)
// x軸下邊箭頭
ctx.moveTo(xaxisLength, 0)
ctx.lineTo(xaxisLength - arrowLength, arrowLength)
ctx.stroke()
這樣就把坐標(biāo)畫(huà)好了,接下來(lái)我們畫(huà)折線
2.畫(huà)折線
首先匀泊,我們需要數(shù)據(jù)优训,定義了一個(gè)簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)
var data = [{
value: 120,
title: '第一季度'
},
{
value: 50,
title: '第二季度'
},
{
value: 100,
title: '第三季度'
},
{
value: 60,
title: '第四季度'
}
]
data.unshift({
value: 0,
title: ''
})
如果組件化了,用戶(hù)肯定是傳的有效數(shù)據(jù)各聘,我在第一項(xiàng)加了個(gè)0的值揣非,也僅僅是為了邏輯處理,此處不用在乎躲因,接下來(lái)早敬,肯定是要遍歷這個(gè)數(shù)組忌傻,然后畫(huà)出折線,這里簡(jiǎn)單的處理就是搞监,每次畫(huà)筆移到上一次點(diǎn)的位置芯勘,然后再畫(huà)一條線到當(dāng)前位置即可,還是上源碼
ctx.font = '20px Arial'
for (var i = 1, len = data.length; i < len; i++) {
ctx.moveTo(interval * (i - 1), -data[i - 1].value)
ctx.lineTo(interval * i, -data[i].value)
var y = -data[i].value - 20
if (i != len - 1 && data[i].value < data[i + 1].value) {
y = -data[i].value + 20
}
ctx.fillText(`${data[i].title}(${data[i].value})`, interval * i - 20, y)
}
ctx.stroke()
這樣就簡(jiǎn)單地實(shí)現(xiàn)了一個(gè)折線圖腺逛,但是實(shí)際中肯定不止這么簡(jiǎn)單荷愕,肯定要炫,這里暫時(shí)就不展開(kāi)了棍矛,可以關(guān)注我的github安疗,代碼會(huì)不定期更新
qa:假如要給線條加上顏色,應(yīng)該怎么實(shí)現(xiàn)呢够委,就像下面這樣