canvas绘图

canvas控件--折线图--区间选择功能(上)

2017-07-11  本文已影响29人  王恩智

根据项目上的需求封装的一个控件,不知道叫什么好,暂时命名为时间区间选择器吧。
简单来讲,就是一个折线图,x轴为时间,y轴为数值,我们可以通过拖拽等方式,在折线图上选择一个时间段,然后通过各种方式展示这个时间段内详细的数据情况。
大体是下面这个样子


在线展示,这个是项目上用的es5版本的,我会重新写一个es6版本的,并在下一篇提供在线展示连接

下面我们看一下代码

const drawChart = (containerId,data = initData('2017-03-20', 20)) => {
    const container = document.getElementById(containerId),
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d'),
        {width: W, height: H, top: T, left: L} = container.getBoundingClientRect(),//容器位置大小,计算鼠标位置等需要
        fontSize = 12;//XY轴文字大小
        chartTop = 10,
        chartRight = W - 10,
        chartBottom = H - fontSize * 3,//图表最下方位置,预留3行文字年月日的位置
        chartLeft = fontSize * 3,//图表左侧位置,预留10像素文字位置
        {dataMax, dataMin, ndata} = getMaxMin(data),//处理数据
        xlength = chartRight - chartLeft,//X轴长度
        ylength = chartBottom - chartTop,//Y轴长度
        xstep = (chartRight - chartLeft) / data.length,//X轴比例尺
        ystep = (chartBottom - chartTop) / (dataMax - dataMin),//Y轴比例尺
        mouseState = null,//鼠标状态
        mouseMovePosition = null,//记录鼠标X轴位置,用于绘制蓝线
        initCanvas = () => {...},
        mousedown = e => {...},
        mousemove = e => {...},
        mouseup = e => {...},
        drawLines = () => {...},
        drawAxis = () => {...},
        drawText = () => {...},
        drawOther = () => {...},
        draw = () => {...};
    initCanvas();
    drawText();
    draw();
}

首先声明了一些变量和方法
然后initCanvas方法初始化canvas,设置canvas样式、像素数和事件,并将canvas添加到容器中

canvas.width = W;
canvas.height = H;
canvas.style.width = W + 'px';
canvas.style.height = H + 'px';
canvas.addEventListener('mousedown', mousedown);
canvas.addEventListener('mousemove', mousemove);
canvas.addEventListener('mouseup', mouseup);
container.appendChild(canvas);

drawText方法绘制x轴y轴上的坐标轴刻度标签,因为坐标轴标签是不变的,所不需要每一帧都绘制,所以我们在这里绘制一次即可

ctx.save();
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.font = `${fontSize}px Arial`;
ndata.map(({title}, index) => {
  if(title !== undefined) {
  let x = chartLeft + index * xstep;
    title.map((elem, ind) => ctx.fillText(elem, x, chartBottom + ind * fontSize));
  }
});
ctx.restore();

最后调用draw方法,如果我们要做的仅仅是通过canvas绘制一个折线图,那么到这一步就结束了了,那么我们的draw方法这样就可以了

drawLines();//绘制折线
drawAxis();//绘制坐标轴
drawOther();//绘制其他内容

至此,我们使用canvas绘制了一个折线图,这个折线图没有任何交互功能
点击下面的在线展示,可以查看这个折线图和代码
在线展示
下一篇,我们将讨论如何实现通过鼠标拖拽等方式实现选择一段时间的功能

上一篇下一篇

猜你喜欢

热点阅读