1. 程式人生 > >HTML5 canvas燃盡圖

HTML5 canvas燃盡圖


先說說這個demo的靈感來源。

我以前有一同事,技術在我心目中算是非常厲害的那種,我這一年多來的技術提高基本上完全靠他所賜,再次對他表示深深的感謝啊!

一次偶然的機會,讓我見識了他的前端部落格,其中裡邊有一個demo給我的印象特別深,好像名字叫做”svg burndown”.

顧名思義,他的這個demo是用svg做的,我覺得挺有意思,於是下定決心自己做一個,svg已經被他用過了,再用就沒意思了。

剩下的也就只有html5的canvas可以考慮了,雖然自己的canvas功底不算很強,但還是決定大膽嘗試一番。

燃盡圖是現在團隊敏捷開發非常重要的考量工具,對於團隊的分工、進度把控、成員協作等方面起到非常重要的作用。

燃盡圖主要分為以下幾個部分:

1、座標軸

主要分為x軸和y軸,其中x軸表示時間,y軸表示剩餘任務量,y軸為0時表示任務全部完成。

drawCoordinate: function() {
            sContext.beginPath();
            sContext.moveTo(xSpace, 0);
            sContext.lineTo(xSpace, config.height - ySpace);
            sContext.lineTo(config.width, config.height - ySpace);
            sContext.lineWidth = 3;
            sContext.strokeStyle = 'rgba(0,0,0,0.5)';
            sContext.stroke();
            sContext.closePath();
        },
        drawScaleX: function() {
            sContext.beginPath();
            sContext.moveTo(xSpace, config.height);
            var len = timeList.length;
            sContext.textAlign = 'center';
            for(var i = 0; i < len; i++) {
                var date = timeList[i];
                var show = date[2] +'/'+ (parseInt(date[1])+1);
                var x = config.width/(len+1)*i + xSpace;
                if(i > 0) {
                    sContext.moveTo(x, 0);
                    sContext.lineTo(x, config.height - ySpace);
                    maxX = [x, config.height - ySpace];
                }
                scaleX[i] = x;
                sContext.fillText(show, x, config.height - 5);
            }
            sContext.lineWidth = 1;
            sContext.strokeStyle = '#eeeeee';
            sContext.stroke();
            sContext.closePath();
        },
        drawScaleY: function() {
            var num = 0;
            var max = config.taskMax;
            var step = config.taskStep;
            var len = max/step;
            var pLen = parseInt(max/step);
            len = len === pLen ? pLen+1 : pLen+2;
            sContext.beginPath();
            sContext.moveTo(xSpace, config.height);
            sContext.textAlign = 'right';
            sContext.textBaseline = 'middle';
            for(var i = 0; i < len; i++) {
                var y = config.height - ySpace - config.height/len*i;
                if(i > 0) {
                    if(i === len - 1) {
                        y = ySpace;
                        num = config.taskMax;
                    }
                    sContext.moveTo(config.width, y);
                    sContext.lineTo(xSpace, y);
                    maxY = [xSpace, y];
                }
                sContext.fillText(num+'', xSpace, y);
                num += step;
            }
            sContext.strokeStyle = '#eeeeee';
            sContext.stroke();
            sContext.closePath();
        },

2、參考線

參考線是指標準的專案燃盡線路圖,當然,在具體專案中,幾乎不可能完全按照參考線的路徑一直往下走,一般都是在參考線上下徘徊才算正常。

drawRefLine: function() {
            sContext.beginPath();
            sContext.moveTo(maxY[0], maxY[1]);
            sContext.lineTo(maxX[0], maxX[1]);
            sContext.lineWidth = 3;
            sContext.strokeStyle = 'rgba(255,255,0,0.5)';
            sContext.stroke();
            sContext.closePath();
        },

3、燃盡線路

燃盡圖最重要的便是燃盡線路,每當到了一個時間點,就應該更新燃盡圖,具體的操作便是新增一個座標,許多個座標連成線變成了燃盡線路。當最後一個時間點的任務量剩餘不為0時,表示任務沒有完成,同志人須努力啊。

drawBurnLine: function(task) {
            task && !this.isSameDate(task) && taskList.push(task);
            taskList = taskList.sort();
            lContext.clearRect(0, 0, config.width, config.height);
            lContext.beginPath();
            lContext.moveTo(maxY[0], maxY[1]);
            for(var i = 0; i < taskList.length; i++) {
                var x = taskList[i][0];
                var y = taskList[i][1];
                for(var j = 0; j < scaleX.length; j++) {
                    if(x.join('') === timeList[j].join('')) {
                        var xx = scaleX[j];
                        var yy = y > 0 ? (1 - y/config.taskMax)*(config.height - ySpace) : config.height - ySpace;
                        lContext.lineTo(xx, yy);
                        lContext.arc(xx, yy, 3, 0, Math.PI*2, true);
                        break;
                    }
                }
            }
            lContext.lineWidth = 3;
            lContext.strokeStyle = 'rgba(0,0,255,0.5)';
            lContext.stroke();
            lContext.closePath();
        },

以上便是canvas燃盡圖的大致實現原理,肯定還有諸多瑕疵,希望看完後能給個評價,自當虛心接受。
       歡迎光臨我的前端部落格:http://xiechengxiong.com/