小程序-Canvas繪製折線圖

小程序-Canvas繪製折線圖

自己在一個小程序項目中,希望通過繪製折線圖展示不同時間的數值變化趨勢,搜索了一番後沒找到特別好的第三方庫,故打算自己實現一個簡單的繪製折線圖方法,本文記錄自己如何在小程序中通過canvas繪製折線圖。

目標

最終目標是達到官方小程序數據助手中折線圖的效果:

除了UI目標外,還要便於在小程序其他地方使用或者在其他小程序中使用,所以API要有適當的通用性。

實現

實現的思路是在頁面上放置指定大小的canvas,然後調用API傳遞’canvas id’與配置選項完成繪製,配置選項主要用來指定繪製數據、有關顏色、繪製大小等,繪製的API可以封裝到一個單獨的模塊中便於公用。

接口

暫時設計了4個接口:init、draw、showLine、hideLine,分別用來初始化、繪製、顯示和隱藏某條線,具體API描述如下所示:

  • init(ctx: string|CanvasContext, options: object): LineChart

init,返回一個LineChart實例,可以調用LineChart原型上的三個方法,其中:

  • ctx: 'canvas id’或通過wx.createCanvasContext得到的CanvasContext對象
  • options:
{
    width: 320,                     // canvas的寬度
    height: 200,                    // canvas的高度
    labelColor: '#888888',          // label的顏色
    axisColor: '#d0d0d0',           // 軸的顏色
    xUnit: '',                      // x軸label的單位
    yUnit: '',                      // y軸label的單位
    xAxis: [1, 2, 3, 4],            // x軸label數組
    lines: [{                       // 需要繪製的線
        color: '#1296db',           // 線的顏色
        points: [10, 29, 18, 20],   // 線的y軸值
    }],                     
    margin: 20,                     // 內容與邊界的距離
    fontSize: 12                    // 文字大小
}
  • LineChart.prototype.draw()

draw,按初始化給定的ctx和options繪製折線圖

  • LineChart.prototype.showLine(index: number)

showLine,顯示options.lines[index]中的該條線

  • LineChart.prototype.hideLine(index: number)

hideLine,隱藏options.lines[index]中的該條線

代碼

完整代碼移步Github,這裏只描述一下自己用canvas繪製折線圖的主要思路:

  • 繪製x軸與label

繪製x軸相對簡單,但所有x軸label都繪製可能導致空間不一夠,所以這裏要依據label數量與寬度計算能夠繪製的個數,然後按等步長的方式從中挑選。同時因爲ctx.fillText的繪製位置是從左上角計算,爲避免溢出,x軸label繪製位置在x軸方向要有適當的偏移

  • 繪製y軸label以及水平標度線

y軸label數可以根據cavans高度與希望的標度線間距計算,而每條水平標度線的取值則需要考慮options.lines在y軸的最大值。數量與取值決定後,繪製就相對容易

  • 繪製線

繪製軸與label需要收集4個信息:xOffset、yOffset、xStep、yStep,分別表示原點的偏移量(座標)和單位步長,此時線上的點:(index, value)對應到的canvas中座標爲:(xOffset + index * xStep, yOffset - value * yStep),最後再使用ctx.moveTo結合ctx.lineTo將所有點連起來即可

  • 繪製線與x軸的陰影面積

將需要繪製的區域連接成一個閉合區域再使用ctx.fill填充即可,在繪製線的起點前添加其在x軸的投影點作爲新起點,以及在繪製線的終點後添加其在x軸的投影點作爲新終點,最後使用ctx.closePath串聯起來並fill

  • 繪製空心數據點

在每個點的位置使用ctx.arc繪製

繪製效果

最後通過LineChart繪製出來的折線圖效果如下:

總結

目前的折線圖還差一個重要的交互功能:“根據觸摸位置,顯示臨近點的y軸取值”,這個功能晚點補上。

博客原文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章