用Canvas画最近30个交易日的K线图

@spiritree  January 26, 2017

1.在HTML中准备<canvas>

  • Canvas是HTML5中的新组建,可以使用JavaScript画图从而放弃Flash。

<canvas id="stock-canvas" width="300" height="200" style="border: 1px solid #ccc; margin-top: 15px;"></canvas>

2.从JSON中提取股票数据

window.loadStockData = function (r) {
    var
        NUMS = 30,
        data = r.data;
    if (data.length > NUMS) {
        data = data.slice(data.length - NUMS);
    }
    data = data.map(function (x) {
        return {
            date: x[0],
            open: x[1],
            close: x[2],
            high: x[3],
            low: x[4],
            vol: x[5],
            change: x[6],
        };
    });
    window.drawStock(data);
};
let js = document.createElement('script');
js.src = 'http://img1.money.126.net/data/hs/kline/day/history/2015/0000001.json?callback=loadStockData&t=' + Date.now();
document.getElementsByTagName('head')[0].appendChild(js);

3.用Canvas(JavaScript)画图

window.drawStock = function (data) {
  let
    canvas = document.getElementById('stock-canvas'),
    width = canvas.width,
    height = canvas.height,
    ctx = canvas.getContext('2d');

  ctx.fillStyle = "#000000";
  ctx.fillRect(0, 0, width, height);

  let candle_width = width / data.length;
  let draw_ratio = 0.5;
  let baseline = height / 2;

  for (let i = 0; i < data.length; i++) {
    let temp = data[i];
    let rise = (temp.close - temp.open >= 0); //判断上涨下跌的逻辑变量
    let candle_x = candle_width * i;
    let candle_height = Math.abs(temp.close - temp.open) * draw_ratio;
    let candle_y = 0;

    if (rise) {
      ctx.fillStyle = "#FF0000";
      ctx.strokeStyle = "#FF0000";
      candle_y = baseline - candle_height;
      let high_stick_height = (temp.high - temp.close) * draw_ratio; //上影线
      let low_stick_height = (temp.open - temp.low) * draw_ratio; //下影线
      ctx.fillRect(candle_x, candle_y, candle_width, candle_height);
      ctx.beginPath();
      ctx.moveTo(candle_x + candle_width / 2, candle_y);
      ctx.lineTo(candle_x + candle_width / 2, candle_y - high_stick_height);
      ctx.stroke();
      ctx.beginPath();
      ctx.moveTo(candle_x + candle_width / 2, candle_y + candle_height);
      ctx.lineTo(candle_x + candle_width / 2, candle_y + candle_height + low_stick_height);
      ctx.stroke();
      baseline = candle_y;
    } else {
      ctx.fillStyle = "#00FF00";
      ctx.strokeStyle = "#00FF00";
      candle_y = baseline;
      let high_stick_height = (temp.high - temp.open) * draw_ratio; //上影线
      let low_stick_height = (temp.low - temp.close) * draw_ratio; //下影线
      ctx.fillRect(candle_x, candle_y, candle_width, candle_height);
      ctx.beginPath();
      ctx.moveTo(candle_x + candle_width / 2, candle_y);
      ctx.lineTo(candle_x + candle_width / 2, candle_y - high_stick_height);
      ctx.stroke();
      ctx.beginPath();
      ctx.moveTo(candle_x + candle_width / 2, candle_y + candle_height);
      ctx.lineTo(candle_x + candle_width / 2, candle_y + candle_height + low_stick_height);
      ctx.stroke();
      baseline = candle_y + candle_height;
    }
  }
};

效果图

![](
https://om4v1ul08.qnssl.com/K-line30.png)


添加新评论