canvas控件--折線圖--區(qū)間選擇功能(上)

根據(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)選擇一段時間的功能

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容