Ich benutze Chart.js. Ich versuche, das Diagramm in ein Bild zu konvertieren, indem ich eine 64-Zeichenfolge erhalte. Das Tutorial (http://www.chartjs.org/docs/) widmet eine ganze Zeile das Thema:

Das Canvas-Element ermöglicht auch das Speichern des Inhalts als Basis-64-Zeichenfolge, wodurch das Diagramm als Bild gespeichert werden kann.

Ein canvas -Element hat die Methode toDataURL, die eine base64-Zeichenfolge des Bildes zurückgibt. Wenn ich das mache, ist das gerenderte Bild jedoch nur ein transparentes Rechteck mit den Abmessungen des Diagramms und enthält nicht den Diagramminhalt.

Hier ist eine Geige: http://jsfiddle.net/KSgV7/

Die "Bilder" in der Geige sind mit einem schwarzen Rand versehen, sodass Sie sehen können, wo sie sich befinden sollen, da sie nur ein großer transparenter Block zu sein scheinen.

Hat jemand ein Chart.js-Diagramm erfolgreich in ein Bild konvertiert?

35
chiliNUT 26 Nov. 2013 im 04:02

7 Antworten

Beste Antwort

Das Diagramm scheint asynchron zu sein, daher müssen Sie wahrscheinlich einen Rückruf bereitstellen, wenn die Animation beendet ist, da sonst die Leinwand leer ist.

var options = {
    bezierCurve : false,
    onAnimationComplete: done  /// calls function done() {} at end
};
30
26 Dez. 2016 im 12:58

@EH_warch Sie müssen den vollständigen Rückruf verwenden, um Ihre base64 zu generieren:

onAnimationComplete: function(){
    console.log(this.toBase64Image())
}

Wenn Sie ein weißes Bild sehen, haben Sie toBase64Image aufgerufen, bevor das Rendern abgeschlossen ist.

0
Matti LeBlanc 9 Sept. 2015 im 02:58

Sie sollten stattdessen die Chartjs-API-Funktion toBase64Image() verwenden und sie nach Abschluss der Animation aufrufen. Deshalb:

var pieChart, URI;

var options = {
    animation : {
        onComplete : function(){    
            URI = pieChart.toBase64Image();
        }
    }
};

var content = {
    type: 'pie', //whatever, not relevant for this example
    data: {
        datasets: dataset //whatever, not relevant for this example
    },
    options: options        
};    

pieChart = new Chart(pieChart, content);

Beispiel

Sie können dieses Beispiel überprüfen und ausführen

var chart = new Chart(ctx, {
   type: 'bar',
   data: {
      labels: ['Standing costs', 'Running costs'], // responsible for how many bars are gonna show on the chart
      // create 12 datasets, since we have 12 items
      // data[0] = labels[0] (data for first bar - 'Standing costs') | data[1] = labels[1] (data for second bar - 'Running costs')
      // put 0, if there is no data for the particular bar
      datasets: [{
         label: 'Washing and cleaning',
         data: [0, 8],
         backgroundColor: '#22aa99'
      }, {
         label: 'Traffic tickets',
         data: [0, 2],
         backgroundColor: '#994499'
      }, {
         label: 'Tolls',
         data: [0, 1],
         backgroundColor: '#316395'
      }, {
         label: 'Parking',
         data: [5, 2],
         backgroundColor: '#b82e2e'
      }, {
         label: 'Car tax',
         data: [0, 1],
         backgroundColor: '#66aa00'
      }, {
         label: 'Repairs and improvements',
         data: [0, 2],
         backgroundColor: '#dd4477'
      }, {
         label: 'Maintenance',
         data: [6, 1],
         backgroundColor: '#0099c6'
      }, {
         label: 'Inspection',
         data: [0, 2],
         backgroundColor: '#990099'
      }, {
         label: 'Loan interest',
         data: [0, 3],
         backgroundColor: '#109618'
      }, {
         label: 'Depreciation of the vehicle',
         data: [0, 2],
         backgroundColor: '#109618'
      }, {
         label: 'Fuel',
         data: [0, 1],
         backgroundColor: '#dc3912'
      }, {
         label: 'Insurance and Breakdown cover',
         data: [4, 0],
         backgroundColor: '#3366cc'
      }]
   },
   options: {
      responsive: false,
      legend: {
         position: 'right' // place legend on the right side of chart
      },
      scales: {
         xAxes: [{
            stacked: true // this should be set to make the bars stacked
         }],
         yAxes: [{
            stacked: true // this also..
         }]
      },
      animation : {
         onComplete : done
      }      
   }
});

function done(){
    alert(chart.toBase64Image());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="ctx" width="700"></canvas>
2
João Pimentel Ferreira 31 März 2018 im 21:49

Die Chart.JS-API hat sich geändert, seit dies veröffentlicht wurde, und ältere Beispiele schienen für mich nicht zu funktionieren. Hier ist eine aktualisierte Geige, die auf den neueren Versionen funktioniert

HTML:

<body>
    <canvas id="canvas" height="450" width="600"></canvas>
    <img id="url" />
</body>

JS:

function done(){
  alert("haha");
  var url=myLine.toBase64Image();
  document.getElementById("url").src=url;
}

var options = {
  bezierCurve : false,
  animation: {
    onComplete: done
  }
};

var myLine = new 
   Chart(document.getElementById("canvas").getContext("2d"),
     {
        data:lineChartData,
        type:"line",
        options:options
      }
    );

http://jsfiddle.net/KSgV7/585/

17
c.j.mcdonn 17 Jän. 2019 im 19:20

Konvertieren Sie zuerst Ihre Chart.js-Zeichenfläche in einen base64-String.

var url_base64 = document.getElementById('myChart').toDataURL('image/png');

Legen Sie es als href-Attribut für das Ankertag fest.

link.href = url_base64;

<a id='link' download='filename.png'>Save as Image</a>

7
Hitesh Rathod 22 Aug. 2016 im 09:52

Sie können mit plugins auf den afterRender Hook zugreifen.

Und hier sind alle Plugin-APIs verfügbar .

In der HTML-Datei:

<html>
  <canvas id="myChart"></canvas>
  <div id="imgWrap"></div>
</html>

In js Datei:

var chart = new Chart(ctx, {
  ...,
  plugins: [{
    afterRender: function () {
      // Do anything you want
      renderIntoImage()
    },
  }],
  ...,
});

const renderIntoImage = () => {
  const canvas = document.getElementById('myChart')
  const imgWrap = document.getElementById('imgWrap')
  var img = new Image();
  img.src = canvas.toDataURL()
  imgWrap.appendChild(img)
  canvas.style.display = 'none'
}
0
Lulala Chen 15 Juli 2017 im 09:48

Sie können auch die Animationseinstellung toBase64Image () verwenden: false

var options = {
    bezierCurve : false,
    animation: false
};

Geige aktualisiert

-1
tudo75 22 Nov. 2014 im 02:10