Use applet to realize charts (pie chart, column chart, line chart)

1. Introduction to the article

This article mainly implements the display of data through various charts on the applet to increase the user experience.

2. Preparation before development

2.1. Download and install WeChat Web Developer Tools.
2.2. Prepare JSON data for interface display.

3. Development steps

1. Line chart

insert image description here
3.1. Open the WeChat developer tool, create a new project, and choose not to use templates or cloud services.
insert image description here
3.2. Create a folder under the pages folder and create a new corresponding page file.
insert image description here

3.3. Create a new JS file in the utils folder and define the corresponding function. The function is to define the initial height and width of the canvas when onLoad.

/*
注意,使用前需要初始化(传入系统宽度值)
  示例:
  onLoad: function () {
    var that = this;
    wx.getSystemInfo({
      success: function (res) {
        dimen.init(res.windowWidth);
        canvasWidth = dimen.rpx2px(710); // 必须在初始化后在使用这些函数方法,不然用下列函数算出的值都是错的
        canvasHeight = dimen.rpx2px(400);
      }
    });
  }
*/

var width = 375;
var r = 0.5;  // 比率

function init(w) {
    
    
    width = w;
    r = width / 750.0;
}

function px2rpx(px) {
    
    
    var rpx = px / r;
    return rpx;
}

function rpx2px(rpx) {
    
    
    var px = rpx * r;
    return px;
}

module.exports = {
    
    
    init: init,
    px2rpx: px2rpx,
    rpx2px: rpx2px
}

3.4. At present, it is only for testing and has not yet accessed the API, so a JS is defined again to store the displayed JSON data.
insert image description here

