Veri değerleri Chart.js'de nasıl görüntülenir?


118

Chart.js kullanarak mümkün olup olmadığını sormak istiyorum veri değerlerini görüntülemek için? Grafiği yazdırmak istiyorum.

Herhangi bir tavsiye için teşekkürler.


grafiğim mükemmel çalışıyor .. sadece LineBar grafiğimde veri değerlerini görüntülemek istiyorum .. o zaman grafiklerimi yazdırabilirim .. çünkü artık veri değerlerini sadece fare olayı ile görüntüleyebiliyorum
FuSsA

Yanıtlar:


138

Geç düzenleme: Chart.js'nin 2.7.0+bunu yapması için resmi bir eklenti var : https://github.com/chartjs/chartjs-plugin-datalabels

Orijinal cevap:

AnimationComplete üzerindeki noktalar / çubuklar arasında dolaşabilir ve değerleri görüntüleyebilirsiniz.


Ön izleme

görüntü açıklamasını buraya girin


HTML

<canvas id="myChart1" height="300" width="500"></canvas>
<canvas id="myChart2" height="300" width="500"></canvas>

Senaryo

var chartData = {
    labels: ["January", "February", "March", "April", "May", "June"],
    datasets: [
        {
            fillColor: "#79D1CF",
            strokeColor: "#79D1CF",
            data: [60, 80, 81, 56, 55, 40]
        }
    ]
};

var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
    showTooltips: false,
    onAnimationComplete: function () {

        var ctx = this.chart.ctx;
        ctx.font = this.scale.font;
        ctx.fillStyle = this.scale.textColor
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";

        this.datasets.forEach(function (dataset) {
            dataset.points.forEach(function (points) {
                ctx.fillText(points.value, points.x, points.y - 10);
            });
        })
    }
});

var ctx = document.getElementById("myChart2").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
    showTooltips: false,
    onAnimationComplete: function () {

        var ctx = this.chart.ctx;
        ctx.font = this.scale.font;
        ctx.fillStyle = this.scale.textColor
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";

        this.datasets.forEach(function (dataset) {
            dataset.bars.forEach(function (bar) {
                ctx.fillText(bar.value, bar.x, bar.y - 5);
            });
        })
    }
});

Fiddle - http://jsfiddle.net/uh9vw0ao/


Ya aynı Grafikte iki çizgi grafiğim varsa?
FuSsA

1
Yukarıdakilerle yine de değerleri gösterir, ancak noktalar birbirine çok yakınsa bir örtüşme görebilirsiniz. Ancak değer konumunu değiştirmek için her zaman mantığa yer verebilirsiniz. Örneğin , renkli bir yazıcınız varsa jsfiddle.net/hh719qex gibi . Yalnızca 2 seriniz varsa, textBaseline'ı farklı EĞER 2 nokta birbirine yakın ayarlamak gibi şeyler de yapabilirsiniz.
potatopeelings

4
bu v1.0.2 içindi v2.1.3 için bu nasıl yapılır? Nesne yapısı sonraki sürümde farklıdır.
techie_28

2
@potatopeelings ben kullandım onCompleteburada geri arama ancak mouseover eğer aynı olması nedeniyle redraw.Would için kapayana numarayı neden grafiğin çubuk yıllardan açıkken o da ateşler onAnimationComplete? Bu geri aramayı mevcut grafik var chartBar
kodumla kullanamıyorum

1
Grafiğimdeki çubuğun üstünde hem araç ipucu hem de verilere ihtiyacım var. Araç ipucu gösterildiğinde, çubuğun üst kısmındaki veriler şeffaf araç ipucumda görünen beyaz renge dönüşür. Bunu nasıl düzeltebilirim?
LJP

82

İşte Chart.js 2.3 için güncellenmiş bir sürüm

23 Eylül 2016: Kodumu hem satır / çubuk türü için v2.3 ile çalışacak şekilde düzenledim.

Önemli: Animasyona ihtiyacınız olmasa bile süre seçeneğini 0 olarak değiştirmeyin, aksi takdirde chartInstance.controller is undefined hatası alırsınız .

