微信小程式Canvs畫資料表格 折線圖
阿新 • • 發佈:2018-11-19
微信小程式Canvs畫資料表格
應設計要求,需要畫個圖示來顯示使用者歷史資料的變化,所以就寫了個方法,方便自己以後用的時候呼叫
廢話不多說,先上效果圖
現在.wxml檔案中加入canvas 標籤 給他一個canvas-id屬性,js中獲取上下文物件的標識
<canvas canvas-id="{{id}}"></canvas>
在.wxml檔案中加入標籤,給它id屬性即可
下面是js程式碼,傳入一個data資料,裡面應該包含canvs的id,和要換圖的資料,我的邏輯是,根據傳入的資料,對其先進行排序,然後分別得到x軸、y軸的屬性資料最大值與最小值,用最大值減去最小值就是當前軸的總的資料長度,在用座標算的當前軸的總長度,用長度除以資料總長度,就可以獲得單位長度,即單位資料值對應的座標長度,然後座標值就應為當前的資料值乘以單位長度,然後連線就可完成
主方法:
/**
* 畫圖表
*/
function createCanvs(canvsData,screenSize){
const rectWidth = screenSize.width * 0.94 * 0.82;
const rectHeight = screenSize.height * 0.2;
const ctx = wx.createCanvasContext(canvsData.id); //建立畫布上下文物件
const grd = ctx.createLinearGradient(0, 0, 200, 0) //建立線性漸變物件
const yoffset = 5 ; //y軸偏移量
const xoffset = 20; //x軸偏移量
var Datainfo = [];
var xMax = 100;
var xMin = 0;
var yMax = 100;
var yMin = 0;
//獲取資料的最大最小值
var xinfo = getMaxMininfo(canvsData.data,"time",0);
var yinfo = getMaxMininfo(canvsData.data, "value", 0);
xMax = parseInt (xinfo.max);
xMin = parseInt(xinfo.min);
yMax = parseInt(yinfo.max);
yMin = parseInt(yinfo.min);
grd.addColorStop(0, '#F780A1');
grd.addColorStop(0.8, '#F1CA5B');
grd.addColorStop(1, '#6CB78B');
ctx.setStrokeStyle("#E5E5E5"); //設定顏色值
ctx.strokeRect(xoffset, yoffset, rectWidth, rectHeight);
//畫橫線
for(var i = 0;i < 6;i++){
ctx.beginPath();
ctx.moveTo(xoffset, rectHeight / 7 * (i + 1) + yoffset);
ctx.lineTo(rectWidth + xoffset, rectHeight / 7 * (i + 1) + yoffset);
ctx.stroke();
}
//畫豎線
for (var i = 0; i < 19; i++) {
ctx.beginPath();
ctx.moveTo(rectWidth / 20 * (i + 1) + xoffset, yoffset);
ctx.lineTo(rectWidth / 20 * (i + 1) + xoffset, rectHeight + yoffset);
ctx.stroke();
}
//畫資料
ctx.setStrokeStyle(grd); //切換為紅色劃線
ctx.setLineWidth(3);
//畫橫座標顯示文字
ctx.setFontSize(10); //設定字號
for(var i = 0; i < 4;i++){
ctx.fillText((yMin + i * 2 * (yMax - yMin) / 7).toFixed(0), 5, rectHeight + yoffset - i * 2 * rectHeight / 7);
}
//計算橫縱座標單位長度
var xUnit = rectWidth / (xMax - xMin);
var yUnit = rectHeight/ (yMax - yMin);
if (typeof canvsData.data[0] != undefined){
//開始畫路徑
//按照time元素從小到大排序
canvsData.data.sort(function(a,b){
return a.time-b.time;
});
ctx.beginPath();
//遍歷資料來源
for (var x in canvsData.data) {
let xgo = xUnit * (canvsData.data[x].time - xMin) + xoffset;
let ygo = rectHeight - yUnit * (canvsData.data[x].value - yMin) + yoffset;
if(x == 0){
ctx.moveTo(xgo, ygo);
}else{
ctx.lineTo(xgo, ygo);
}
Datainfo[x]={
"xgo": xgo,
"ygo": ygo
};
}
ctx.stroke();
for (var l in Datainfo){
//畫外圓
ctx.beginPath();
ctx.arc(Datainfo[l].xgo, Datainfo[l].ygo, 4, 0, 2 * Math.PI);
ctx.setFillStyle("#FF4D59");
ctx.stroke();
//畫內圓
ctx.beginPath();
ctx.setFillStyle("#fff");
ctx.arc(Datainfo[l].xgo, Datainfo[l].ygo, 2, 0, 2 * Math.PI);
ctx.fill();
}
}
ctx.draw();
}
獲取對應元素最大值及最小值方法:
/**
* 獲取最大值最小值
*/
function getMaxMininfo(arry,element,offset){
var info = {
max:0,
min:0
};
for(var x in arry){
if(x == 0){
info.max = arry[x][element];
info.min = arry[x][element];
}
if(info.max < arry[x][element]){
info.max = arry[x][element];
}
if(info.min > arry[x][element]){
info.min = arry[x][element];
}
}
info.max = parseInt(info.max) + offset;
info.min = parseInt(info.min) - offset;
if (info.min < 0){
info.min = 0;
}
return info;
}