var visitTrend = [
  {
    
    
    "ref_date": "20170701",
    "session_cnt": 8,
    "visit_pv": 49,
    "visit_uv": 4,
    "visit_uv_new": 1,
    "stay_time_uv": 73.75,
    "stay_time_session": 36.875,
    "visit_depth": 3.25
  },
  {
    
    
    "ref_date": "20170702",
    "session_cnt": 10,
    "visit_pv": 81,
    "visit_uv": 8,
    "visit_uv_new": 2,
    "stay_time_uv": 351.25,
    "stay_time_session": 281,
    "visit_depth": 3.5
  },
  {
    
    
    "ref_date": "20170703",
    "session_cnt": 17,
    "visit_pv": 58,
    "visit_uv": 10,
    "visit_uv_new": 4,
    "stay_time_uv": 187.3,
    "stay_time_session": 110.1765,
    "visit_depth": 2.4706
  },
  {
    
    
    "ref_date": "20170704",
    "session_cnt": 2,
    "visit_pv": 6,
    "visit_uv": 2,
    "visit_uv_new": 0,
    "stay_time_uv": 17.5,
    "stay_time_session": 17.5,
    "visit_depth": 3
  },
  {
    
    
    "ref_date": "20170705",
    "session_cnt": 9,
    "visit_pv": 78,
    "visit_uv": 5,
    "visit_uv_new": 2,
    "stay_time_uv": 90.2,
    "stay_time_session": 50.1111,
    "visit_depth": 4.6667
  },
  {
    
    
    "ref_date": "20170706",
    "session_cnt": 21,
    "visit_pv": 155,
    "visit_uv": 10,
    "visit_uv_new": 4,
    "stay_time_uv": 173.8,
    "stay_time_session": 82.7619,
    "visit_depth": 3.4286
  },
  {
    
    
    "ref_date": "20170707",
    "session_cnt": 17,
    "visit_pv": 118,
    "visit_uv": 11,
    "visit_uv_new": 4,
    "stay_time_uv": 67.7273,
    "stay_time_session": 43.8235,
    "visit_depth": 3.8824
  },
  {
    
    
    "ref_date": "20170708",
    "session_cnt": 32,
    "visit_pv": 197,
    "visit_uv": 18,
    "visit_uv_new": 10,
    "stay_time_uv": 90.7222,
    "stay_time_session": 51.0313,
    "visit_depth": 3.5313
  },
  {
    
    
    "ref_date": "20170709",
    "session_cnt": 25,
    "visit_pv": 138,
    "visit_uv": 11,
    "visit_uv_new": 6,
    "stay_time_uv": 80.8182,
    "stay_time_session": 35.56,
    "visit_depth": 3.64
  },
  {
    
    
    "ref_date": "20170710",
    "session_cnt": 20,
    "visit_pv": 141,
    "visit_uv": 13,
    "visit_uv_new": 4,
    "stay_time_uv": 270.5385,
    "stay_time_session": 175.85,
    "visit_depth": 3.3
  },
  {
    
    
    "ref_date": "20170711",
    "session_cnt": 11,
    "visit_pv": 116,
    "visit_uv": 9,
    "visit_uv_new": 3,
    "stay_time_uv": 116.8889,
    "stay_time_session": 95.6364,
    "visit_depth": 4.6364
  },
  {
    
    
    "ref_date": "20170712",
    "session_cnt": 12,
    "visit_pv": 90,
    "visit_uv": 7,
    "visit_uv_new": 2,
    "stay_time_uv": 122,
    "stay_time_session": 71.1667,
    "visit_depth": 3
  },
  {
    
    
    "ref_date": "20170713",
    "session_cnt": 27,
    "visit_pv": 214,
    "visit_uv": 12,
    "visit_uv_new": 5,
    "stay_time_uv": 72,
    "stay_time_session": 32,
    "visit_depth": 4.2593
  },
  {
    
    
    "ref_date": "20170714",
    "session_cnt": 73,
    "visit_pv": 627,
    "visit_uv": 29,
    "visit_uv_new": 23,
    "stay_time_uv": 123.2759,
    "stay_time_session": 48.9726,
    "visit_depth": 4.0959
  },
  {
    
    
    "ref_date": "20170715",
    "session_cnt": 48,
    "visit_pv": 394,
    "visit_uv": 18,
    "visit_uv_new": 11,
    "stay_time_uv": 139.7222,
    "stay_time_session": 52.3958,
    "visit_depth": 3.75
  },
  {
    
    
    "ref_date": "20170716",
    "session_cnt": 34,
    "visit_pv": 289,
    "visit_uv": 18,
    "visit_uv_new": 9,
    "stay_time_uv": 91.2222,
    "stay_time_session": 48.2941,
    "visit_depth": 4.3529
  },
  {
    
    
    "ref_date": "20170717",
    "session_cnt": 55,
    "visit_pv": 595,
    "visit_uv": 24,
    "visit_uv_new": 16,
    "stay_time_uv": 235.8333,
    "stay_time_session": 102.9091,
    "visit_depth": 4.3636
  },
  {
    
    
    "ref_date": "20170718",
    "session_cnt": 18,
    "visit_pv": 82,
    "visit_uv": 12,
    "visit_uv_new": 3,
    "stay_time_uv": 57.3333,
    "stay_time_session": 38.2222,
    "visit_depth": 2.7778
  },
  {
    
    
    "ref_date": "20170719",
    "session_cnt": 57,
    "visit_pv": 413,
    "visit_uv": 20,
    "visit_uv_new": 8,
    "stay_time_uv": 136.4,
    "stay_time_session": 47.8596,
    "visit_depth": 3.8772
  },
  {
    
    
    "ref_date": "20170720",
    "session_cnt": 41,
    "visit_pv": 299,
    "visit_uv": 14,
    "visit_uv_new": 10,
    "stay_time_uv": 103.1429,
    "stay_time_session": 35.2195,
    "visit_depth": 3.5366
  },
  {
    
    
    "ref_date": "20170721",
    "session_cnt": 43,
    "visit_pv": 349,
    "visit_uv": 27,
    "visit_uv_new": 13,
    "stay_time_uv": 80.8519,
    "stay_time_session": 50.7674,
    "visit_depth": 3.6744
  },
  {
    
    
    "ref_date": "20170722",
    "session_cnt": 76,
    "visit_pv": 565,
    "visit_uv": 35,
    "visit_uv_new": 20,
    "stay_time_uv": 76.5429,
    "stay_time_session": 35.25,
    "visit_depth": 3.75
  },
  {
    
    
    "ref_date": "20170723",
    "session_cnt": 75,
    "visit_pv": 509,
    "visit_uv": 34,
    "visit_uv_new": 18,
    "stay_time_uv": 122.6765,
    "stay_time_session": 55.6133,
    "visit_depth": 3.3733
  },
  {
    
    
    "ref_date": "20170724",
    "session_cnt": 74,
    "visit_pv": 552,
    "visit_uv": 34,
    "visit_uv_new": 18,
    "stay_time_uv": 106.5294,
    "stay_time_session": 48.9459,
    "visit_depth": 3.8514
  },
  {
    
    
    "ref_date": "20170725",
    "session_cnt": 33,
    "visit_pv": 348,
    "visit_uv": 21,
    "visit_uv_new": 9,
    "stay_time_uv": 109.9048,
    "stay_time_session": 69.9394,
    "visit_depth": 4.2424
  },
  {
    
    
    "ref_date": "20170726",
    "session_cnt": 93,
    "visit_pv": 663,
    "visit_uv": 27,
    "visit_uv_new": 12,
    "stay_time_uv": 172.9259,
    "stay_time_session": 50.2043,
    "visit_depth": 3.3871
  },
  {
    
    
    "ref_date": "20170727",
    "session_cnt": 117,
    "visit_pv": 900,
    "visit_uv": 44,
    "visit_uv_new": 21,
    "stay_time_uv": 311.5909,
    "stay_time_session": 117.1795,
    "visit_depth": 3.6496
  },
  {
    
    
    "ref_date": "20170728",
    "session_cnt": 83,
    "visit_pv": 566,
    "visit_uv": 41,
    "visit_uv_new": 21,
    "stay_time_uv": 154.9024,
    "stay_time_session": 76.5181,
    "visit_depth": 3.4699
  },
  {
    
    
    "ref_date": "20170729",
    "session_cnt": 109,
    "visit_pv": 786,
    "visit_uv": 52,
    "visit_uv_new": 35,
    "stay_time_uv": 264.5577,
    "stay_time_session": 126.211,
    "visit_depth": 3.4495
  },
  {
    
    
    "ref_date": "20170730",
    "session_cnt": 86,
    "visit_pv": 554,
    "visit_uv": 42,
    "visit_uv_new": 19,
    "stay_time_uv": 80.1667,
    "stay_time_session": 39.1512,
    "visit_depth": 3.0581
  },
  {
    
    
    "ref_date": "20170731",
    "session_cnt": 109,
    "visit_pv": 850,
    "visit_uv": 49,
    "visit_uv_new": 32,
    "stay_time_uv": 95.0408,
    "stay_time_session": 42.7248,
    "visit_depth": 3.6514
  }
]