var chartData = {
    labels: ["January", "February", "March", "April", "May", "June"],
        datasets: [
            {
                fillColor: "#79D1CF",
                strokeColor: "#79D1CF",
                data: [60, 80, 81, 56, 55, 40]
            }
        ]
    };

var opt = {
    events: false,
    tooltips: {
        enabled: false
    },
    hover: {
        animationDuration: 0
    },
    animation: {
        duration: 1,
        onComplete: function () {
            var chartInstance = this.chart,
                ctx = chartInstance.ctx;
            ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
            ctx.textAlign = 'center';
            ctx.textBaseline = 'bottom';

            this.data.datasets.forEach(function (dataset, i) {
                var meta = chartInstance.controller.getDatasetMeta(i);
                meta.data.forEach(function (bar, index) {
                    var data = dataset.data[index];                            
                    ctx.fillText(data, bar._model.x, bar._model.y - 5);
                });
            });
        }
    }
};
 var ctx = document.getElementById("Chart1"),
     myLineChart = new Chart(ctx, {
        type: 'bar',
        data: chartData,
        options: opt
     });
<canvas id="myChart1" height="300" width="500"></canvas>


Bunu çubuk grafiklerde denerken "Yakalanmamış TypeError: Tanımsız '0' özelliği okunamıyor" mesajı alıyorum. Çubuklar "dataset.metaData [i] ._ model" dışında bir şey kullanıyor mu?
Chris Ensell

Aslında var model = dataset._meta [i] .data [0] ._ modeli;
Flanamacca

Bu aynı zamanda tam gerçek değil. Yine de istisnalar alıyorum. Anlamaya çalışacak.
val

var model = veri kümesi._meta [0] .data [i] ._ modeli; aslında.
brian

2
Görünüşe göre _meta [0] kadar basit değil. Gerçekte _meta nesnesi bir dizi değildir, anahtar olarak bir sayı olan tek bir elemana sahiptir. Sayının ne olacağının ardındaki mantığı bulamıyorum, bu nedenle anahtarlar listesine bakarak ilk öğeyi şu şekilde alıyorum: var model = dataset._meta [Object.keys (dataset._meta) [0]] .Data [i] ._ modeli;
IrishDubGuy

34

Bu animasyon seçeneği, çubuk grafikte 2.1.3 için çalışır.

Biraz değiştirilmiş @Ross yanıtı

animation: {
duration: 0,
onComplete: function () {
    // render the value of the chart above the bar
    var ctx = this.chart.ctx;
    ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
    ctx.fillStyle = this.chart.config.options.defaultFontColor;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    this.data.datasets.forEach(function (dataset) {
        for (var i = 0; i < dataset.data.length; i++) {
            var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
            ctx.fillText(dataset.data[i], model.x, model.y - 5);
        }
    });
}}

3
Ayrıca hover: {animationDuration: 0}üzerine
gelindiğinde

1
Ayrıca, açıklamadan bir şeyi gizlediğinizde etiketleri gizlemek istiyorsanız, forEach döngüsünden önce aşağıdakileri eklemeniz gerektiğini unutmayın:.filter(dataset => !dataset._meta[0].hidden)
iamyojimbo

1
Bu yöntem, çubukların üzerinde yeterli alan yoksa değerlerin kırpılmasına neden olur.
Janne Annala

2
Bunun o kadar çirkin ^^ iyi iş olduğuna inanamıyorum
La masse

İyi görünüyor, ancak araç ipuçları yeniden çizildiğinde yanıp sönüyor. Ayrıca, birleştirilmiş grafikler üzerindeki çarpışmaları ve yığılmış çubuklar için kümülatif veri etiketlerini işlemez - bu tabii ki daha fazla kodlama gerektirir.
dma_k

22

Bunu chartJS v2.x'te yapmanın en güzel seçeneğinin bir eklenti kullanmak olduğunu düşünüyorum, bu nedenle seçeneklerde büyük bir kod bloğunuz yok. Ek olarak, bir çubuğun üzerine gelindiğinde verilerin kaybolmasını önler.

