Chart.jsにデータ値を表示する方法


117

Chart.jsを使用して可能かどうかを確認したい データ値を表示するには?グラフを印刷したい。

アドバイスありがとうございます。


私のグラフは完全に機能しています。LineBarチャートにデータ値を表示したいだけです。その後、グラフを印刷できます。マウスイベントだけでデータ値を表示できるようになりました
FuSsA

回答:


138

遅い編集:2.7.0+これを行うためのChart.jsの公式プラグインがあります:https : //github.com/chartjs/chartjs-plugin-datalabels

元の答え:

あなたはAnimationComplete上のポイント/バーをループして値を表示することができます


プレビュー

ここに画像の説明を入力してください


HTML

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

脚本

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

フィドル-http://jsfiddle.net/uh9vw0ao/


同じグラフに2つの折れ線グラフがある場合はどうなりますか?
FuSsA

1
上記の場合でも値は表示されますが、ポイントが互いに近すぎる場合はオーバーラップが発生する可能性があります。ただし、値の位置を変更するロジックをいつでも使用できます。たとえば、カラープリンタを使用している場合はjsfiddle.net/hh719qexのように。シリーズが2つしかない場合は、textBaselineを異なるように設定することもできます(2つのポイントが2に近い場合)。
ポタトピーリング

4
これはv1.0.2の場合で、v2.1.3でこれを行う方法は?オブジェクトの構造は、以降のバージョンでは異なります。
techie_28