var visitDistribution = [
  {
    
    
    key: 16,
    value: 175
  },
  {
    
    
    key: 15,
    value: 333
  },
  {
    
    
    key: 14,
    value: 87
  },
  {
    
    
    key: 13,
    value: 67
  },
  {
    
    
    key: 12,
    value: 230
  },
  {
    
    
    key: 11,
    value: 111
  },
  {
    
    
    key: 10,
    value: 99
  },
  {
    
    
    key: 9,
    value: 10
  },
  {
    
    
    key: 8,
    value: 44
  },
  {
    
    
    key: 7,
    value: 33
  },
  {
    
    
    key: 6,
    value: 22
  },
  {
    
    
    key: 4,
    value: 6
  },
  {
    
    
    key: 3,
    value: 322
  },
  {
    
    
    key: 2,
    value: 16
  },
  {
    
    
    key: 1,
    value: 164
  }]

var userPortraitForGender = [
  {
    
    
    id: 0,
    name: "未知",
    ref_date: "20170731",
    value: 1
  },
  {
    
    
    id: 1,
    name: "男",
    ref_date: "20170731",
    value: 14
  },
  {
    
    
    id: 2,
    name: "女",
    ref_date: "20170731",
    value: 6
  }
]

var userPortraitForAge = [
  {
    
    
    id: 0,
    name: "未知",
    ref_date: "20170801",
    value: 1
  },
  {
    
    
    id: 1,
    name: "17岁以下",
    ref_date: "20170801",
    value: 0
  },
  {
    
    
    id: 2,
    name: "18-24岁",
    ref_date: "20170801",
    value: 35
  },
  {
    
    
    id: 3,
    name: "25-29岁",
    ref_date: "20170801",
    value: 32
  },
  {
    
    
    id: 4,
    name: "30-39岁",
    ref_date: "20170801",
    value: 36

  },
  {
    
    
    id: 5,
    name: "40-49岁",
    ref_date: "20170801",
    value: 6
  },
  {
    
    
    id: 6,
    name: "50岁以上",
    ref_date: "20170801",
    value: 4
  }]

