Intereting Posts
Написание PHP-расширений с использованием Delphi 2010 и php4Delphi Как разрешить cURL Error (7): не удалось подключиться к хосту? Преобразовать строку в число и обратно в строку? Многостраничная загрузка HTML 5 с помощью PHP PHP PDO: невозможно подключиться, неверное имя каталога Несколько переключений Почти как вкладки JavaScript / CSS Миграции доктрины: в пространстве имен "" отсутствуют команды Как пропустить необязательные аргументы в вызове функции? PHP Удаленное удаление файлов в Dropbox с использованием PHP без использования API CodeIgniter 404 Страница не найдена, но почему? Что происходит быстрее, большой объединенный запрос с большим количеством PHP или несколькими небольшими выборками с меньшим количеством PHP? call_user_func (массив ($ this, $ method), $ par) из конструктора родителя? Проверьте, содержит ли url http: // или https: // как отображать данные отношения в формате json из двух таблиц в yii2 restful api Вопросы CodeIgniter: собственные PHP-сессии, поток кода, вопросы размещения?

Как отображать значения данных круговой диаграммы для каждого фрагмента в 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-код:

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

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

Из того, что я знаю, я не считаю, что 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); } } 

PieChart.segments диаграмма имеет массив сегментов, хранящихся в 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 , затем добавим % в конце. Для целого числа процентов плиток я округлялся до ближайшего целого числа, хотя может привести к проблемам с точностью. Если нам нужна более высокая точность, вы можете использовать .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 + '%'; 

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

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

Для 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)) + "%"; 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 }); 

HTML

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

jsFiddle

Я нашел отличный плагин Chart.js который делает именно то, что вы хотите: https://github.com/emn178/Chart.PieceLabel.js

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

{itemLabel: {mode: 'percent', precision: 2}}

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

Ответ @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 });