Bagaimana cara menambahkan teks di dalam bagan donat menggunakan Chart.js?


Jawaban:


38

Anda harus mengubah kode seperti: in chart.Doughnut.defaults

labelFontFamily : "Arial",
labelFontStyle : "normal",
labelFontSize : 24,
labelFontColor : "#666"

dan kemudian berfungsi drawPieSegments

ctx.fillText(data[0].value + "%", width/2 - 20, width/2, 200);

Lihat tarikan ini: https://github.com/nnnick/Chart.js/pull/35

berikut adalah biola http://jsfiddle.net/mayankcpdixit/6xV78/ menerapkan hal yang sama.


2
Apakah ada orang lain yang tidak dapat menemukan fungsi drawPieSegments ini?
Yulian

2
Perlu disebutkan bahwa itu tidak berfungsi dengan v2. Gunakan kode jsfiddle yang disertakan agar mudah digunakan
Alwin Kesler

1
Bagaimana cara menambahkan% di baris baru? apakah ini didukung?
pengguna7334203

1
Masih ini solusinya?
ACB

@ ArunC.B - gulir ke bawah
ashleedawg

179

Tidak ada jawaban lain yang mengubah ukuran teks berdasarkan jumlah teks dan ukuran donat. Berikut ini skrip kecil yang dapat Anda gunakan untuk secara dinamis menempatkan sejumlah teks di tengah, dan secara otomatis akan mengubah ukurannya.

Contoh: http://jsfiddle.net/kdvuxbtj/

Donat Dengan Teks Dinamis di Tengah

Ini akan membutuhkan teks dalam jumlah berapa pun yang berukuran sempurna untuk donat. Untuk menghindari menyentuh tepi, Anda dapat mengatur bantalan samping sebagai persentase dari diameter bagian dalam lingkaran. Jika Anda tidak mengaturnya, maka defaultnya adalah 20. Anda juga akan memilih warna, font, dan teks. Plugin akan menangani sisanya.

Kode plugin akan dimulai dengan ukuran font dasar 30px. Dari sana itu akan memeriksa lebar teks dan membandingkannya dengan jari-jari lingkaran dan mengubah ukurannya berdasarkan rasio lebar lingkaran / teks.

Ini memiliki ukuran font minimum default 20px. Jika teks melebihi batas pada ukuran font minimum, itu akan membungkus teks. Tinggi garis default saat membungkus teks adalah 25px, tetapi Anda dapat mengubahnya. Jika Anda menyetel ukuran font minimum default ke false, teks akan menjadi sangat kecil dan tidak akan terbungkus.

Ini juga memiliki ukuran font maks default 75px jika tidak ada cukup teks dan hurufnya akan terlalu besar.

Ini adalah kode plugin