module.exports = {
    
    
  visitTrend: visitTrend,
  visitDistribution: visitDistribution,
  userPortraitForGender: userPortraitForGender,
  userPortraitForAge: userPortraitForAge
}

3.5. Go back to the page created at the beginning, and implement the corresponding wxml and wxss to display the data.

<view class="margin-left__20 margin-right__20">
  <view class="margin-top__20 margin-bottom__20 font-size__large">
    <text>30天访问趋势</text>
  </view>
  <view class="flex__row">
    <view class="flex__row align-items__center margin-bottom__20 margin-right__20">
      <view class="width__30 height__30  margin-right__10 radius__30 bord__white bg-color__27A5C2"></view>
      <text>访问人数</text>
    </view>
    <view class="flex__row align-items__center margin-bottom__20">
      <view class="width__30 height__30 margin-right__10 radius__30  bord__white bg-color__1E3A50 "></view>
      <text>新用户数</text>
    </view>
  </view>
  <canvas canvas-id="line-canvas" id="line-canvas"></canvas>
</view>
#line-canvas {
      
      
  width: 710rpx;
  height: 400rpx;
  background: #192429;
}
#navigationBarLine {
      
      
  position: fixed;
  height: 1px;
  top: 0px;
  width: 100%;
  background-color: #e5e5e5;
  z-index: 100;
}

#tabBarLine {
      
      
  position: fixed;
  height: 1px;
  bottom: 0px;
  width: 100%;
  background-color: #e5e5e5;
}

.divider__solid {
    
    
  height: 0;
  border-bottom: 1px solid #e5e5e5;
}

.divider__dashed {
    
    
  height: 0;
  border-bottom: 1px dashed #e5e5e5;
}
.cell-hover {
    
    
  /*background-color: rgba(0, 0, 0, 0.1);*/
  opacity: 0.7;
}

.icon-hover {
    
    
  opacity: 0.7;
}

.hot__article-hover {
    
    
  /*color: #1e6bc4;*/
  opacity: 0.7;
}
.widget__arrow {
    
    
  width: 15rpx;
  height: 26rpx;
  flex-shrink: 0;
  padding-left: 20rpx;
}

.overflow-y__auto {
    
    
  overflow-y: auto;
}

3.6. To implement the corresponding JS, remember to initialize the width and height of the canvas in the onLoad function.