2
@potatopeelings onCompleteここではコールバックを使用しましたが、マウスオーバーがチャートのバーの上にあるときにも発生し、再描画のために数値が点滅しonAnimationCompleteます。私は私の既存のチャートのコードで、このコールバックを使用することができません(参照var chartBar下部にpastebin.com/tT7yTkGh
techie_28

1
グラフの棒の上にツールヒントとデータの両方が必要です。ツールチップが表示されると、バーの上部のデータが白色に変わり、透明なツールチップに表示されます。どうすれば修正できますか?
LJP、

82

ここにChart.js 2.3の更新バージョンがあります

2016年9月23日:線/棒タイプの両方でv2.3で動作するようにコードを編集しました。

重要:アニメーションが必要ない場合でも、期間オプションを0に変更しないでください。変更すると、chartInstance.controllerが未定義のエラーになります。

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>


棒グラフでこれを実行しようとすると、「Uncaught TypeError:プロパティ '0'を読み取れません」が表示されます。バーは「dataset.metaData [i] ._ model」以外のものを使用していますか?
Chris Ensell 16年

実際にはvar model = dataset._meta [i] .data [0] ._ model;です。
フラナマッカ2016年

それも完全な真実ではありません。それでも例外が発生します。それを理解しようとします。
ヴァル

var model = dataset._meta [0] .data [i] ._ model; 実際に。
ブライアン

2
_meta [0]ほど単純ではないようです。実際、_metaオブジェクトは配列ではなく、数値をキーとする単一の要素を持っています。数値がどうなるかについての根拠がわからないので、次のようにキーリストを調べて最初の要素を取得します。var model = dataset._meta [Object.keys(dataset._meta)[0]] .data [i] ._ model;
IrishDubGuy

34

このアニメーションオプションは、棒グラフの2.1.3で機能します。

少し変更された@Ross回答

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
またhover: {animationDuration: 0}、ホバー時にアニメーションが
消えるの

1
また、あなたが非表示のラベルにしたい場合は、伝説から何かを隠したとき、あなたはforeachループの前に次のことを追加する必要があります:.filter(dataset => !dataset._meta[0].hidden)
iamyojimbo

1
このメソッドは、バーの上に十分なスペースがない場合、値をクリップします。
Janne Annala、2016年

2
信じられないほど醜い^^いい仕事
La masse

見た目は良いですが、ツールチップが再描画されると点滅します。また、積み上げ棒の複合グラフと累積データラベルの衝突も処理しません。もちろん、より多くのコーディングが必要になります。
dma_k 2017

22

chartJS v2.xでこれを行うための最も良いオプションはプラグインを使用することです。そのため、オプションに大きなコードブロックはありません。さらに、バーの上にカーソルを置いたときにデータが消えないようにします。

つまり、チャートが描画された後にテキストを追加するプラグインを登録するこのコードを単に使用します。

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 2016

使わざるを得なかったChart.defaults.global.tooltips.enabled = false;。そのソリューションの問題は、afterDraw関数が何百回も呼び出され、おそらくCPUオーバーヘッドを生成することです。それでも、まばたきのない今のところ唯一の答えです。horizontalBarグラフのレンダリングを改善する必要がある場合は、ctx.textAlign = 'left'; ctx.textBaseline = 'middle';およびを使用してくださいctx.fillText(dataset.data[i], model.x+5, model.y);
KrisWebDev 2016

よりクリーンでモジュール化されたソリューション。
hadaytullah 2017年

20

Chart.js 2.0以降に対する@Rossの回答に基づいて、バーの高さがスケールの境界に近づきすぎた場合に備えて、少し微調整を加える必要がありました。

例

animation棒グラフのオプションの属性:

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

チャートのマウスオーバー時にテキストが点滅します。ctx.save()最後に電話をかけてみましたが、うまく
いき

onComplete私はこれはと同じでblink.Wouldに再描画&テキストが表示されますが発生するバーの上で推移したときに、コールバックが実行されonAnimationComplete、私が使用することができませんか。だけでなくonAnimationComplete、私の既存のコード(参照して、コールバックをvar chartBarの下部にペーストビン。 com / tT7yTkGh
techie_28

同じことを円グラフで行うことは可能ですか
Ravi Khambhati

@RaviKhambhatiはい、次の回答で確認できます:stackoverflow.com/a/38797604/6402571
Hung Tran

17

プラグインchartjs-plugin-datalabelsを使用している場合、次のコードオプションオブジェクトが役立ちます

import 'chartjs-plugin-datalabels';typescriptファイルにインポートするか<script src="chartjs-plugin-datalabels.js"></script>、javascriptファイルに参照を追加してください。

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

1
あなたの答えはとても簡単で、私にとってはうまくいきました。ありがとうございました。ハッピーコーディング。
Bandham Manikanta

7

この良い答えに従って、棒グラフに次のオプションを使用します。

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

棒グラフ

これはまだツールチップシステムと彼の利点(自動配置、テンプレートなど)を使用していますが、装飾(背景色、キャレットなど)を非表示にしています


チャートのタイプによって実装が変わる場合があります。たとえば、折れ線グラフの場合、のthis.datasets[0].points代わりです.bars。ツールチップシステムを使用するため、私はこのソリューションを好みます。
Telmo Marques 2016年

1
以前のバージョンのこのソリューション。最新バージョン、つまり2.1.3でこれを達成する方法。アニメーションonCompleteコールバックでポタトピーリングとファントランの回答を使用しましたが、チャートのバーの上にホバーしたときにもトリガーされ、テキストが再描画されて不要な点滅効果が発生します。私も試しましafterDrawたが、すべて同じです。 potatopeelingsによって提供されるフィドルでは発生しません。
techie_28

6

chart.jsサンプルから(ファイルChart.js-2.4.0 / samples / data_labelling.html):

`` `//データラベルを提供するプラグインを定義する

    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 == "horizo​​ntalBar")を実行して水平方向のバーチャートに配置するための行をこれに追加し、中央に配置するために10のカスタム垂直パディングを定義しました。
Jeff Beagley 2017

6

このプラグインの使用をお勧めします:https : //github.com/chartjs/chartjs-plugin-datalabels

プラグインをjsファイルにインポートするだけで、ラベルをチャートに追加できます。例:

import 'chartjs-plugin-datalabels'

そして、これらのドキュメントを使用して微調整することができます:https : //chartjs-plugin-datalabels.netlify.com/options.html


2
最も簡単な方法は、「コード」を必要とせず、標準の「オプション」オブジェクトを使用してカスタマイズするだけです。要注意:charts.jsの最低限必要なバージョンは2.7.0で、CDNから2.5.0を参照していたが、グラフに変更はなかった...
GBU

@GBUオプション属性とは?
Bhimbim、

5

@ajhuddyの回答を少し編集しました。棒グラフのみ。私のバージョンは追加します:

  • 値のアニメーションをフェードインします。
  • バーが高すぎる場合は、バーの内側に値を配置してクリッピングを防止します。
  • 点滅しない。

例

欠点:内部に値があるバーの上にカーソルを置くと、値が少しギザギザに見えることがあります。ホバー効果を無効にするソリューションが見つかりません。独自の設定によっては、微調整が必​​要になる場合もあります。

構成:

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

ヘルパー:

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

ジャンヌ、解決策をありがとう、それは素晴らしいですね。しかし、私は自分の値が実際には少し大きい(10進数の5桁)状況にあり、画面サイズが小さい場合、または多くのグラフがある場合、数値は互いに重なり合っています。これを責任を持って機能させる方法はありますか?同様に、バーの下のラベルのように、スペースがないときに数字を回転させますか?
Phiter 2016年

@PhiterFernandes modifyCtx関数で現在の画面サイズを確認し、ctx.rotateを使用することで、回転が可能になるはずです。ただし、値のサイズと使用可能なスペースを比較して、いつ回転するかを判断する方法がわかりません。
Janne Annala、2016年

modifyCtx関数は一度だけ機能し、サイズ変更では機能しません。chart.jsソースコードを見て、x軸のラベルの回転をどこで行うかを確認します。私が何かを見つけたら、私は何かをしようとし、ここであなたに言います、いいですか?=)
Phiter 2016年

バージョン2.3.0の7075行目calculateTickRotationで何かを見つけました。これは、Scale関数の内部にあります。分析します。
Phiter

5

私の経験では、chartjs-plugin-datalabelsプラグインを含めると<script>ページのchart.jsタグの後ろにタグを配置してください)、グラフに値が表示され始めます。

次に選択する場合は、ニーズに合わせてカスタマイズできます。カスタマイズはここに明確に文書化されてますが、基本的に、形式は次の架空の例のようになります。

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);
                }
            }
        }
    }
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.