根据项目上的需求封装的一个控件,不知道叫什么好,暂时命名为时间区间选择器吧。
简单来讲,就是一个折线图,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绘制了一个折线图,这个折线图没有任何交互功能
点击下面的在线展示,可以查看这个折线图和代码
在线展示
下一篇,我们将讨论如何实现通过鼠标拖拽等方式实现选择一段时间的功能