insert image description here

  onLoad: function () {
    
    
    var that = this;
    wx.getSystemInfo({
    
    
      success: function (res) {
    
    
        dimen.init(res.windowWidth);
        canvasWidth_line = dimen.rpx2px(710);    // 折线图的画布宽度
        canvasHeight_line = dimen.rpx2px(400);   // 折线图的画布高度
      }
    });

    this.loadForVisitTrend();
  },
   /* 画访问人数的折线 */
  drawVisitUvLine: function (list, count) {
    
    
    list.forEach(function (data, i, array) {
    
    
      if (data.visit_uv > maxUV) {
    
    
        maxUV = data.visit_uv;
      }
    });

    ratioX = (canvasWidth_line - dimen.rpx2px(30)) / list.length;
    ratioY = (canvasHeight_line - dimen.rpx2px(80)) / maxUV;

    if (count < list.length - 1) {
    
    
      // 当前点坐标
      var currentPoint = {
    
    
        x: count * ratioX + dimen.rpx2px(40),
        y: (canvasHeight_line - list[count].visit_uv * ratioY) - dimen.rpx2px(40)
      };
      // 下一个点坐标
      var nextPoint = {
    
    
        x: (count + dimen.rpx2px(2)) * ratioX + dimen.rpx2px(40),
        y: (canvasHeight_line - list[count + 1].visit_uv * ratioY) - dimen.rpx2px(40)
      }

      // 开始路径
      context_line.beginPath();

      // 画线:移动到当前点
      context_line.moveTo(currentPoint.x, currentPoint.y);
      // 画线:画线到下个点
      context_line.lineTo(nextPoint.x, nextPoint.y);
      // 设置线宽度
      context_line.setLineWidth(dimen.rpx2px(2));
      // 设置线颜色
      context_line.setStrokeStyle('white');
      // 描线
      context_line.stroke();

      // 填充内容:竖直往下,至x轴
      context_line.lineTo(nextPoint.x, canvasHeight_line - dimen.rpx2px(40));
      // 填充内容:水平往左,至上一个点的在x轴的垂点
      context_line.lineTo(currentPoint.x, canvasHeight_line - dimen.rpx2px(40));
      // 设置填充颜色
      context_line.setFillStyle('#27A5C2');

      // 实现闭合与x轴之前的区域
      context_line.fill();
    }
  },
  /* 画访问人数的圆圈 */
  drawVisitUvDot: function (list, count) {
    
    
    if (count < list.length) {
    
    
      // 当前点坐标
      var currentPoint = {
    
    
        x: count * ratioX + dimen.rpx2px(40),
        y: (canvasHeight_line - list[count].visit_uv * ratioY) - dimen.rpx2px(40)
      };

      context_line.beginPath();
      context_line.arc(currentPoint.x, currentPoint.y, 2, 0, 2 * Math.PI);
      context_line.setStrokeStyle('#05DBCE');
      context_line.setFillStyle('white');
      context_line.stroke();
      context_line.fill();
    }
  },
  /* 画新用户数的折线 */
  drawVisitUvnLine: function (list, count) {
    
    
    list.forEach(function (data, i, array) {
    
    
      if (data.visit_uv > maxUV) {
    
    
        maxUV = data.visit_uv_new;
      }
    });

    ratioX = (canvasWidth_line - dimen.rpx2px(30)) / list.length;
    ratioY = (canvasHeight_line - dimen.rpx2px(80)) / maxUV;

    if (count < list.length - 1) {
    
    
      var currentPoint = {
    
    
        x: count * ratioX + dimen.rpx2px(40),
        y: (canvasHeight_line - list[count].visit_uv_new * ratioY) - dimen.rpx2px(40)
      };
      var nextPoint = {
    
    
        x: (count + dimen.rpx2px(2)) * ratioX + dimen.rpx2px(40),
        y: (canvasHeight_line - list[count + 1].visit_uv_new * ratioY) - dimen.rpx2px(40)
      }
      context_line.beginPath();
      context_line.moveTo(currentPoint.x, currentPoint.y);
      context_line.lineTo(nextPoint.x, nextPoint.y);
      context_line.setLineWidth(dimen.rpx2px(2));
      context_line.setStrokeStyle('#1E3A50');
      context_line.stroke();
      context_line.lineTo(nextPoint.x, canvasHeight_line - dimen.rpx2px(40));
      context_line.lineTo(currentPoint.x, canvasHeight_line - dimen.rpx2px(40));
      context_line.setFillStyle('#1E3A50');
      context_line.fill();
    }
  },
  /* 画新用户数的圆点 */
  drawVisitUvnDot: function (list, count) {
    
    
    if (count < list.length) {
    
    
      var currentPoint = {
    
    
        x: count * ratioX + dimen.rpx2px(40),
        y: (canvasHeight_line - list[count].visit_uv_new * ratioY) - dimen.rpx2px(40)
      };
      context_line.beginPath();
      context_line.arc(currentPoint.x, currentPoint.y, 2, 0, 2 * Math.PI);
      context_line.setStrokeStyle('#191970');
      context_line.setFillStyle('white');
      context_line.stroke();
      context_line.fill();
    }
  },
  /* 画横向参照线 */
  drawVisitBackground: function () {
    
    
    var lineCount = 5;
    var estimateRatio = 2;
    var ratio = (canvasHeight_line + dimen.rpx2px(30)) / lineCount;
    var maxPeople = ((Math.floor(Math.floor(148 / 10) / 4) + 1) * 4) * 10;
    for (var i = 0; i < lineCount; i++) {
    
    
      context_line.beginPath();
      var currentPoint = {
    
    
        x: dimen.rpx2px(40),
        y: (canvasHeight_line - i * ratio) - dimen.rpx2px(40)
      };
      // 移动到原点
      context_line.moveTo(currentPoint.x, currentPoint.y);
      // 向Y正轴方向画线
      context_line.lineTo(canvasWidth_line - dimen.rpx2px(10), (canvasHeight_line - i * ratio) - dimen.rpx2px(40));
      // 设置属性
      context_line.setLineWidth(dimen.rpx2px(2));
      // 设置颜色
      context_line.setStrokeStyle(lightGray);
      context_line.stroke();
      // 标注数值
      context_line.setFillStyle(gray);
      // 底部时间文字
      context_line.fillText(i * maxPeople / (lineCount - 1), currentPoint.x - dimen.rpx2px(40), currentPoint.y);
    }
  },
  /* 画底部日期 */
  drawDate: function (list) {
    
    
    var ref_date = "";
    var temp_ref_date1 = "";
    var temp_ref_date2 = "";

    list.forEach(function (data, i, array) {
    
    
      if (i < array.length - 1) {
    
    
        context_line.setFillStyle(gray);

        ref_date = data.ref_date.toString();
        temp_ref_date1 = ref_date.substring(4, 6) + ".";
        temp_ref_date2 = ref_date.substring(6, ref_date.length);
        ref_date = temp_ref_date1 + temp_ref_date2;

        if (i % 4 == 0) {
    
    
          context_line.fillText(ref_date, i * ratioX + dimen.rpx2px(10), canvasHeight_line - dimen.rpx2px(10));
        }
      }
    });
  },

