Подтвердить что ты не робот

Как отображать значения данных круговой диаграммы для каждого фрагмента в chart.js

Я использую Chart.js для рисования круговой диаграммы на моей странице php. Я нашел всплывающую подсказку как показывающую все значения среза.
введите описание изображения здесь

Но я хочу показать эти значения, как показано ниже. введите описание изображения здесь

Я не знаю, как это сделать с помощью chart.js.

Пожалуйста, помогите мне.

Мой код javascript:

function drawPie(canvasId,data,legend){
    var ctx = $("#pie-canvas-" + canvasId).get(0).getContext("2d");

    var piedata = [];
    $.each(data,function(i,val){
        piedata.push({value:val.count,color:val.color,label:val.status});
    });
    var options =
    {
        tooltipTemplate: "<%= Math.round(circumference / 6.283 * 100) %>%",
    }
    var pie = new Chart(ctx).Pie(piedata,options);
    if(legend)document.getElementById("legend").innerHTML = pie.generateLegend();
}

php code:

printf('<table><tr>');
echo '<td style="text-align: right;"><canvas id="pie-canvas-'
    . $canvasId
    . '" width="256" height="256" ></canvas></td><td style="text-align: left;width:360px;height:auto" id="legend" class="chart-legend"></td></tr></table>';

     echo '<script type="text/javascript">drawPie('
    . $canvasId
    . ', '
    . $data3
    .', '
    . $legend
    . ');</script>';

введите описание изображения здесь

4b9b3361

Ответ 1

Из того, что я знаю, я не верю, что Chart.JS имеет любую функциональность, помогающую рисовать текст на круговой диаграмме. Но это не значит, что вы не можете сделать это самостоятельно в родном JavaScript. Я приведу вам пример того, как это сделать, ниже приведен код для рисования текста для каждого сегмента в круговой диаграмме:

function drawSegmentValues()
{
    for(var i=0; i<myPieChart.segments.length; i++) 
    {
        // Default properties for text (size is scaled)
        ctx.fillStyle="white";
        var textSize = canvas.width/10;
        ctx.font= textSize+"px Verdana";

        // Get needed variables
        var value = myPieChart.segments[i].value;
        var startAngle = myPieChart.segments[i].startAngle;
        var endAngle = myPieChart.segments[i].endAngle;
        var middleAngle = startAngle + ((endAngle - startAngle)/2);

        // Compute text location
        var posX = (radius/2) * Math.cos(middleAngle) + midX;
        var posY = (radius/2) * Math.sin(middleAngle) + midY;

        // Text offside to middle of text
        var w_offset = ctx.measureText(value).width/2;
        var h_offset = textSize/4;

        ctx.fillText(value, posX - w_offset, posY + h_offset);
    }
}

A Pie Chart имеет массив сегментов, хранящихся в PieChart.segments, мы можем посмотреть на startAngle и endAngle этих сегментов, чтобы определить угол между тем, где текст будет middleAngle. Тогда мы движемся в этом направлении на Radius/2, чтобы находиться в средней точке диаграммы в радианах.

В приведенном выше примере выполняются некоторые другие операции очистки, из-за того, что позиция текста, изображенного в fillText(), является верхним правом углом, нам нужно получить некоторые значения смещения, чтобы исправить это. И, наконец, textSize определяется на основе размера самой диаграммы, чем больше диаграмма, тем больше текст.

Пример скрипта


С небольшими изменениями вы можете изменить значения дискретных чисел для набора данных в числа процентилей на графике. Для этого получите общее количество элементов value в вашем наборе данных, назовите это totalValue. Затем на каждом сегменте вы можете найти процент:

Math.round(myPieChart.segments[i].value/totalValue*100)+'%';

Здесь раздел myPieChart.segments[i].value/totalValue вычисляет процент, который сегмент занимает в диаграмме. Например, если текущий сегмент имел значение 50, а totalValue было 200. Тогда процент, который занял сегмент, будет следующим: 50/200 => 0.25. Остальное - сделать это хорошо. 0.25*100 => 25, то мы добавим a % в конец. Для целого числа процентов плиток я округлялся до ближайшего целого числа, хотя может привести к проблемам с точностью. Если нам нужна более высокая точность, вы можете использовать .toFixed(n) для сохранения десятичных знаков. Например, мы могли бы сделать это, чтобы сохранить одно десятичное место при необходимости:

var value = myPieChart.segments[i].value/totalValue*100;
if(Math.round(value) !== value)
    value = (myPieChart.segments[i].value/totalValue*100).toFixed(1);
value = value + '%';

Скрипт Пример процентиля с десятичными знаками

Скрипт Пример процента с целыми числами

Ответ 2

