美文网首页canvas绘图
canvas控件--折线图--区间选择功能(上)

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

作者: 王恩智 | 来源:发表于2017-07-11 12:46 被阅读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绘制了一个折线图,这个折线图没有任何交互功能
    点击下面的在线展示,可以查看这个折线图和代码
    在线展示
    下一篇,我们将讨论如何实现通过鼠标拖拽等方式实现选择一段时间的功能

    相关文章

      网友评论

        本文标题:canvas控件--折线图--区间选择功能(上)

        本文链接:https://www.haomeiwen.com/subject/eskuhxtx.html