3.7. After saving and compiling, the corresponding line chart effect can be realized.

2. Histogram

insert image description here

3.8. Create a new page under the pages folder to implement the histogram.
insert image description here

<view class="margin-left__20 margin-right__20">
  <view class="color__white font-size__medium margin-top__10">
    <text>用户年龄分布</text>
  </view>
  <canvas canvas-id="age-canvas" id="age-canvas" />
</view>

3.9. To implement the corresponding wxml and wxss, some common css content can be encapsulated in a common one.

#age-canvas {
      
      
	width: 710rpx;
	height: 400rpx;
	background: #192429;
}
.flex-wrap__nowrap {
    
    
  flex-wrap: nowrap;
}

.justify-content__center {
    
    
  justify-content: center;
}

.justify-content__flex-start {
    
    
  justify-content: flex-start;
}

.justify-content__flex-end {
    
    
  justify-content: flex-end;
}

.justify-content__space-between {
    
    
  justify-content: space-between;
}

.align-items__center {
    
    
  align-items: center;
}

.text-align__center {
    
    
  text-align: center;
}

.text-align__end {
    
    
  text-align: end;
}

.display__inline-block {
    
    
  display: inline-block;
}

3.10. External JS for data storage and data processing needs to be introduced in js.
insert image description here

var data = require('../../../data/jsonData.js');
var dimen = require("../../../utils/loadPage.js");

3.11. It is necessary to define the canvas variable and the magnification of the x-axis and y-axis at the top.