Для Chart.js 2.0 и выше данные объекта Chart изменились. Для тех, кто использует Chart.js 2. 0+, ниже приведен пример использования метода HTML5 Canvas fillText() для отображения значения данных внутри круговой части. Код работает и для кольцевой диаграммы, с той лишь разницей, что type: 'pie' и type: 'doughnut' при создании диаграммы.

Сценарий:

Javascript

var data = {
    datasets: [{
        data: [
            11,
            16,
            7,
            3,
            14
        ],
        backgroundColor: [
            "#FF6384",
            "#4BC0C0",
            "#FFCE56",
            "#E7E9ED",
            "#36A2EB"
        ],
        label: 'My dataset' // for legend
    }],
    labels: [
        "Red",
        "Green",
        "Yellow",
        "Grey",
        "Blue"
    ]
};

var pieOptions = {
  events: false,
  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,
              total = dataset._meta[Object.keys(dataset._meta)[0]].total,
              mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
              start_angle = model.startAngle,
              end_angle = model.endAngle,
              mid_angle = start_angle + (end_angle - start_angle)/2;

          var x = mid_radius * Math.cos(mid_angle);
          var y = mid_radius * Math.sin(mid_angle);

          ctx.fillStyle = '#fff';
          if (i == 3){ // Darker text color for lighter background
            ctx.fillStyle = '#444';
          }
          var percent = String(Math.round(dataset.data[i]/total*100)) + "%";      
          //Don't Display If Legend is hide or value is 0
          if(dataset.data[i] != 0 && dataset._meta[0].data[i].hidden != true) {
            ctx.fillText(dataset.data[i], model.x + x, model.y + y);
            // Display percent in another line, line break does not work for fillText
            ctx.fillText(percent, model.x + x, model.y + y + 15);
          }
        }
      });               
    }
  }
};

var pieChartCanvas = $("#pieChart");
var pieChart = new Chart(pieChartCanvas, {
  type: 'pie', // or doughnut
  data: data,
  options: pieOptions
});

HTML

<canvas id="pieChart" width=200 height=200></canvas>

jsFiddle

Ответ 4

Вы можете использовать плагин PieceLabel для Chart.js.

{ pieceLabel: { mode: 'percentage', precision: 2 } }

Демо | Документация

Похоже, у плагина новое местоположение (и название): Demo Docs.

Ответ 5

@Ответ на Hung Tran работает отлично. В качестве улучшения я бы предложил не показывать значения, равные 0. Скажем, у вас есть 5 элементов, а 2 из них равны 0, а остальные из них имеют значения, в приведенном выше решении будут отображаться 0 и 0%. Лучше отфильтровать это с не равной 0 проверке!

          var val = dataset.data[i];
          var percent = String(Math.round(val/total*100)) + "%";

          if(val != 0) {
            ctx.fillText(dataset.data[i], model.x + x, model.y + y);
            // Display percent in another line, line break doesn't work for fillText
            ctx.fillText(percent, model.x + x, model.y + y + 15);
          }

Обновленный код ниже:

var data = {
    datasets: [{
        data: [
            11,
            16,
            7,
            3,
            14
        ],
        backgroundColor: [
            "#FF6384",
            "#4BC0C0",
            "#FFCE56",
            "#E7E9ED",
            "#36A2EB"
        ],
        label: 'My dataset' // for legend
    }],
    labels: [
        "Red",
        "Green",
        "Yellow",
        "Grey",
        "Blue"
    ]
};

var pieOptions = {
  events: false,
  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,
              total = dataset._meta[Object.keys(dataset._meta)[0]].total,
              mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
              start_angle = model.startAngle,
              end_angle = model.endAngle,
              mid_angle = start_angle + (end_angle - start_angle)/2;

          var x = mid_radius * Math.cos(mid_angle);
          var y = mid_radius * Math.sin(mid_angle);

          ctx.fillStyle = '#fff';
          if (i == 3){ // Darker text color for lighter background
            ctx.fillStyle = '#444';
          }

          var val = dataset.data[i];
          var percent = String(Math.round(val/total*100)) + "%";

          if(val != 0) {
            ctx.fillText(dataset.data[i], model.x + x, model.y + y);
            // Display percent in another line, line break doesn't work for fillText
            ctx.fillText(percent, model.x + x, model.y + y + 15);
          }
        }
      });               
    }
  }
};

var pieChartCanvas = $("#pieChart");
var pieChart = new Chart(pieChartCanvas, {
  type: 'pie', // or doughnut
  data: data,
  options: pieOptions
});

Ответ 7

Самый простой способ сделать это с Chartjs. Просто добавьте нижнюю строку в настройках:

pieceLabel: {
        fontColor: '#000'
    }

Удачи