问题
I've been doing a lot of research but I wasn't able to figure out, how to enter percentage into labels badge like this image below.
update: I'm using this laravel wrapper : https://github.com/ConsoleTVs/Charts so was the reason I didn't want to confuse viewers. I just want to know the name of the option.. my code is this:
$perTopicChart = (new AnsweredPerTopic);//->percentageInnerCutout(70);
$perTopicChart->options([
"events" => [],
"legend" => [
"labels" => [
"defaultFontFamily" => "Tahoma",
"fontSize" => 16,
],
"position" => 'bottom'
],
"cutoutPercentage" => 80,
'tooltips' => [
"show" => true
]
])->displayAxes(0);
// put the labels (keys)
$perTopicChart->labels($keys->map(function ($q) use ($perTopic) {
$topic = Topic::find($q);
$str = $topic->name;
foreach ($perTopic as $key => $value) {
if ($key == $q) {
$str .= ' ' . round($value) . '%';
}
}
return "topic name " . '-'. $topic->id;
})->push('other'))
->options([]);
// get random color
// $color = RandomColor::many(count($keys), array(
// 'luminosity' => 'bright',
// 'hue' => ['pink', 'green', 'orange'] // e.g. 'rgb(225,200,20)'
// ));
$color = [
"#38c172",
"#9F9",
"#Fa0",
"pink",
"red",
];
$perTopicChart->dataset("Practice per Category", "doughnut", $values->map(function ($q) {
return round($q);
})->push($remainingPercenteg))
->backgroundColor($color)
->options([
'borderWidth' => 2.5,
]);
the first image the current result and the second is what I wanted. thanks in advance.
回答1:
Even I researched a lot, couldn't find anything for this kind of behavior in chartjs library, So come up with a hack.
Hack is something like, Do not let chart js to draw legends, Instead we just get the HTML of legends from chart js library, and put it in our container. By doing this we have full access of legends and we can do whatever we want.
https://jsfiddle.net/1kxenzpr/
const data = [70, 30, 0];
debugger;
var ctx = document.getElementById("myChart").getContext('2d');
var chart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["Green", "Blue", "Gray", "Purple", "Yellow", "Red", "Black"],
datasets: [{
backgroundColor: [
"#2ecc71",
"#3498db",
"#95a5a6",
"#9b59b6",
"#f1c40f",
"#e74c3c",
"#34495e"
],
data: data
}]
},
options: {
legend: {
display: false
},
}
});
var myLegendContainer = document.getElementById("legend");
myLegendContainer.innerHTML = chart.generateLegend();
var legendItems = myLegendContainer.getElementsByTagName('li');
for (var i = 0; i < legendItems.length; i++) {
legendItems[i].querySelectorAll('span')[0].innerHTML = data[i] + '%'
}
.container {
width: 80%;
margin: 15px auto;
}
[class$="-legend"] {
list-style: none;
cursor: pointer;
padding-left: 0;
}
[class$="-legend"] li {
display: inline-block;
padding: 0 5px;
}
[class$="-legend"] li.hidden {
text-decoration: line-through;
}
[class$="-legend"] li span {
display: inline-block;
margin-right: 10px;
width: 50px;
font-size: 12px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div class="container">
<div>
<canvas id="myChart"></canvas>
<div id="legend"></div>
</div>
</div>
回答2:
No way (By setting X or Y). You should use legendCallback
:
https://www.chartjs.org/docs/latest/configuration/legend.html#html-legends
In general, your Q does not follow StackOverflow guidelines (This is more a mission, not Q). https://stackoverflow.com/help/how-to-ask
Anyway, this is +- the idea (convert to % by basic JS). To take this step forward you should generate full generate HTML legend (To put a number inside a color div). Related: Custom Legend with ChartJS v2.0
var myData = [4, 9, 5];
var data = {
labels: ["Africa", "Asia", "Europe"],
datasets: [{
label: "Population (millions)",
backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f"],
data: myData
}]
};
/* get total */
const reducer = (accumulator, currentValue) => accumulator + currentValue;
var total = myData.reduce(reducer);
var options = {
responsive: true,
title: {
text: 'Show % calucate on fly',
position: 'top',
display: true
},
legend: {
display: true,
labels: {
/* generateLabels */
generateLabels(chart) {
const data = chart.data;
if (data.labels.length && data.datasets.length) {
/* inner loop throw lables */
return data.labels.map((label, i) => {
var backgroundColor = data.datasets[0].backgroundColor[i];
var current = data.datasets[0].data[i];
var percentage = ((current * 100) / total).toFixed(2) + '%';
return {
text: label + " | " + percentage,
fillStyle: backgroundColor,
// Extra data used for toggling the correct item
index: i
};
});
}
return [];
}
},
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}]
}
};
new Chart(document.getElementById("chart"), {
type: 'pie',
data: data,
options: options
});
<canvas id="chart" width="800" height="450"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
来源:https://stackoverflow.com/questions/61285234/add-percentage-to-label-badge-doughnut-chart-js