const context_age = wx.createCanvasContext('age-canvas');
var canvasWidth = 0;
var canvasHeight = 0;
var ratioX = 0; // x轴放大倍数
var ratioY = 0; // y轴放大倍数
var royalBlue = '#4169E1';
var gray = '#cccccc';
var count = 0;

3.12. Implement the corresponding JS.
insert image description here

  // 画总年龄百分比
  drawPercent: function (list) {
    
    
    // 计算全部年龄总和
    var totalAge = 0;
    list.forEach(function (data, i, array) {
    
    
      totalAge += data.value;
    });

    context_age.setFillStyle('white');
    context_age.setFontSize(dimen.rpx2px(24));
    list.forEach(function (data, i, array) {
    
    
      context_age.fillText(
        Math.floor(data.value * 10000 / totalAge) / 100 + '%',
        i * ratioX + (i == 0 ? dimen.rpx2px(50) : dimen.rpx2px(30)),
        canvasHeight - dimen.rpx2px(80) + (-data.value * dimen.rpx2px(8)));
    });
  },
  // 画柱状图 
  drawColumn: function (list, process) {
    
    
    context_age.setFillStyle(royalBlue);
    list.forEach(function (data, i, array) {
    
    
      var height = - data.value * dimen.rpx2px(8);
      height *= process;
      context_age.fillRect(
        i * ratioX + (i == 0 ? dimen.rpx2px(30) : dimen.rpx2px(14)),
        canvasHeight - dimen.rpx2px(40),
        dimen.rpx2px(50), height)
    });
  },
  // 画柱状图上面的年龄
  drawColumnNumber: function (list) {
    
    
    context_age.setFillStyle(royalBlue);
    context_age.setFontSize(dimen.rpx2px(24));
    list.forEach(function (data, i, array) {
    
    
      context_age.fillText(
        data.value, 
        i * ratioX + (i == 0 ? dimen.rpx2px(50) : dimen.rpx2px(30)), 
        canvasHeight - dimen.rpx2px(50) + (-data.value * dimen.rpx2px(8)));
    });
  },
  // 画线
  drawLine: function (list) {
    
    
    context_age.beginPath();
    context_age.setStrokeStyle(gray);
    context_age.setLineWidth(dimen.rpx2px(2));
    context_age.moveTo(0, canvasHeight - dimen.rpx2px(40));
    context_age.lineTo(canvasWidth, canvasHeight - dimen.rpx2px(40));
    context_age.stroke();  // 这行必须要写,不然线就出不来
  },
  // 画年龄文字
  drawText: function (list) {
    
    
    context_age.setFillStyle(gray);
    context_age.setFontSize(dimen.rpx2px(24));
    list.forEach(function (data, i, array) {
    
    
      context_age.fillText(
        data.name, 
        i * ratioX + (i == 0 ? dimen.rpx2px(30) : 0), 
        canvasHeight - dimen.rpx2px(10));
    });
  },

3.13. Dynamic rendering effects can be added after implementation.
insert image description here

var Timing = {
    
    
  easeIn: function easeIn(pos) {
    
    
    return Math.pow(pos, 3);
  },

  easeOut: function easeOut(pos) {
    
    
    return Math.pow(pos - 1, 3) + 1;
  },

  easeInOut: function easeInOut(pos) {
    
    
    if ((pos /= 0.5) < 1) {
    
    
      return 0.5 * Math.pow(pos, 3);
    } else {
    
    
      return 0.5 * (Math.pow(pos - 2, 3) + 2);
    }
  },

  linear: function linear(pos) {
    
    
    return pos;
  }
};
this.Animation({
    
    
  timing: 'easeIn',
  duration: 1000,
  onProcess: function onProcess(process) {
    
    
    count++;
    that.drawColumn(list, process);
    that.draw();
  },
  onAnimationFinish: function onAnimationFinish() {
    
    
    that.drawColumnNumber(list);
    that.drawPercent(list);
    that.draw();
  }
});

3. Bar chart

3.14. Repeat the above steps to create a page again.

