根據(jù)項目上的需求封裝的一個控件,不知道叫什么好,暫時命名為時間區(qū)間選擇器吧。
簡單來講,就是一個折線圖,x軸為時間,y軸為數(shù)值,我們可以通過拖拽等方式,在折線圖上選擇一個時間段,然后通過各種方式展示這個時間段內(nèi)詳細的數(shù)據(jù)情況。
大體是下面這個樣子
在線展示,這個是項目上用的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,//圖表最下方位置,預(yù)留3行文字年月日的位置
chartLeft = fontSize * 3,//圖表左側(cè)位置,預(yù)留10像素文字位置
{dataMax, dataMin, ndata} = getMaxMin(data),//處理數(shù)據(jù)
xlength = chartRight - chartLeft,//X軸長度
ylength = chartBottom - chartTop,//Y軸長度
xstep = (chartRight - chartLeft) / data.length,//X軸比例尺
ystep = (chartBottom - chartTop) / (dataMax - dataMin),//Y軸比例尺
mouseState = null,//鼠標狀態(tài)
mouseMovePosition = null,//記錄鼠標X軸位置,用于繪制藍線
initCanvas = () => {...},
mousedown = e => {...},
mousemove = e => {...},
mouseup = e => {...},
drawLines = () => {...},
drawAxis = () => {...},
drawText = () => {...},
drawOther = () => {...},
draw = () => {...};
initCanvas();
drawText();
draw();
}
首先聲明了一些變量和方法
然后initCanvas方法初始化canvas,設(shè)置canvas樣式、像素數(shù)和事件,并將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();
最后調(diào)用draw方法,如果我們要做的僅僅是通過canvas繪制一個折線圖,那么到這一步就結(jié)束了了,那么我們的draw方法這樣就可以了
drawLines();//繪制折線
drawAxis();//繪制坐標軸
drawOther();//繪制其他內(nèi)容
至此,我們使用canvas繪制了一個折線圖,這個折線圖沒有任何交互功能
點擊下面的在線展示,可以查看這個折線圖和代碼
在線展示
下一篇,我們將討論如何實現(xiàn)通過鼠標拖拽等方式實現(xiàn)選擇一段時間的功能