Per quanto ne so, ChartJS non supporta l'animazione asse x out-of-the-box. Quindi dovrai hackerarlo. Ci sono diversi modi per farlo, ma i seguenti metodi sembrano funzionare.
Se si desidera animare i dati del X-Axis
Quando un grafico viene aggiornato, i seguenti passaggi: 1) Gli assi sono disegnati, e poi 2) una funzione draw()
è chiamato a disegnare i dati. Esistono diverse funzioni draw()
per diversi tipi di grafici e la funzione per i grafici a linee è Chart.controllers.line.prototype.draw
. Le funzioni draw()
accettano un argomento, che chiamerò animationFraction
, che indica la completezza dell'animazione come frazione. Ad esempio, se un'animazione è completa al 5%, animationFraction
sarà 0,05 e se un'animazione è completa al 100% (ovvero se il grafico è nella sua forma finale), animationFraction=1
. La funzione draw()
viene richiamata in ogni fase dell'animazione per aggiornare la visualizzazione dei dati.
Una trucco animare l'asse x è quindi di scimmia correggere il grafico a linee draw()
funzione di tradurre la tela nella dimensione orizzontale in ogni disegnare passo:
var hShift = (1-animationFraction)*ctx.canvas.width;
hShift
è lo spostamento orizzontale in pixel del grafico. Come sopra definito, i dati scorreranno da destra; se vuoi che scorra da sinistra, puoi rendere negativo il precedente. È quindi salvare lo stato contesto tela, di trasformare la tela utilizzando hShift
, disegna i dati del grafico, e quindi ripristinare la tela al suo stato originale in modo che la prossima animazione fotogramma gli assi saranno disegnate nel punto corretto:
ctx.save();
ctx.setTransform(1, 0, 0, 1, hShift, 0);
ctx.oldDraw.call(this, animationFraction);
ctx.restore();
In quanto sopra, this
si riferisce all'oggetto grafico e oldDraw
si riferisce alla funzione di disegno grafico a linea originale che è stato salvato in precedenza:
var oldDraw = Chart.controllers.line.prototype.draw;
È possibile inoltre configurare il nuovo draw()
funzione per leggere nuove opzioni di animazione che permettono tu per impostare wheth er l'asse xe asse y sono animati:
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);
}
}
È quindi possibile creare un grafico linea con entrambi gli assi animati con:
var lineChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
animation: {
duration: 5000,
xAxis: true,
yAxis: true,
}
}
});
Vedere https://jsfiddle.net/16L8sk2p/ per una demo.
Se si desidera animare l'asse X Limiti
Se si desidera animare i limiti dell'asse x - cioè. sposta i dati, le tacche degli assi e le etichette di spunta, quindi puoi utilizzare la seguente strategia. È un po 'bizzarro, quindi potrebbe essere necessario uno sforzo per risolvere i nodi per ogni caso d'uso, ma credo che dovrebbe funzionare in generale. Innanzitutto, è necessario convertire il grafico a linee in un grafico a dispersione. I grafici a linee hanno assi X categoriali che si muovono a passi, quindi non è possibile impostare i limiti degli assi tra i tick, che è quello che devi fare per ottenere l'animazione. Quindi, dovrai utilizzare un grafico a dispersione lineare, poiché i grafici a dispersione possono avere limiti di assi arbitrari. Puoi farlo numerando ogni punto dati e assegnando quel numero al valore x per quel punto dati. Per esempio, per generare un insieme di dati a caso, si potrebbe fare:
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));
}
Avrete quindi bisogno di scrivere una funzione per la conversione tra i valori x assegnati dei punti di dati e le etichette dei punti dati (vale a dire la categorie che saranno nelle classifiche asse 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];
}
}
dove Linechart è il nostro oggetto Chart, che sarà definita di seguito. Nota che ChartJS disegna il grafico in modo leggermente diverso se c'è un'etichetta al valore minimo dell'asse x, quindi dovrai scrivere questa funzione per restituire una stringa vuota se il valore == il valore minimo dell'asse x. È quindi possibile definire l'oggetto Chart:
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 è impostata la nostra funzione getXAxisLabel
sopra. Quando ChartJS disegna l'asse x, passerà i valori x dei punti dati alla funzione di callback e quindi utilizzerà la stringa risultante come valore sull'asse x. In questo modo, possiamo disegnare un grafico a dispersione come un grafico a linee. Ho anche impostato autoSkip=false
e maxRotation=0
per assicurarmi che le etichette degli assi vengano disegnate in modo coerente.
È quindi possibile animare il grafico regolando i valori dell'asse x ticks.min
e ticks.max
e chiamando il metodo .update()
del grafico. Per illustrare ciò, il codice seguente esegue la scansione lungo l'asse x del grafico, mostrando dieci punti dati alla volta.
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();
Mettere tutto insieme: https://jsfiddle.net/qLhojncy/
non è chiaro se si stava chiedendo circa animare i dati del grafico nella dimensione X come CTG ha fatto seguito, o se si intende animare le etichette sulla X- asce (che è quello che ho preso la tua domanda per dire, ed è quello che stavo cercando quando ho creato la taglia), che nessuna risposta qui indirizzo. Potresti chiarire? – Aerovistae