Yani basitçe, grafik çizildikten sonra metni ekleyen bir eklentiyi kaydeden bu kodu kullanın.

Chart.pluginService.register({
    afterDraw: function(chartInstance) {
        var ctx = chartInstance.chart.ctx;

        // render the value of the chart above the bar
        ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';

        chartInstance.data.datasets.forEach(function (dataset) {
            for (var i = 0; i < dataset.data.length; i++) {
                var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
                ctx.fillText(dataset.data[i], model.x, model.y - 2);
            }
        });
  }
});

Chart.plugins.register ({
hasentopf

Kullanmak zorunda kaldım Chart.defaults.global.tooltips.enabled = false;. Bu çözümle ilgili sorun, afterDrawişlevin yüzlerce kez çağrılmasıdır ve muhtemelen CPU ek yükü oluşturur. Yine de, şimdilik göz kırpmadan tek cevap bu. horizontalBarGrafikler için daha iyi bir görüntülemeye ihtiyacınız varsa , ctx.textAlign = 'left'; ctx.textBaseline = 'middle';ve kullanın ctx.fillText(dataset.data[i], model.x+5, model.y);.
KrisWebDev

çok daha temiz ve modüler bir çözüm.
hadaytullah

20

@ Ross'un Chart.js 2.0 ve üstü için verdiği cevaba dayanarak, çubuğun yükseklikleri ölçek sınırına çok yaklaştığında duruma karşı korunmak için küçük bir ayar eklemek zorunda kaldım.

Misal

animationÇubuk grafiğin seçeneğinin özellik:

animation: {
            duration: 500,
            easing: "easeOutQuart",
            onComplete: function () {
                var ctx = this.chart.ctx;
                ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
                ctx.textAlign = 'center';
                ctx.textBaseline = 'bottom';

                this.data.datasets.forEach(function (dataset) {
                    for (var i = 0; i < dataset.data.length; i++) {
                        var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
                            scale_max = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
                        ctx.fillStyle = '#444';
                        var y_pos = model.y - 5;
                        // Make sure data value does not get overflown and hidden
                        // when the bar's value is too close to max value of scale
                        // Note: The y value is reverse, it counts from top down
                        if ((scale_max - model.y) / scale_max >= 0.93)
                            y_pos = model.y + 20; 
                        ctx.fillText(dataset.data[i], model.x, y_pos);
                    }
                });               
            }
        }

Grafiğin fareyle üzerine gelindiğinde metin yanıp sönüyor .. ctx.save()Sonunda aramayı denedim ama yardımcı olmadı
techie_28

onCompleteBen bu konuda aynı olması blink.Would için yeniden çizim ve metin görünür sebep çubuk yıllardan üzerinde süpürdü zaman çağrı geri yürütüldüğünde onAnimationCompleteiyi? ı kullanamıyor olduğum gibi onAnimationCompletebenim mevcut kodla çağrı arka (bkz var chartBaraltındaki pastebin. com / tT7yTkGh
techie_28

Aynısını pasta grafikte yapmak mümkün mü
Ravi Khambhati

@RaviKhambhati Evet, bu cevapta kontrol edebilirsiniz: stackoverflow.com/a/38797604/6402571
Hung Tran

17

Eklenti chartjs-plugin-datalabels kullanıyorsanız , aşağıdaki kod seçenekleri nesnesi yardımcı olacaktır

import 'chartjs-plugin-datalabels';Typecript dosyanıza içe aktardığınızdan veya <script src="chartjs-plugin-datalabels.js"></script>javascript dosyanıza referans eklediğinizden emin olun .

options: {
    maintainAspectRatio: false,
    responsive: true,
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true,
        }
      }]
    },
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'top',
        formatter: Math.round,
        font: {
          weight: 'bold'
        }
      }
    }
  }

1
Cevabınız çok basit ve benim için çalıştı. Teşekkür ederim. Mutlu kodlamalar.
Bandham Manikanta

7

Bu iyi cevabı takiben , bir çubuk grafik için şu seçenekleri kullanırdım:

var chartOptions = {
    animation: false,
    responsive : true,
    tooltipTemplate: "<%= value %>",
    tooltipFillColor: "rgba(0,0,0,0)",
    tooltipFontColor: "#444",
    tooltipEvents: [],
    tooltipCaretSize: 0,
    onAnimationComplete: function()
    {
        this.showTooltip(this.datasets[0].bars, true);
    }
};

window.myBar = new Chart(ctx1).Bar(chartData, chartOptions);

Grafik çubuğu

Bu hala araç ipucu sistemini ve avantajlarını (otomatik konumlandırma, şablonlama, ...) kullanıyor ancak dekorasyonları gizliyor (arka plan rengi, şapka, ...)


Uygulama, grafik türüne bağlı olarak değişebilir. Örneğin bir çizgi grafik için, bunun this.datasets[0].pointsyerine .bars. Araç ipucu sistemini kullandığı için bu çözümü tercih ediyorum.
Telmo Marques

1
Daha önceki bir sürüm için bu çözüm. En son sürüm yani 2.1.3 için bu nasıl elde edilir. Potatopeelings & Huang Trang cevaplarını animasyonlar onCompletegeri aramasında kullandım, ancak grafiğin çubuklarının üzerine getirildiğinde bile tetikleniyor ve bu da metnin yeniden afterDrawçizilmesine ve istenmeyen bir göz kırpma efekti vermesine neden oluyor.Ayrıca denedim ve hepsi aynı. potatopeelings tarafından sağlanan keman içinde olmaz. Herhangi bir Fikir plz?
techie_28

6

Chart.js örneklerinden (Chart.js-2.4.0 / samples / data_labelling.html dosyası):

`` // Veri etiketleri sağlamak için bir eklenti tanımlayın

    Chart.plugins.register({
        afterDatasetsDraw: function(chartInstance, easing) {
            // To only draw at the end of animation, check for easing === 1
            var ctx = chartInstance.chart.ctx;

            chartInstance.data.datasets.forEach(function (dataset, i) {
                var meta = chartInstance.getDatasetMeta(i);
                if (!meta.hidden) {
                    meta.data.forEach(function(element, index) {
                        // Draw the text in black, with the specified font
                        ctx.fillStyle = 'rgb(0, 0, 0)';

                        var fontSize = 16;
                        var fontStyle = 'normal';
                        var fontFamily = 'Helvetica Neue';
                        ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);

                        // Just naively convert to string for now
                        var dataString = dataset.data[index].toString();

                        // Make sure alignment settings are correct
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';

                        var padding = 5;
                        var position = element.tooltipPosition();
                        ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
                    });
                }
            });
        }
    });

