2016-07-03 108 views
10

我想使用chartjs線條圖可視化我的數據點。 Chartjs默認情況下似乎爲圖形設置了動畫效果,但不會爲x軸上的值生成動畫。 x軸僅以不連續的步驟移動。Chartjs動畫x軸

有什麼辦法可以在軸上啓用動畫嗎?

謝謝!

+0

目前還不清楚是否是問在X維動畫的圖形數據作爲CTG已經低於完成,或者如果你的意思是在x動畫標籤斧頭(這是我把你的問題的意思,是我創造賞金時尋找的),這裏沒有答案。你能澄清嗎? – Aerovistae

回答

4

據我所知,ChartJS不支持x軸動畫外的所述盒。所以你必須破解它。有幾種方法可能做到這一點,但以下方法似乎工作。

如果要進行動畫的數據在X軸

當圖表被更新時,發生以下步驟:1)將軸拉伸,然後2)draw()函數被調用,以繪製數據。對於不同的圖表類型,有不同的draw()函數,折線圖的函數是Chart.controllers.line.prototype.drawdraw()函數帶有一個參數,我將調用animationFraction,它表示動畫的分數是多少。例如,如果動畫完成5%,則animationFraction將爲0.05,並且如果動畫完成100%(即,如果圖表處於其最終形式),則animationFraction=1。在動畫的每個步驟調用draw()函數來更新數據顯示。

一分劈動畫x軸則是猴子修補線圖表draw()功能到畫布中在每個水平維度平移繪製步驟:

var hShift = (1-animationFraction)*ctx.canvas.width; 

hShift是在像素水平移位的圖表。如上所述,數據將從右側掃入;如果你想讓它從左邊掃入,你可以使上面的消極。然後保存畫布上下文狀態,變換使用hShift畫布,畫圖表數據,然後在畫布恢復到原來的狀態,以便在下一次動畫幀軸將在正確的位置可以得出:

ctx.save(); 
ctx.setTransform(1, 0, 0, 1, hShift, 0); 
ctx.oldDraw.call(this, animationFraction); 
ctx.restore(); 

在上面,this指圖表對象,並oldDraw是指以前保存原線圖繪圖功能:

var oldDraw = Chart.controllers.line.prototype.draw; 

,你還可以設置你的新draw()函數讀取新的動畫選項,允許你設置什麼呃x軸和y軸的動畫:

var oldDraw = Chart.controllers.line.prototype.draw; 
Chart.controllers.line.prototype.draw = function(animationFraction) { 
    var animationConfig = this.chart.options.animation; 
    if (animationConfig.xAxis === true) { 
     var ctx = this.chart.chart.ctx; 
     var hShift = (1-animationFraction)*ctx.canvas.width; 
     ctx.save(); 
     ctx.setTransform(1, 0, 0, 1, hShift,0); 
     if (animationConfig.yAxis === true) { 
      oldDraw.call(this, animationFraction); 
     } else { 
      oldDraw.call(this, 1); 
     } 
     ctx.restore(); 
    } else if (animationConfig.yAxis === true) { 
     oldDraw.call(this, animationFraction); 
    } else { 
     oldDraw.call(this, 1); 
    } 
} 

然後,您可以創建與動畫兩個軸折線圖:

var lineChart = new Chart(ctx, { 
    type: 'line', 
    data: data, 
    options: { 
     animation: { 
      duration: 5000, 
      xAxis: true, 
      yAxis: true, 
     } 
    } 
}); 

的演示中看到https://jsfiddle.net/16L8sk2p/

如果你想動畫的X軸極限

如果你想動畫x軸的限制 - 即。移動數據,座標軸刻度和刻度標籤,然後您可以使用以下策略。這有點古怪,因此可能需要一些努力來解決任何特定用例的問題,但我相信它應該可以普遍使用。首先,您需要將線圖轉換爲散點圖。折線圖具有分步移動的分類x軸,因此您不能將軸限制設置在滴答之間,這是您獲取動畫所需執行的操作。因此,您需要使用線散點圖,因爲散點圖可以具有任意的軸限制。您可以通過爲每個數據點編號並將該數字分配給該數據點的x值來完成此操作。例如,要生成一個隨機的數據集,你可以這樣做:

var DATA_POINT_NUM = 58; 
var data = { 
    labels: [], 
    datasets: [ 
     { 
      data: [], 
     }, 
    ] 
} 
for (var i=0; i<DATA_POINT_NUM; i++) { 
    data.datasets[0].data.push({ x: i, 
            y: Math.random()*10 
           }); 
    data.labels.push(String.fromCharCode(65+i)); 
} 

然後您就需要編寫一個函數,數據點對應的X值和數據點標籤之間進行轉換(即類別,這將是在圖表上X軸):

function getXAxisLabel(value) { 
    try { 
     var xMin = lineChart.options.scales.xAxes[0].ticks.min; 
    } catch(e) { 
     var xMin = undefined; 
    } 
    if (xMin === value) { 
     return ''; 
    } else { 
     return data.labels[value]; 
    } 
} 

其中應用於LineChart是我們的圖表對象,這將在下面定義。請注意,ChartJS以略微不同的方式繪製圖表,如果在x軸的最小值處存在標籤,則需要編寫此函數以返回空字符串,如果值== x軸的最小值。然後您可以定義圖表對象:

var lineChart = new Chart(ctx, { 
    type: 'line', 
    data: data, 
    options: { 
     animation: false, 
     scales: { 
      xAxes: [{ 
       type: 'linear', 
       position: 'bottom', 
       ticks: { 
        min: 0, 
        max: 10, 
        callback: getXAxisLabel, // function(value) { return data.labels[value]; }, 
        autoSkip: false, 
        maxRotation: 0, 

       }, 
      }] 
     } 
    } 
}); 

ticks.callback上面設置爲我們getXAxisLabel功能。當ChartJS繪製x軸時,它會將數據點的x值傳遞給回調函數,然後將結果字符串用作x軸上的值。通過這種方式,我們可以繪製一個散點圖,如折線圖。我還設置了autoSkip=falsemaxRotation=0以確保軸標籤以一致的方式繪製。

然後,您可以通過調整x軸ticks.minticks.max值並調用圖表的.update()方法來爲圖表製作動畫。爲了說明這一點,下面的代碼沿圖表x軸掃描,一次顯示10個數據點。

var xMin = 0;     // Starting minimum value for the x-axis 
var xLength = 10;    // Length of the x-axis 
var animationDuration = 5000; // Duration of animation in ms 

// Calculate animation properties 
var framesPerSec = 100; 
var frameTime = 1000/framesPerSec; 
var xStep = (DATA_POINT_NUM-xMin+xLength)/(animationDuration/1000*framesPerSec); 

function nextFrame() { 
    var xMax = xMin+xLength; 
    if (xMax < DATA_POINT_NUM-1) { 

     if (xMax+xStep > DATA_POINT_NUM-1) { 
      xMax = DATA_POINT_NUM-1; 
      xMin = xMax-xLength; 
     } 
     lineChart.options.scales.xAxes[0].ticks.min = xMin; 
     lineChart.options.scales.xAxes[0].ticks.max = xMax; 
     lineChart.update(); 
     setTimeout(nextFrame, frameTime); 
     xMin += 0.1; 
    } 
} 

nextFrame(); 

全部放在一起:https://jsfiddle.net/qLhojncy/

+0

現在我重新閱讀這個問題似乎還不清楚,但是當我創建賞金時,我所尋找的就是能夠在x軸上對*標籤*進行動畫製作,而不是x維中的圖形數據。我不確定那些原始提問者是指哪一個。您可以通過點擊此圖上的'更新'來查看我的意思是在這裏d3的示例〜http://bl.ocks.org/d3noob/7030f35b72de721622b8 – Aerovistae

+0

@Aerovistae,我明白了。我編輯了我的答案,其中包括一種可能的標籤動畫製作方法。希望它能爲你工作。 – cjg

+0

謝謝,這是完美的! –

1

我不是javascript的專家,但是我發現Chartjs的一個例子,當插入一個新的數據點,通過動畫更新x軸,看起來可能會幫助你:example

示例源:sitepoint.com

+1

由於問題表明問題是在折線圖上爲x軸設置動畫。 –