Ich habe eine einfache App, die Bootstrap, vue.js und chart.js verwendet. Die HTML-Vorlage ist ziemlich einfach. Bei der Suche nach meinem Fehler ist mir aufgefallen, dass dieses Problem häufig beim Rendern eines Diagramms in einer Registerkarte oder in einem Modal auftritt, aber ich habe mein Diagramm nicht in einem Modal oder Tab.Chart.js rendern nicht mit vue.js, bis das Fenster die Größe ändert
Sobald ich die Größe meines Browserfensters ändere, wird das Diagramm korrekt gerendert und skaliert, damit es in das div und alles passt.
Aus welchen Gründen auch immer, wenn die Seite geladen wird, macht die Leinwand HTML-Tag wie folgt aus:
<canvas id="graph" width="0" height="0" style="margin: auto; width: 0px; display: block; height: 0px;"></canvas>
Aber wenn ich die Fenster, alles ändert sich die Größe und ich sehe richtig das Diagramm.
<canvas id="graph" width="493" height="328" style="margin: auto; width: 493px; display: block; height: 328px;"></canvas>
Warum ist es nicht die Höhe & Breite korrekte Laden der Seite bekommen?
HTML-Vorlage
<div class="panel panel-default">
<div class="panel-heading">Chart List</div>
<div class="panel-body">
<div class="row">
<div class="col-sm-6">
<defaultchart>
</defaultchart>
</div>
<div class="col-sm-6">
<chartlistview
:data="{{ $private }}"
:columns="{{ json_encode($columns) }}"
>
</chartlistview>
</div>
</div>
</div>
</div>
DefaultChart.vue
<template>
<div>
<canvas
id="graph"
v-el:canvas
width="600"
height="400"
style="margin:auto; width: 600px;"
></canvas>
</div>
</template>
<script>
export default {
data() {
return {
ourChart: '',
chartData: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3]
}]
}
};
},
ready() {
this.drawChart();
},
methods: {
drawChart: function() {
if (this.ourChart) {
this.ourChart.destroy();
}
var context = document.querySelector('#graph').getContext('2d');
this.ourChart = new Chart(context, {
type: 'line',
data: this.chartData
// wouldn't render at all with this regardless of resizing
/*options: {
response: true,
maintainAspectRatio: false
}*/
});
// added these lines to see if it would fix the issue; it didn't
this.ourChart.render();
this.ourChart.update();
}
}
};
</script>
Wow, das hat funktioniert. Vielen Dank! Frage aber. Ist das ein Fehler in Vue? Ich würde denken, dass die Methode 'ready()' genauso funktionieren würde wie in jQuery. Oder benutzte ich es falsch und ich sollte immer '$ nextTick' verwenden? – Nathan
Nein, es ist kein Fehler in Vue. Wie gesagt, Vue [aktualisiert das DOM asynchron] (http://vuejs.org/guide/reactivity.html#Async-Update-Queue) aus Leistungsgründen, was bedeutet, dass wenn Vue sagt "setze dieses Element in das DOM" , und feuert den ready() - Haken danach, "dieses Element" ist möglicherweise noch nicht im DOM. Da dies eine der häufigsten Fallstricke ist, denen die Leute zu begegnen scheinen, werde ich vorschlagen, sie den Dokumenten besser hinzuzufügen. –
OK, das macht Sinn. Ich ging davon aus, dass Vue auf einen Ereignis-Callback vom Browser wartete, als das DOM tatsächlich fertig war. – Nathan