基于canvas生成股票k线(60日线简版)

2022-04-11  本文已影响0人  Mr无愧于心

一般绘图的插件eChart / highChart体积太大,(react-sparklines / vue-sparklines)存在兼容性问题,索性自己用canvas画一个。

canvas大神可以略过。。。

const data=[1,2,3,4,5,6,8]
function getBrokenLine (el, data) {
      if (data.length < 60) {// 数据少于60日,补齐
        data = [...data, ...new Array(60).fill(-1)].slice(0, 60);
      }
      var cv = document.getElementById(el);
      cv.style.width = '70px';
      cv.style.height = '30px';
      cv.width = 70;
      cv.height = 30;
      var ctx = cv.getContext('2d');
      var maxNum = Math.max.apply(null, data); // 求数组中的最大值
      var minNum = Math.min.apply(null, data); // 求数组中的最小值
      var xLength = cv.width; // x轴的长度
      var yLength = cv.height; // y轴的长度
      var pointsWidth = xLength / (data.length - 1); // 折线上每个点之间的距离
      // 绘制右侧y轴
      var radio = 1;
      if (minNum < 0) {
        radio = maxNum - minNum;
      } else {
        radio = maxNum;
      }
      ctx.beginPath();
      for (let i = 0; i < data.length; i++) {
        const pointX = i * pointsWidth;
        let pointY = 0;
        if (minNum < 0) {
          pointY = (1 + minNum / radio - data[i] / radio) * yLength + 1;
        } else {
          if (1 - data[i] / radio !== 1) {
            pointY = (1 - data[i] / radio) * yLength + 1;
          } else {
            pointY = (1 - data[i] / radio) * yLength;
          }
        }
        ctx.lineTo(pointX, pointY);
      }
      ctx.lineWidth = 1;
      ctx.strokeStyle = 'rgb(0,102,204)';
      ctx.stroke();

      ctx.beginPath();// 控制绘制的折线不受坐标轴样式属性的影响
      ctx.moveTo(xLength, (1 - data[data.length - 1] / radio) * yLength);
      ctx.lineTo(xLength, yLength);
      // 绘制x轴
      ctx.lineTo(0, yLength);
      // 绘制y轴
      ctx.lineTo(0, yLength);

      // 绘制折线
      for (let i = 0; i < data.length; i++) {
        const pointX = i * pointsWidth;
        let pointY = 0;
        if (minNum < 0) {
          pointY = (1 + minNum / radio - data[i] / radio) * yLength + 1;
        } else {
          pointY = (1 - data[i] / radio) * yLength + 1;
        }
        ctx.lineTo(pointX, pointY);
      }
      ctx.closePath();
      ctx.fillStyle = 'rgba(0,102,204,0.1)';
      ctx.fill();
      ctx.strokeStyle = 'rgba(0,102,204,0.1)';
      ctx.stroke();
    }
  }
效果时这样的
上一篇 下一篇

猜你喜欢

热点阅读