Chart.pluginService.register({
  beforeDraw: function(chart) {
    if (chart.config.options.elements.center) {
      // Get ctx from string
      var ctx = chart.chart.ctx;

      // Get options from the center object in options
      var centerConfig = chart.config.options.elements.center;
      var fontStyle = centerConfig.fontStyle || 'Arial';
      var txt = centerConfig.text;
      var color = centerConfig.color || '#000';
      var maxFontSize = centerConfig.maxFontSize || 75;
      var sidePadding = centerConfig.sidePadding || 20;
      var sidePaddingCalculated = (sidePadding / 100) * (chart.innerRadius * 2)
      // Start with a base font of 30px
      ctx.font = "30px " + fontStyle;

      // Get the width of the string and also the width of the element minus 10 to give it 5px side padding
      var stringWidth = ctx.measureText(txt).width;
      var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;

      // Find out how much the font can grow in width.
      var widthRatio = elementWidth / stringWidth;
      var newFontSize = Math.floor(30 * widthRatio);
      var elementHeight = (chart.innerRadius * 2);

      // Pick a new font size so it will not be larger than the height of label.
      var fontSizeToUse = Math.min(newFontSize, elementHeight, maxFontSize);
      var minFontSize = centerConfig.minFontSize;
      var lineHeight = centerConfig.lineHeight || 25;
      var wrapText = false;

      if (minFontSize === undefined) {
        minFontSize = 20;
      }

      if (minFontSize && fontSizeToUse < minFontSize) {
        fontSizeToUse = minFontSize;
        wrapText = true;
      }

      // Set font settings to draw it correctly.
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
      var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
      ctx.font = fontSizeToUse + "px " + fontStyle;
      ctx.fillStyle = color;

      if (!wrapText) {
        ctx.fillText(txt, centerX, centerY);
        return;
      }

      var words = txt.split(' ');
      var line = '';
      var lines = [];

      // Break words up into multiple lines if necessary
      for (var n = 0; n < words.length; n++) {
        var testLine = line + words[n] + ' ';
        var metrics = ctx.measureText(testLine);
        var testWidth = metrics.width;
        if (testWidth > elementWidth && n > 0) {
          lines.push(line);
          line = words[n] + ' ';
        } else {
          line = testLine;
        }
      }

      // Move the center up depending on line height and number of lines
      centerY -= (lines.length / 2) * lineHeight;

      for (var n = 0; n < lines.length; n++) {
        ctx.fillText(lines[n], centerX, centerY);
        centerY += lineHeight;
      }
      //Draw text in center
      ctx.fillText(line, centerX, centerY);
    }
  }
});

Dan Anda menggunakan opsi berikut di objek bagan Anda

options: {
  elements: {
    center: {
      text: 'Red is 2/3 the total numbers',
      color: '#FF6384', // Default is #000000
      fontStyle: 'Arial', // Default is Arial
      sidePadding: 20, // Default is 20 (as a percentage)
      minFontSize: 20, // Default is 20 (in px), set to false and text will not wrap.
      lineHeight: 25 // Default is 25 (in px), used for when text wraps
    }
  }
}

Penghargaan untuk @Jenna Sloan atas bantuannya dalam matematika yang digunakan dalam solusi ini.


5
Bekerja dengan baik! Sebagian besar opsi lain terputus ketika legenda ada di kanan atau kiri.
louisav

2
Solusi luar biasa!
JustLooking

3
Saya memperbarui biola Anda dan menambahkan ukuran font maksimum: jsfiddle.net/nkzyx50o/3059
Felix Geenen

4
Mungkinkah untuk membagi teks menjadi beberapa baris? Teks saya memiliki 6 kata dan meluap di antara batas-batas guntingan
Quanda

2
Terima kasih, ini juga berfungsi untuk saya, tetapi bagaimana cara menambahkan teks multi baris?
Ashutosh Shrestha

54

Berikut adalah contoh yang dibersihkan dan gabungan dari solusi di atas - responsif (coba ubah ukuran jendela), mendukung penyelarasan otomatis animasi, mendukung tooltips

https://jsfiddle.net/cmyker/u6rr5moq/

Chart.types.Doughnut.extend({
    name: "DoughnutTextInside",
    showTooltip: function() {
        this.chart.ctx.save();
        Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments);
        this.chart.ctx.restore();
    },
    draw: function() {
        Chart.types.Doughnut.prototype.draw.apply(this, arguments);

        var width = this.chart.width,
            height = this.chart.height;

        var fontSize = (height / 114).toFixed(2);
        this.chart.ctx.font = fontSize + "em Verdana";
        this.chart.ctx.textBaseline = "middle";

        var text = "82%",
            textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2),
            textY = height / 2;

        this.chart.ctx.fillText(text, textX, textY);
    }
});

var data = [{
    value: 30,
    color: "#F7464A"
}, {
    value: 50,
    color: "#E2EAE9"
}, {
    value: 100,
    color: "#D4CCC5"
}, {
    value: 40,
    color: "#949FB1"
}, {
    value: 120,
    color: "#4D5360"
}];

