微信小程序Canvs画数据表格 折线图


微信小程序Canvs画数据表格


应设计要求,需要画个图标来显示用户历史数据的变化,所以就写了个方法,方便自己以后用的时候调用


废话不多说,先上效果图


微信小程序Canvs画数据表格 折线图_第1张图片

现在.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;
}

你可能感兴趣的:(微信小程序)