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

根據(jù)項(xiàng)目上的需求封裝的一個(gè)控件,不知道叫什么好,暫時(shí)命名為時(shí)間區(qū)間選擇器吧。
簡(jiǎn)單來(lái)講,就是一個(gè)折線圖,x軸為時(shí)間,y軸為數(shù)值,我們可以通過(guò)拖拽等方式,在折線圖上選擇一個(gè)時(shí)間段,然后通過(guò)各種方式展示這個(gè)時(shí)間段內(nèi)詳細(xì)的數(shù)據(jù)情況。
大體是下面這個(gè)樣子


在線展示,這個(gè)是項(xiàng)目上用的es5版本的,我會(huì)重新寫(xiě)一個(gè)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(),//容器位置大小,計(jì)算鼠標(biāo)位置等需要
        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軸長(zhǎng)度
        ylength = chartBottom - chartTop,//Y軸長(zhǎng)度
        xstep = (chartRight - chartLeft) / data.length,//X軸比例尺
        ystep = (chartBottom - chartTop) / (dataMax - dataMin),//Y軸比例尺
        mouseState = null,//鼠標(biāo)狀態(tài)
        mouseMovePosition = null,//記錄鼠標(biāo)X軸位置,用于繪制藍(lán)線
        initCanvas = () => {...},
        mousedown = e => {...},
        mousemove = e => {...},
        mouseup = e => {...},
        drawLines = () => {...},
        drawAxis = () => {...},
        drawText = () => {...},
        drawOther = () => {...},
        draw = () => {...};
    initCanvas();
    drawText();
    draw();
}

首先聲明了一些變量和方法
然后initCanvas方法初始化canvas,設(shè)置canvas樣式、像素?cái)?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軸上的坐標(biāo)軸刻度標(biāo)簽,因?yàn)樽鴺?biāo)軸標(biāo)簽是不變的,所不需要每一幀都繪制,所以我們?cè)谶@里繪制一次即可

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方法,如果我們要做的僅僅是通過(guò)canvas繪制一個(gè)折線圖,那么到這一步就結(jié)束了了,那么我們的draw方法這樣就可以了

drawLines();//繪制折線
drawAxis();//繪制坐標(biāo)軸
drawOther();//繪制其他內(nèi)容

至此,我們使用canvas繪制了一個(gè)折線圖,這個(gè)折線圖沒(méi)有任何交互功能
點(diǎn)擊下面的在線展示,可以查看這個(gè)折線圖和代碼
在線展示
下一篇,我們將討論如何實(shí)現(xiàn)通過(guò)鼠標(biāo)拖拽等方式實(shí)現(xiàn)選擇一段時(shí)間的功能

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容