因爲微信小程序自己框架的限制,很難集成目前已有的圖表工具,顯示圖表目前有兩種方案:
一、服務器端渲染圖表,輸出圖片,微信小程序中直接顯示渲染好的圖片,好比highcharts提供了服務端渲染的能力hightcharts server render,這種方式須要後臺有一套渲染服務,而且有必定的網絡開銷。
二、微信小程序API中提供了canvas的支持,利用canvas自行繪製圖表。javascript
下面咱們來看下怎麼在微信小程序中繪製圖表。html
關注個人 github項目 查看完整代碼。html5
查看微信小程序詳細 Canvas API 文檔java
在模板文件中使用<canvas></canvas>
聲明一個canvas組件git
使用wx.createContext
獲取繪圖上下文 contextgithub
調用wx.drawCanvas進行繪製canvas
wx.drawCanvas({ canvasId: 'firstCanvas', actions: context.getActions() // 獲取繪圖動做數組 });
// 獲取繪圖上下文 context var context = wx.createContext(); // 設置描邊顏色 context.setStrokeStyle("#7cb5ec"); // 設置線寬 context.setLineWidth(4); context.moveTo(50, 70); context.lineTo(150, 150); context.lineTo(250, 30); context.lineTo(350, 120); context.lineTo(450, 150); context.lineTo(550, 95); // 對當前路徑進行描邊 context.stroke(); wx.drawCanvas({ canvasId: 'testCanvas', actions: context.getActions() });
說明:moveTo
方法不記錄到路徑中小程序
效果圖:segmentfault
好像沒有想象中難,看上去效果還不錯微信小程序
... context.beginPath(); // 設置描邊顏色 context.setStrokeStyle("#ffffff"); // 設置填充顏色 context.setFillStyle("#7cb5ec"); context.moveTo(50 + 7, 70); // 繪製圓形區域 context.arc(50, 70, 8, 0, 2 * Math.PI, false); context.moveTo(150 + 7, 150); context.arc(150, 150, 8, 0, 2 * Math.PI, false); ... context.closePath(); // 填充路徑 context.fill(); context.stroke();
效果圖:
說明:避免以前繪製的折線路徑影響到標識圖案的路徑,這裏包裹在了beginPath
和closePath
中
規定咱們的參數格式是這樣的
opts = { width: 640, // 畫布區域寬度 height: 400, // 畫布區域高度 categories: ['2016-08', '2016-09', '2016-10', '2016-11', '2016-12', '2017'] }
咱們根據參數中的categories
來繪製橫座標
稍微整理下思路:
一、根據categories
數均分畫布寬度
二、計算出橫座標中每一個分類的起始點
三、繪製文案(這兒會多一些代碼,後面會具體提到)
var eachSpacing = Math.floor(opts.width / opts.categories.length); var points = []; // 起始點x座標 var startX = 0; // 起始點y座標 var startY = opts.height - 30; // 終點x座標 var endX = opts.width; // 終點y座標 var endY = opts.height; // 計算每一個分類的起始點x座標 opts.categories.forEach(function(item, index) { points.push(startX + index * eachSpacing); }); points.push(endX); // 繪製橫座標 context.beginPath(); context.setStrokeStyle("#cccccc"); context.setLineWidth(1); // 繪製座標軸橫線 context.moveTo(startX, startY); context.lineTo(endX, startY); // 繪製座標軸各區塊豎線 points.forEach(function(item, index) { context.moveTo(item, startY); context.lineTo(item, endY); }); context.closePath(); context.stroke(); context.beginPath(); // 設置字體大小 context.setFontSize(20); // 設置字體填充顏色 context.setFillStyle('#666666'); opts.categories.forEach(function(item, index) { context.fillText(item, points[index], startY + 28); }); context.closePath(); context.stroke();
效果圖:
效果不錯,除了文字沒有居中.......
查看微信小程序官方提供的文檔並無提供html5 canvas
中的mesureText
(獲取文案寬度)方法,下面咱們本身簡單的實現,並非絕對精確,可是偏差基本能夠忽略
function mesureText (text) { var text = text.split(''); var width = 0; text.forEach(function(item) { if (/[a-zA-Z]/.test(item)) { width += 14; } else if (/[0-9]/.test(item)) { width += 11; } else if (/\./.test(item)) { width += 5.4; } else if (/-/.test(item)) { width += 6.5; } else if (/[\u4e00-\u9fa5]/.test(item)) { width += 20; } }); return width; }
這裏分別處理了字母
, 數字
, .
, -
, 漢字
這幾個經常使用字符
上面的代碼稍微修改下:
opts.categories.forEach(function(item, index) { var offset = eachSpacing / 2 - mesureText(item) / 2; context.fillText(item, points[index] + offset, startY + 28); });
大功告成!
如何在折線上繪製出每一個數據點的數值文案你們能夠動手本身實現下
預告:下一部分咱們一塊兒討論如何根據真實的數據繪製折線以及若是肯定縱座標的範圍和縱座標分區的問題。