微信小程序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;
}