Ridimensionamento della tela Chart.js


86

In ( Android WebView HTML5 canvas error ) ho pubblicato una domanda riguardante la stampa di grafici utilizzando la libreria Graph.js. Il problema che ho ora è che se chiamo la funzione per tracciare il grafico più volte, la tela si ridimensiona ogni volta. Ogni volta che il grafico viene ridisegnato sulla stessa tela, anche la sua dimensione cambia. Ho anche provato a impostare le dimensioni della tela ma senza successo.

Quale potrebbe essere il motivo? Perché la tela si ridimensiona ogni volta?


Ora la loro pagina è dedicata a quel sito web ufficiale di Chart.js, qui: chartjs.org/docs/latest/general/responsive.html Ha testato la soluzione e funziona perfettamente.
Amine27,

Risposte:


175

Ho avuto molti problemi con questo, perché dopo tutto ciò la mia grafica al tratto sembrava terribile quando il mouse si spostava e ho trovato un modo più semplice per farlo, spero che possa aiutare :)

Usa queste opzioni Chart.js:

// Boolean - whether or not the chart should be responsive and resize when the browser does.

responsive: true,

// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container

maintainAspectRatio: false,

Grazie @NoFlag per la risposta. Per me gli attributi di altezza e larghezza non venivano applicati alla tela, nel caso qualcuno finisse qui alla ricerca di una soluzione per provare a ridimensionare la tela, prova a impostare responsive su true. * Chart.defaults.global.responsive = false *
sghosh968

13
Non dimenticare che affinché questo metodo funzioni correttamente, devi posizionare la tela in una <div>e impostare l'altezza e / o la larghezza su detta <div>invece della tela.
totymedli

2
Questi flag sono ora impostati per impostazione predefinita true, quindi non è necessario toccarli: chartjs.org/docs/latest/general/responsive.html
João Pimentel Ferreira

Insieme a questo, imposta anche la larghezza e l'altezza della tela. Allora funziona bene. Grazie
Mazhar MIK

63

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);

Mi sono imbattuto in questo errore: Uncaught ReferenceError: pastenutData non è definito
Dulith De Costa

11
Err. sì, questa è solo una variabile segnaposto lì, poiché semplicemente non so quali dati stavi tentando di rappresentare graficamente.
jcmiller11

26

Questo funziona per me:

<body>
    <form>
        [...]
        <div style="position:absolute; top:60px; left:10px; width:500px; height:500px;">
            <canvas id="cv_values"></canvas>

            <script type="text/javascript">
                var indicatedValueData = {
                    labels: ["1", "2", "3"],
                    datasets: [
                        {
                            [...]
                        };

                var cv_values = document.getElementById("cv_values").getContext("2d");
                var myChart = new Chart(cv_values, { type: "line", data: indicatedValueData });
            </script>
        </div>
    </form>
</body>

Il fatto essenziale è che dobbiamo impostare la dimensione della tela nel tag div.


essere d'accordo! posiziona semplicemente la tela all'interno di un div, quindi assicurati che l'opzione per "responsive" NON sia falsa (è vera per impostazione predefinita). Quindi applica la regola di dimensionamento al div.
NoelB

20

In IOS e Android il browser nasconde la barra degli strumenti durante lo scorrimento, cambiando così la dimensione della finestra che gira il grafico principale per ridimensionare il grafico. La soluzione è mantenere le proporzioni.

var options = { 
    responsive: true,
    maintainAspectRatio: true
}

Questo dovrebbe risolvere il tuo problema.


6

Come suggerito da jcmiller11, impostare la larghezza e l'altezza aiuta. Una soluzione leggermente più carina è recuperare la larghezza e l'altezza della tela prima di disegnare il grafico. Quindi utilizzare quei numeri per impostare il grafico su ogni successivo ridisegno del grafico. Questo assicura che non ci siano costanti nel codice javascript.

ctx.canvas.originalwidth = ctx.canvas.width;
ctx.canvas.originalheight = ctx.canvas.height;

function drawchart() {
    ctx.canvas.width = ctx.canvas.originalwidth;
    ctx.canvas.height = ctx.canvas.originalheight;

    var chartctx = new Chart(ctx);
    myNewBarChart = chartctx.Bar(data, chartSettings); 
}

Non ho capito, potresti spiegare come funziona? Ad esempio, apro una pagina, quindi la tela ha una dimensione, ma se ridimensiono la finestra e la tela avrà una dimensione diversa (e presumibilmente non ho bisogno della dimensione originale perché era per la dimensione precedente della finestra)?
kiradotee

6

Ho dovuto usare una combinazione di più risposte qui con alcune piccole modifiche.

Innanzitutto, è necessario avvolgere l'elemento canvas all'interno di un contenitore a livello di blocco. Ti dico, non lasciare che l'elemento tela abbia fratelli; lascia che sia un bambino solitario, perché è testardo e viziato . (L'involucro potrebbe non aver bisogno di alcuna restrizione di dimensionamento su di esso, ma per sicurezza potrebbe essere opportuno applicare un'altezza massima.)

Dopo esserti assicurato che le condizioni precedenti siano soddisfatte, quando si avvia il grafico, assicurarsi che vengano utilizzate le seguenti opzioni:

var options = { 
    "responsive": true,
    "maintainAspectRatio": false
}

Se desideri regolare l'altezza del grafico, fallo a livello di elemento canvas.

<canvas height="500"></canvas>

Non cercare di trattare con il bambino in nessun altro modo. Questo dovrebbe tradursi in un grafico soddisfacente e ben strutturato, che rimanga nella sua culla pacificamente.


3

Ho avuto un problema simile e ho trovato la tua risposta .. Alla fine sono arrivato a una soluzione.

Sembra che il sorgente di Chart.js abbia quanto segue (presumibilmente perché non dovrebbe essere rieseguito e un grafico completamente diverso nella stessa tela):

    //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
if (window.devicePixelRatio) {
    context.canvas.style.width = width + "px";
    context.canvas.style.height = height + "px";
    context.canvas.height = height * window.devicePixelRatio;
    context.canvas.width = width * window.devicePixelRatio;
    context.scale(window.devicePixelRatio, window.devicePixelRatio);
}

Questo va bene se viene chiamato una volta, ma quando ridisegni più volte finisci per cambiare la dimensione dell'elemento DOM canvas più volte causando un ridimensionamento.

Spero che aiuti!


1

Se qualcuno ha problemi, ho trovato una soluzione che non comporta il sacrificio della reattività, ecc.

Avvolgi semplicemente la tua tela in un contenitore div (senza stile) e reimposta il contenuto del div su una tela vuota con ID prima di chiamare il costruttore del grafico.

Esempio:

HTML:

<div id="chartContainer">
    <canvas id="myChart"></canvas>
</div>

JS:

$("#chartContainer").html('<canvas id="myChart"></canvas>');
//call new Chart() as usual

1

Ho provato a ridimensionare la tela usando jQuery ma non ha funzionato bene. Penso che CSS3 sia l'opzione migliore che puoi provare, se vuoi zoomare al passaggio del mouse a un certo livello.

Seguente opzione hover da un altro collegamento codepan:

.style_prevu_kit:hover{
    z-index: 2;
    -webkit-transition: all 200ms ease-in;
    -webkit-transform: scale(1.5);
    -ms-transition: all 200ms ease-in;
    -ms-transform: scale(1.5);   
    -moz-transition: all 200ms ease-in;
    -moz-transform: scale(1.5);
    transition: all 200ms ease-in;
    transform: scale(1.5);
}

Segui il mio link codepan:

https://codepen.io/hitman0775/pen/XZZzqN


1

Avevo lo stesso problema. Sono stato in grado di risolverlo impostando l'opzione:

responsive: false,
maintainAspectRatio: true,
showScale: false,

E in CSS, imposta la larghezza del div contenitore uguale alla tela:

    #canvasContainer { 
      width: 300px;
    }
    
    canvas {
      width: 300px;
    }


0

Ho avuto lo stesso tipo di problema di ridimensionamento utilizzando Angular CLI. È riuscito a farlo funzionare rimuovendo questa riga da index.html:

<script src="node_modules/chart.js/dist/Chart.bundle.min.js"></script>

e poi nel file angular-cli.json, nella sezione degli script, usando questo:

"scripts": ["../node_modules/chart.js/dist/Chart.bundle.min.js"]

Fonte : mikebarr58


-3

Aggiungi dive risolverà il problema

<div style="position:absolute; top:50px; left:10px; width:500px; height:500px;"></div>

-5
 let canvasBox = ReactDOM.findDOMNode(this.refs.canvasBox);
 let width = canvasBox.clientWidth;
 let height = canvasBox.clientHeight;
 let charts = ReactDOM.findDOMNode(this.refs.charts);
 let ctx = charts.getContext('2d');
 ctx.canvas.width = width;
 ctx.canvas.height = height;
 this.myChart = new Chart(ctx);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.