var DoughnutTextInsideChart = new Chart($('#myChart')[0].getContext('2d')).DoughnutTextInside(data, {
    responsive: true
});
<html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<body>
    <canvas id="myChart"></canvas>
</body>
</html>

UPDATE 17.06.16:

Fungsionalitas yang sama tetapi untuk chart.js versi 2:

https://jsfiddle.net/cmyker/ooxdL2vj/

var data = {
  labels: [
    "Red",
    "Blue",
    "Yellow"
  ],
  datasets: [
    {
      data: [300, 50, 100],
      backgroundColor: [
        "#FF6384",
        "#36A2EB",
        "#FFCE56"
      ],
      hoverBackgroundColor: [
        "#FF6384",
        "#36A2EB",
        "#FFCE56"
      ]
    }]
};

Chart.pluginService.register({
  beforeDraw: function(chart) {
    var width = chart.chart.width,
        height = chart.chart.height,
        ctx = chart.chart.ctx;

    ctx.restore();
    var fontSize = (height / 114).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.textBaseline = "middle";

    var text = "75%",
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

    ctx.fillText(text, textX, textY);
    ctx.save();
  }
});

var chart = new Chart(document.getElementById('myChart'), {
  type: 'doughnut',
  data: data,
  options: {
  	responsive: true,
    legend: {
      display: false
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>


3
Saya mendapatkan Uncaught TypeError: Cannot read property 'extend' of undefinedide?
Max Rose-Collins

2
Juga, Anda bisa mengubah warna teks menggunakan ctx.fillStyle = 'black';
Adrian Lopez

ini terus menulis teks lagi dan lagi jika bagan disegarkan dengan memberikan parameter data baru
techie_28

Sudahkah Anda menemukan solusi untuk itu?
Cmyker

@Cmyker solusi CSS / HTML dapat membantu tetapi itu tidak mengekspor teks tengah saat bagan diekspor sebagai PNG. Adakah ide untuk memperbaiki ini? Ini adalah solusi lengkap hanya saja tidak membersihkan area tengah saat bagan di-refresh .
techie_28

38

Saya akan menghindari memodifikasi kode chart.js untuk mencapai ini, karena cukup mudah dengan CSS dan HTML biasa. Inilah solusi saya:

HTML:

<canvas id="productChart1" width="170"></canvas>
<div class="donut-inner">
    <h5>47 / 60 st</h5>
    <span>(30 / 25 st)</span>
</div>

CSS:

.donut-inner {
   margin-top: -100px;
   margin-bottom: 100px;
}
.donut-inner h5 {
   margin-bottom: 5px;
   margin-top: 0;
}
.donut-inner span {
   font-size: 12px;
}

Outputnya terlihat seperti ini:

masukkan deskripsi gambar di sini


5
Kenapa tidak? Cukup tambahkan @ media-queries ke kelas Anda.
Mattias

2
Itu tidak berhasil untuk saya, saya menggunakan cara yang responsif, jadi saya tidak bisa menggunakan nilai tetap. :(
Massa

2
@Massa Sudahkah Anda mencoba menggunakan kueri media untuk berbagai resolusi? Atau memodifikasi css yang saya tulis menggunakan%, bukan px?
Mattias

2
@Mattias ini adalah solusi yang bagus tetapi teks pusat tidak diekspor ketika bagan diunduh sebagai PNG.
techie_28

1
@ techie_28 poin yang valid, tidak memperhitungkannya karena pertanyaan tidak menyebutkan ekspor sama sekali.
Mattias

21

Ini juga bekerja di akhir saya ...

<div style="width: 100px; height: 100px; float: left; position: relative;">
    <div
        style="width: 100%; height: 40px; position: absolute; top: 50%; left: 0; margin-top: -20px; line-height:19px; text-align: center; z-index: 999999999999999">
        99%<Br />
        Total
    </div>
    <canvas id="chart-area" width="100" height="100" />
</div>

masukkan deskripsi gambar di sini


5
Saya menggunakan solusi Anda karena itu yang tercepat dan melakukan tugasnya. Terima kasih!
MDT

@Amrik Singh ini memang solusi yang bagus tetapi teks tengah tidak akan diekspor jika bagan diunduh sebagai gambar PNG.
techie_28

Solusi bagus, Tidak perlu banyak repot.
Shashank

kamu adalah teman saya! Saya tidak dapat menemukan solusi di angularjs dan tidak pernah melakukan seperti ini. Luar biasa.
Nomi Ali

1
perbaikan yang indah, cepat dan bersih
Khaleel

11

Berdasarkan jawaban @ rap-2-h, Berikut kode untuk menggunakan teks pada diagram donat di Chart.js untuk digunakan di dashboard seperti. Ini memiliki ukuran font dinamis untuk opsi responsif.

HTML:

<div>text
<canvas id="chart-area" width="300" height="300" style="border:1px solid"/><div>

Naskah:

var doughnutData = [
            {
                value: 100,
                color:"#F7464A",
                highlight: "#FF5A5E",
                label: "Red"
            },
            {
                value: 50,
                color: "#CCCCCC",
                highlight: "#5AD3D1",
                label: "Green"
            }
        ];

$(document).ready(function(){
  var ctx = $('#chart-area').get(0).getContext("2d");

  var myDoughnut = new Chart(ctx).Doughnut(doughnutData,{
     animation:true,
     responsive: true,
     showTooltips: false,
     percentageInnerCutout : 70,
     segmentShowStroke : false,
     onAnimationComplete: function() {

     var canvasWidthvar = $('#chart-area').width();
     var canvasHeight = $('#chart-area').height();
     //this constant base on canvasHeight / 2.8em
     var constant = 114;
     var fontsize = (canvasHeight/constant).toFixed(2);
     ctx.font=fontsize +"em Verdana";
     ctx.textBaseline="middle"; 
     var total = 0;
     $.each(doughnutData,function() {
       total += parseInt(this.value,10);
   });
  var tpercentage = ((doughnutData[0].value/total)*100).toFixed(2)+"%";
  var textWidth = ctx.measureText(tpercentage).width;

   var txtPosx = Math.round((canvasWidthvar - textWidth)/2);
    ctx.fillText(tpercentage, txtPosx, canvasHeight/2);
  }
 });
});

Berikut kode contoh. Coba ubah ukuran jendela. http://jsbin.com/wapono/13/edit


1
Ini harus menjadi jawaban yang diterima dalam kasus kebutuhan akan daya tanggap (kasus saya).
Greg Blass

2
Jika Anda memiliki keterangan alat, teks tersebut menghilang saat melayang.
Yulian

Kesalahan "pengecualian jQuery.Deferred: Bagan tidak ditentukan"
Kiquenet

11

Anda dapat menggunakan css dengan pemosisian relatif / absolut jika ingin responsif. Selain itu, alat ini dapat menangani multi-line dengan mudah.

https://jsfiddle.net/mgyp0jkk/

<div class="relative">
  <canvas id="myChart"></canvas>      
  <div class="absolute-center text-center">
    <p>Some text</p>
    <p>Some text</p>
  </div>
</div>

solusi yang indah :)
Manza

Kerja Super bro Anda membuat hari saya
DVP SmartCreators Inc kami membuat

8

Ini didasarkan pada pembaruan Cmyker untuk Chart.js 2. (diposting sebagai jawaban lain karena saya belum bisa berkomentar)

Saya mengalami masalah dengan perataan teks di Chrome saat legenda ditampilkan karena tinggi bagan tidak menyertakan ini sehingga tidak disejajarkan dengan benar di tengah. Memperbaiki ini dengan memperhitungkan ini dalam perhitungan fontSize dan textY.

Saya menghitung persentase di dalam metode daripada nilai yang ditetapkan karena saya memiliki beberapa di halaman ini. Asumsinya adalah bagan Anda hanya memiliki 2 nilai (jika tidak, berapa persentasenya? Dan yang pertama adalah yang ingin Anda perlihatkan persentasenya. Saya juga memiliki banyak bagan lain, jadi saya melakukan pemeriksaan untuk type = donut. Saya hanya menggunakan donat untuk menunjukkan persentase jadi itu berhasil untuk saya.

Warna teks tampaknya sedikit terpukul dan terlewat tergantung pada urutan apa yang dijalankan dll jadi saya mengalami masalah saat mengubah ukuran bahwa teks akan berubah warna (antara hitam dan warna primer dalam satu kasus, dan warna sekunder dan putih di kasus lain) jadi Saya "menyimpan" apa pun gaya isian yang ada, menggambar teks (dengan warna data utama) lalu mengembalikan gaya isian yang lama. (Mempertahankan gaya pengisian lama sepertinya tidak diperlukan tetapi Anda tidak pernah tahu.)

https://jsfiddle.net/g733tj8h/

Chart.pluginService.register({
  beforeDraw: function(chart) {
    var width = chart.chart.width,
        height = chart.chart.height,
        ctx = chart.chart.ctx,
        type = chart.config.type;

    if (type == 'doughnut')
    {
      var percent = Math.round((chart.config.data.datasets[0].data[0] * 100) /
                    (chart.config.data.datasets[0].data[0] +
                    chart.config.data.datasets[0].data[1]));
      var oldFill = ctx.fillStyle;
      var fontSize = ((height - chart.chartArea.top) / 100).toFixed(2);

      ctx.restore();
      ctx.font = fontSize + "em sans-serif";
      ctx.textBaseline = "middle"

      var text = percent + "%",
          textX = Math.round((width - ctx.measureText(text).width) / 2),
          textY = (height + chart.chartArea.top) / 2;

      ctx.fillStyle = chart.config.data.datasets[0].backgroundColor[0];
      ctx.fillText(text, textX, textY);
      ctx.fillStyle = oldFill;
      ctx.save();
    }
  }
});


7

Anda juga dapat menempelkan kode mayankcpdixit di onAnimationCompleteopsi:

// ...
var myDoughnutChart = new Chart(ctx).Doughnut(data, {
    onAnimationComplete: function() {
        ctx.fillText(data[0].value + "%", 100 - 20, 100, 200);
    }
});

Teks akan ditampilkan setelah animasi


6
Bagus tapi teksnya menghilang saat melayang
rnaud

1
Benar, teks menghilang saat hover ... :( Alangkah baiknya jika teks tidak hilang, tahu bagaimana melakukan ini? Terima kasih
MDT

@MDT @maud mungkin dengan menggunakan savemetode
techie_28

7

Saya membuat demo dengan 7 jQueryUI Slider dan ChartJs (dengan teks dinamis di dalamnya)

Chart.types.Doughnut.extend({
        name: "DoughnutTextInside",
        showTooltip: function() {
            this.chart.ctx.save();
            Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments);
            this.chart.ctx.restore();
        },
        draw: function() {
            Chart.types.Doughnut.prototype.draw.apply(this, arguments);

            var width = this.chart.width,
                height = this.chart.height;

            var fontSize = (height / 140).toFixed(2);
            this.chart.ctx.font = fontSize + "em Verdana";
            this.chart.ctx.textBaseline = "middle";

            var red = $( "#red" ).slider( "value" ),
            green = $( "#green" ).slider( "value" ),
            blue = $( "#blue" ).slider( "value" ),
            yellow = $( "#yellow" ).slider( "value" ),
            sienna = $( "#sienna" ).slider( "value" ),
            gold = $( "#gold" ).slider( "value" ),
            violet = $( "#violet" ).slider( "value" );
            var text = (red+green+blue+yellow+sienna+gold+violet) + " minutes";
            var textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2);
            var textY = height / 2;
            this.chart.ctx.fillStyle = '#000000';
            this.chart.ctx.fillText(text, textX, textY);
        }
    });


var ctx = $("#myChart").get(0).getContext("2d");
var myDoughnutChart = new Chart(ctx).DoughnutTextInside(data, {
    responsive: false
});

DEMO DI JSFIDDLE

masukkan deskripsi gambar di sini


3

@ rap-2-h dan @Ztuons Ch jawaban tidak memungkinkan showTooltipsopsi untuk aktif, tetapi yang dapat Anda lakukan adalah membuat dan melapisi keduacanvas objek belakang yang menampilkan bagan.

Bagian penting adalah gaya yang diperlukan dalam div dan untuk objek kanvas itu sendiri sehingga mereka ditampilkan di atas satu sama lain.

var data = [
    {value : 100, color : 'rgba(226,151,093,1)', highlight : 'rgba(226,151,093,0.75)', label : "Sector 1"},
    {value : 100, color : 'rgba(214,113,088,1)', highlight : 'rgba(214,113,088,0.75)', label : "Sector 2"},
    {value : 100, color : 'rgba(202,097,096,1)', highlight : 'rgba(202,097,096,0.75)', label : "Sector 3"}
]

var options = { showTooltips : true };
     
var total = 0;
for (i = 0; i < data.length; i++) {
     total = total + data[i].value;
}

var chartCtx = $("#canvas").get(0).getContext("2d");
var chart = new Chart(chartCtx).Doughnut(data, options);

var textCtx = $("#text").get(0).getContext("2d");
textCtx.textAlign = "center";
textCtx.textBaseline = "middle";
textCtx.font = "30px sans-serif";
textCtx.fillText(total, 150, 150);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<html>
<body>
<div style="position: relative; width:300px; height:300px;">
    <canvas id="text" 
            style="z-index: 1; 
                   position: absolute;
                   left: 0px; 
                   top: 0px;" 
            height="300" 
            width="300"></canvas>
    <canvas id="canvas" 
            style="z-index: 2; 
                   position: absolute;
                   left: 0px; 
                   top: 0px;" 
            height="300" 
            width="300"></canvas>
</div>
</body>
</html>

Inilah jsfiddle: https://jsfiddle.net/68vxqyak/1/


1

@Cmyker, solusi hebat untuk chart.js v2

Satu peningkatan kecil: Masuk akal untuk memeriksa id kanvas yang sesuai, lihat cuplikan yang dimodifikasi di bawah ini. Jika tidak, teks (yaitu 75%) juga ditampilkan di tengah jenis bagan lain dalam halaman.

  Chart.pluginService.register({
    beforeDraw: function(chart) {
      if (chart.canvas.id === 'doghnutChart') {
        let width = chart.chart.width,
            height = chart.chart.outerRadius * 2,
            ctx = chart.chart.ctx;

        rewardImg.width = 40;
        rewardImg.height = 40;
        let imageX = Math.round((width - rewardImg.width) / 2),
            imageY = (height - rewardImg.height ) / 2;

        ctx.drawImage(rewardImg, imageX, imageY, 40, 40);
        ctx.save();
      }
    }
  });

Karena sebuah legenda (lihat: http://www.chartjs.org/docs/latest/configuration/legend.html ) memperbesar tinggi bagan, nilai untuk tinggi harus diperoleh dari radius.


0

Pertama-tama, pujian dalam memilih Chart.js! Saya menggunakannya di salah satu proyek saya saat ini dan saya sangat menyukainya - ini melakukan pekerjaan dengan sempurna.

Meskipun label / tooltips belum menjadi bagian dari pustaka, Anda mungkin ingin melihat tiga permintaan tarik berikut:

Dan, seperti yang disebutkan Cracker0dks , Chart.js digunakan canvasuntuk rendering sehingga Anda mungkin juga menerapkan tooltips Anda sendiri dengan berinteraksi dengannya secara langsung.

Semoga ini membantu.


0

Solusi Alesana bekerja dengan sangat baik untuk saya secara umum, tetapi seperti orang lain, saya ingin dapat menentukan di mana jeda baris terjadi. Saya membuat beberapa modifikasi sederhana untuk membungkus baris pada karakter '\ n', selama teks sudah dibungkus. Solusi yang lebih lengkap akan memaksa pembungkusan jika ada karakter '\ n' dalam teks, tetapi saya tidak punya waktu saat ini untuk membuatnya berfungsi dengan ukuran font. Perubahan juga berpusat sedikit lebih baik secara horizontal saat membungkus (menghindari spasi tambahan). Kode di bawah (saya belum bisa mengirim komentar).

Akan keren jika seseorang memasang plugin ini di GitHub ...

Chart.pluginService.register({
  beforeDraw: function(chart) {
    if (chart.config.options.elements.center) {
      // Get ctx from string
      var ctx = chart.chart.ctx;

      // Get options from the center object in options
      var centerConfig = chart.config.options.elements.center;
      var fontStyle = centerConfig.fontStyle || 'Arial';
      var txt = centerConfig.text;
      var color = centerConfig.color || '#000';
      var maxFontSize = centerConfig.maxFontSize || 75;
      var sidePadding = centerConfig.sidePadding || 20;
      var sidePaddingCalculated = (sidePadding / 100) * (chart.innerRadius * 2)
      // Start with a base font of 30px
      ctx.font = "30px " + fontStyle;

      // Get the width of the string and also the width of the element minus 10 to give it 5px side padding
      var stringWidth = ctx.measureText(txt).width;
      var elementWidth = (chart.innerRadius * 2) - sidePaddingCalculated;

      // Find out how much the font can grow in width.
      var widthRatio = elementWidth / stringWidth;
      var newFontSize = Math.floor(30 * widthRatio);
      var elementHeight = (chart.innerRadius * 2);

      // Pick a new font size so it will not be larger than the height of label.
      var fontSizeToUse = Math.min(newFontSize, elementHeight, maxFontSize);
      var minFontSize = centerConfig.minFontSize;
      var lineHeight = centerConfig.lineHeight || 25;
      var wrapText = false;

      if (minFontSize === undefined) {
        minFontSize = 20;
      }

      if (minFontSize && fontSizeToUse < minFontSize) {
        fontSizeToUse = minFontSize;
        wrapText = true;
      }

      // Set font settings to draw it correctly.
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      var centerX = ((chart.chartArea.left + chart.chartArea.right) / 2);
      var centerY = ((chart.chartArea.top + chart.chartArea.bottom) / 2);
      ctx.font = fontSizeToUse + "px " + fontStyle;
      ctx.fillStyle = color;

      if (!wrapText) {
        ctx.fillText(txt, centerX, centerY);
        return;
      }

      var lines = [];
      var chunks = txt.split('\n');
      for (var m = 0; m < chunks.length; m++) {
        var words = chunks[m].split(' ');
        var line;

        // Break words up into multiple lines if necessary
        for (var n = 0; n < words.length; n++) {
          var testLine = (n == 0) ? words[n] : line + ' ' + words[n];
          var metrics = ctx.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > elementWidth && n > 0) {
            lines.push(line);
            line = words[n];
          } else {
            line = testLine;
          }
        }
        lines.push(line);
      }

      // Move the center up depending on line height and number of lines
      centerY -= ((lines.length-1) / 2) * lineHeight;

      // All but last line
      for (var n = 0; n < lines.length; n++) {
        ctx.fillText(lines[n], centerX, centerY);
        centerY += lineHeight;
      }
    }
  }
});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.