<view class="margin-left__20 margin-right__20">
  <view class="margin-top__30 margin-bottom__20 font-size__large">
    <text>30天访问来源</text>
  </view>
  <canvas canvas-id="striptype-canvas" id="striptype-canvas" style="height:{
    
    {canvasHeight_striptype}}px;"/> 
</view>

insert image description here
3.15. Implement the corresponding JS and WXML.

 // 画左侧文字
  drawText: function (list){
    
    
    var source = '';
    context_striptype.setFillStyle('#5A8DA7');
    context_striptype.setFontSize(dimen.rpx2px(24));
    list.forEach(function (data, i, array) {
    
    
      switch (data.key) {
    
    
        case 1:
          source = '小程序历史列表';
          break;
        case 2:
          source = '搜索';
          break;
        case 3:
          source = '会话';
          break;
        case 4:
          source = '二维码';
          break;
        case 5:
          source = '公众号主页';
          break;
        case 6:
          source = '聊天顶部';
          break;
        case 7:
          source = '系统桌面';
          break;
        case 8:
          source = '小程序主页';
          break;
        case 9:
          source = '附近的小程序';
          break;
        case 10:
          source = '其他';
          break;
        case 11:
          source = '模板消息';
          break;
        case 12:
          source = '客服消息';
          break;
        case 13:
          source = '公众号菜单';
          break;
        case 14:
          source = 'APP分享';
          break;
        case 15:
          source = '支付完成页';
          break;
        case 16:
          source = '长按识别二维码';
        case 17:
          source = '相册选取二维码';
          break;
        case 18:
          source = '公众号文章';
          break;
        default:
          break;
      }
      context_striptype.fillText(source, 0, i * ratioY + dimen.rpx2px(30));
      if (source.toString().length > maxStringLenth) {
    
    
        maxStringLenth = source.toString().length;
      }
    });
  },
  // 画竖线
  drawLine: function (canvasHeight) {
    
    
    context_striptype.beginPath();
    context_striptype.setStrokeStyle(gray);
    context_striptype.setLineWidth(dimen.rpx2px(2));
    context_striptype.moveTo(maxStringLenth * dimen.rpx2px(26), canvasHeight);
    context_striptype.lineTo(maxStringLenth * dimen.rpx2px(26), dimen.rpx2px(10));
    context_striptype.stroke();
  },
  // 画条形图
  drawStricptype: function (list, process) {
    
    
    context_striptype.setFillStyle('#00EFFE');
    list.forEach(function (data, i, array) {
    
    
      var width = data.value < 200 ? data.value : dimen.rpx2px(400);
      width *= process;
      context_striptype.fillRect(
        maxStringLenth * dimen.rpx2px(26) + dimen.rpx2px(2),
        i * ratioY + dimen.rpx2px(12),
        width,
        dimen.rpx2px(20));
    });
  },
  // 画条形图数值
  drawStricptypeNum: function (list) {
    
    
    context_striptype.setFontSize(dimen.rpx2px(24));
    list.forEach(function (data, i, array) {
    
    
      context_striptype.fillText(data.value,
        maxStringLenth * dimen.rpx2px(26) + dimen.rpx2px(10) + (data.value < 200 ? data.value : dimen.rpx2px(400)),
        i * ratioY + dimen.rpx2px(30));
    });
  },
  // 画百分比
  drawpercent: function (list) {
    
    
    var totalSouce = 0;
    list.forEach(function (data, i, array) {
    
    
      totalSouce += data.value;
    });
    context_striptype.setFillStyle('white');
    list.forEach(function (data, i, array) {
    
    
      context_striptype.fillText(
        (Math.floor(data.value * 10000 / totalSouce) / 100).toFixed(1) + '%',
        maxStringLenth * dimen.rpx2px(26) + dimen.rpx2px(60) + (data.value < 200 ? data.value : dimen.rpx2px(400)),
        i * ratioY + dimen.rpx2px(30));
    });
  },

Guess you like

Origin blog.csdn.net/weixin_42794881/article/details/127319786