`


If (chart.config.type == "horizontalBar") yapıp ardından ortalamak için 10'luk özel bir dikey dolgu tanımlayarak Yatay Çubuk Grafikte hizalama için buna bir çizgi ekledim.
Jeff Beagley

6

Bu eklentiyi kullanmanızı tavsiye ederim: https://github.com/chartjs/chartjs-plugin-datalabels

Eklentiyi js dosyasına aktararak grafiklerinize etiketler eklenebilir, örneğin:

import 'chartjs-plugin-datalabels'

Ve şu dokümanlar kullanılarak ince ayar yapılabilir: https://chartjs-plugin-datalabels.netlify.com/options.html


2
En kolayı, "kod" gerektirmez, sadece standart "options" nesnesini kullanarak özelleştirme gerektirir. Bir uyarı: minimum gerekli charts.js sürümü 2.7.0 , CDN'den 2.5.0'a atıfta bulunuyordum ve grafiklerde herhangi bir değişiklik olmadı ...
GBU

@GBU seçenek özelliği nedir?.
Bhimbim

5

@ Ajhuddy'nin cevabı biraz düzenlendi. Yalnızca çubuk grafikler için . Sürümüm şunları ekler:

  • Değerler için animasyonda karartın.
  • Çubuk çok yüksekse değeri çubuğun içine yerleştirerek kırpmayı önleyin.
  • Göz kırpma yok.

Misal

Dezavantajı: İçinde değeri olan bir çubuğun üzerine gelindiğinde, değer biraz pürüzlü görünebilir. Üzerine gelme efektlerini devre dışı bırakacak bir çözüm bulamadım. Ayrıca kendi ayarlarınıza bağlı olarak ince ayar yapılması gerekebilir.

Yapılandırma:

bar: {
  tooltips: {
    enabled: false
  },
  hover: {
    animationDuration: 0
  },
  animation: {
    onComplete: function() {
      this.chart.controller.draw();
      drawValue(this, 1);
    },
    onProgress: function(state) {
      var animation = state.animationObject;
      drawValue(this, animation.currentStep / animation.numSteps);
    }
  }
}

Yardımcılar:

// Font color for values inside the bar
var insideFontColor = '255,255,255';
// Font color for values above the bar
var outsideFontColor = '0,0,0';
// How close to the top edge bar can be before the value is put inside it
var topThreshold = 20;

var modifyCtx = function(ctx) {
  ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
  ctx.textAlign = 'center';
  ctx.textBaseline = 'bottom';
  return ctx;
};

var fadeIn = function(ctx, obj, x, y, black, step) {
  var ctx = modifyCtx(ctx);
  var alpha = 0;
  ctx.fillStyle = black ? 'rgba(' + outsideFontColor + ',' + step + ')' : 'rgba(' + insideFontColor + ',' + step + ')';
  ctx.fillText(obj, x, y);
};

var drawValue = function(context, step) {
  var ctx = context.chart.ctx;

  context.data.datasets.forEach(function (dataset) {
    for (var i = 0; i < dataset.data.length; i++) {
      var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
      var textY = (model.y > topThreshold) ? model.y - 3 : model.y + 20;
      fadeIn(ctx, dataset.data[i], model.x, textY, model.y > topThreshold, step);
    }
  });
};

Janne, çözüm için teşekkürler, harika görünüyor. Ancak değerlerimin aslında biraz büyük (5 ondalık sayı) olduğu ve ekran boyutu küçük olduğunda veya çok sayıda grafiğim olduğunda, sayıların üst üste geldiği bir durum var. Bunun duyarlılıkla çalışmasını sağlamanın herhangi bir yolu var mı? Mesela, çubuğun altındaki etiketler gibi, boşluk olmadığında sayıların dönmesini sağlamak gibi?
Phiter

@PhiterFernandes DeğiştirCtx işlevinde mevcut ekran boyutunu kontrol ederek ve ctx.rotate kullanarak döndürmenin mümkün olduğunu düşünüyorum. Ancak, ne zaman döndürüleceğini belirlemek için değer boyutunu mevcut alanla nasıl karşılaştıracağımdan emin değilim.
Janne Annala

ModifyCtx işlevi yalnızca bir kez çalışır ve yeniden boyutlandırmada çalışmaz, değil mi? Chart.js kaynak koduna bir göz atacağım ve x ekseninde etiketlerin rotasyonunu nerede yaptıklarını göreceğim. Bir şey görürsem burada bir şeyler yapmaya ve sana anlatmaya çalışırım, tamam mı? =)
Phiter

2.3.0 sürümünün 7075 satırında bir şey buldum calculateTickRotation, bu Ölçek işlevinin içinde. Analiz edeceğim.
Phiter

5

Tecrübelerime göre, chartjs-plugin-datalabels eklentisini eklediğinizde ( <script>etiketi sayfanıza chart.js etiketinden sonra yerleştirdiğinizden emin olun ), grafikleriniz değerleri göstermeye başlar.

Daha sonra seçerseniz, ihtiyaçlarınıza uyacak şekilde özelleştirebilirsiniz. Özelleştirme burada açıkça belgelenmiştir , ancak temelde format şu varsayımsal örnek gibidir:

var myBarChart = new Chart(ctx, {
    type: 'bar',
    data: yourDataObject,
    options: {
        // other options
        plugins: {
            datalabels: {
                anchor :'end',
                align :'top',
                // and if you need to format how the value is displayed...
                formatter: function(value, context) {
                    return GetValueFormatted(value);
                }
            }
        }
    }
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.