Quello che sta succedendo è Chart.js moltiplica le dimensioni della tela quando viene chiamato, quindi tenta di ridimensionarlo utilizzando CSS, lo scopo è fornire grafici a risoluzione più elevata per dispositivi ad alta risoluzione.
Il problema è che non si rende conto di averlo già fatto, quindi quando viene chiamato più volte, moltiplica ANCORA la dimensione già (raddoppiata o qualsiasi altra cosa) finché le cose non iniziano a rompersi. (Quello che sta realmente accadendo è controllare se è necessario aggiungere più pixel alla tela modificando l'attributo DOM per larghezza e altezza, se necessario, moltiplicandolo per qualche fattore, di solito 2, quindi cambiandolo e quindi cambiando lo stile CSS attributo per mantenere la stessa dimensione sulla pagina.)
Ad esempio, quando lo esegui una volta e la larghezza e l'altezza della tua tela sono impostate su 300, le imposta su 600, quindi cambia l'attributo di stile su 300 ... ma se lo esegui di nuovo, vede che la larghezza e l'altezza del DOM sono 600 (controlla l'altra risposta a questa domanda per vedere perché) e poi lo imposta a 1200 e la larghezza e l'altezza css a 600.
Non è la soluzione più elegante, ma ho risolto questo problema mantenendo la risoluzione migliorata per i dispositivi retina semplicemente impostando manualmente la larghezza e l'altezza della tela prima di ogni chiamata successiva a Chart.js
var ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.width = 300;
ctx.canvas.height = 300;
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);