Chart.js 2.0 甜甜圈工具提示百分比
Chart.js 2.0 doughnut tooltip percentages
我曾使用 chart.js 1.0,我的圆环图工具提示显示基于数据除以数据集的百分比,但我无法用图表 2.0 复制它。
我到处搜索,但没有找到可行的解决方案。我知道它会在选项下进行,但我尝试过的一切充其量只是使馅饼功能失调。
<html>
<head>
<title>Doughnut Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="canvas-holder" style="width:75%">
<canvas id="chart-area" />
</div>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
486.5,
501.5,
139.3,
162,
263.7,
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Expenditures'
}],
labels: [
"Hospitals: 6.5 billion",
"Physicians & Professional Services: 1.5 billion",
"Long Term Care: 9.3 billion",
"Prescription Drugs: 2 billion",
"Other Expenditures: 3.7 billion"
]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
title: {
display: false,
text: 'Chart.js Doughnut Chart'
},
animation: {
animateScale: true,
animateRotate: true
}
}
};
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx, config);{
}
};
</script>
</body>
</html>
更新: 下面的答案显示了基于总数据的百分比,但是 @William Surya Permana
有一个很好的答案,它根据显示的数据更新
在options
中你可以传入一个tooltips
对象(更多可以在chartjs docs阅读)
tooltips
的一个字段,为了得到你想要的结果,是一个callbacks
的对象,有一个label
的字段。 label
将是一个函数,它接收您悬停的工具提示项和构成图表的数据。只是 return 一个字符串,你想从这个函数进入工具提示。
这是一个示例,说明它的样子
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
//get the concerned dataset
var dataset = data.datasets[tooltipItem.datasetIndex];
//calculate the total of this data set
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
//get the current items value
var currentValue = dataset.data[tooltipItem.index];
//calculate the precentage based on the total and current item, also this does a rough rounding to give a whole number
var percentage = Math.floor(((currentValue/total) * 100)+0.5);
return percentage + "%";
}
}
}
以及您提供的数据的完整示例
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
486.5,
501.5,
139.3,
162,
263.7,
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Expenditures'
}],
labels: [
"Hospitals: 6.5 billion",
"Physicians & Professional Services: 1.5 billion",
"Long Term Care: 9.3 billion",
"Prescription Drugs: 2 billion",
"Other Expenditures: 3.7 billion"
]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
title: {
display: false,
text: 'Chart.js Doughnut Chart'
},
animation: {
animateScale: true,
animateRotate: true
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var percentage = Math.floor(((currentValue/total) * 100)+0.5);
return percentage + "%";
}
}
}
}
};
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx, config); {
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder" style="width:75%">
<canvas id="chart-area" />
</div>
对于那些想根据图表上当前显示的内容(而不是基于总数据)显示动态百分比的人,可以试试这个代码:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var meta = dataset._meta[Object.keys(dataset._meta)[0]];
var total = meta.total;
var currentValue = dataset.data[tooltipItem.index];
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return currentValue + ' (' + percentage + '%)';
},
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
},
我遇到这个问题是因为我需要在堆积条形图上显示百分比。我需要的百分比是每个堆叠的列。我通过像这样修改 Willian Surya 的答案来完成此操作:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var index = tooltipItem.index;
var currentValue = data.datasets[tooltipItem.datasetIndex].data[index];
var total = 0;
data.datasets.forEach(function(el){
total = total + el.data[index];
});
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return currentValue + ' (' + percentage + '%)';
},
title: function(tooltipItem, data) {
return data.datasets[tooltipItem[0].datasetIndex].label;
}
}
}
这是最终结果:
在3.x及更高版本中用法有所改变,因此我将为此附上一个方法。
const data: ChartData = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
data: excerciseData,
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)"
]
}
]
};
...
callbacks: {
label: tooltipItem => {
let total = 0;
data.datasets[0].data.forEach(num => {
total += num as number;
});
const currentValue = data.datasets[0].data[tooltipItem.dataIndex] as number;
const percentage = ((currentValue * 100) / total).toFixed(1) + "%";
return `${currentValue}(${percentage})`;
},
title: tooltipItems => {
return tooltipItems[0].label;
}
}
在 3.5 中它将是:
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context){
var data = context.dataset.data,
label = context.label,
currentValue = context.raw,
total = 0;
for( var i = 0; i < data.length; i++ ){
total += data[i];
}
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return label + ": " +currentValue + ' (' + percentage + '%)';
}
}
}
}
}
但更好的是动态版本:
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context){
var label = context.label,
currentValue = context.raw,
total = context.chart._metasets[context.datasetIndex].total;
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return label + ": " +currentValue + ' (' + percentage + '%)';
}
}
}
}
}
只需使用这个:
const options = {
responsive: true,
plugins: {
tooltip: {
callbacks: {
label: (Item) => '%' + (Item.formattedValue) + ' | ' + Item.label
}
}
},
};
我曾使用 chart.js 1.0,我的圆环图工具提示显示基于数据除以数据集的百分比,但我无法用图表 2.0 复制它。
我到处搜索,但没有找到可行的解决方案。我知道它会在选项下进行,但我尝试过的一切充其量只是使馅饼功能失调。
<html>
<head>
<title>Doughnut Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="canvas-holder" style="width:75%">
<canvas id="chart-area" />
</div>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
486.5,
501.5,
139.3,
162,
263.7,
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Expenditures'
}],
labels: [
"Hospitals: 6.5 billion",
"Physicians & Professional Services: 1.5 billion",
"Long Term Care: 9.3 billion",
"Prescription Drugs: 2 billion",
"Other Expenditures: 3.7 billion"
]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
title: {
display: false,
text: 'Chart.js Doughnut Chart'
},
animation: {
animateScale: true,
animateRotate: true
}
}
};
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx, config);{
}
};
</script>
</body>
</html>
更新: 下面的答案显示了基于总数据的百分比,但是 @William Surya Permana
有一个很好的答案,它根据显示的数据更新
在options
中你可以传入一个tooltips
对象(更多可以在chartjs docs阅读)
tooltips
的一个字段,为了得到你想要的结果,是一个callbacks
的对象,有一个label
的字段。 label
将是一个函数,它接收您悬停的工具提示项和构成图表的数据。只是 return 一个字符串,你想从这个函数进入工具提示。
这是一个示例,说明它的样子
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
//get the concerned dataset
var dataset = data.datasets[tooltipItem.datasetIndex];
//calculate the total of this data set
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
//get the current items value
var currentValue = dataset.data[tooltipItem.index];
//calculate the precentage based on the total and current item, also this does a rough rounding to give a whole number
var percentage = Math.floor(((currentValue/total) * 100)+0.5);
return percentage + "%";
}
}
}
以及您提供的数据的完整示例
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
486.5,
501.5,
139.3,
162,
263.7,
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Expenditures'
}],
labels: [
"Hospitals: 6.5 billion",
"Physicians & Professional Services: 1.5 billion",
"Long Term Care: 9.3 billion",
"Prescription Drugs: 2 billion",
"Other Expenditures: 3.7 billion"
]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
title: {
display: false,
text: 'Chart.js Doughnut Chart'
},
animation: {
animateScale: true,
animateRotate: true
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var percentage = Math.floor(((currentValue/total) * 100)+0.5);
return percentage + "%";
}
}
}
}
};
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx, config); {
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.bundle.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder" style="width:75%">
<canvas id="chart-area" />
</div>
对于那些想根据图表上当前显示的内容(而不是基于总数据)显示动态百分比的人,可以试试这个代码:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
var meta = dataset._meta[Object.keys(dataset._meta)[0]];
var total = meta.total;
var currentValue = dataset.data[tooltipItem.index];
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return currentValue + ' (' + percentage + '%)';
},
title: function(tooltipItem, data) {
return data.labels[tooltipItem[0].index];
}
}
},
我遇到这个问题是因为我需要在堆积条形图上显示百分比。我需要的百分比是每个堆叠的列。我通过像这样修改 Willian Surya 的答案来完成此操作:
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var index = tooltipItem.index;
var currentValue = data.datasets[tooltipItem.datasetIndex].data[index];
var total = 0;
data.datasets.forEach(function(el){
total = total + el.data[index];
});
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return currentValue + ' (' + percentage + '%)';
},
title: function(tooltipItem, data) {
return data.datasets[tooltipItem[0].datasetIndex].label;
}
}
}
这是最终结果:
在3.x及更高版本中用法有所改变,因此我将为此附上一个方法。
const data: ChartData = {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
data: excerciseData,
backgroundColor: [
"rgba(255, 99, 132, 0.5)",
"rgba(54, 162, 235, 0.5)",
"rgba(255, 206, 86, 0.5)",
"rgba(75, 192, 192, 0.5)",
"rgba(153, 102, 255, 0.5)",
"rgba(255, 159, 64, 0.5)"
]
}
]
};
...
callbacks: {
label: tooltipItem => {
let total = 0;
data.datasets[0].data.forEach(num => {
total += num as number;
});
const currentValue = data.datasets[0].data[tooltipItem.dataIndex] as number;
const percentage = ((currentValue * 100) / total).toFixed(1) + "%";
return `${currentValue}(${percentage})`;
},
title: tooltipItems => {
return tooltipItems[0].label;
}
}
在 3.5 中它将是:
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context){
var data = context.dataset.data,
label = context.label,
currentValue = context.raw,
total = 0;
for( var i = 0; i < data.length; i++ ){
total += data[i];
}
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return label + ": " +currentValue + ' (' + percentage + '%)';
}
}
}
}
}
但更好的是动态版本:
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context){
var label = context.label,
currentValue = context.raw,
total = context.chart._metasets[context.datasetIndex].total;
var percentage = parseFloat((currentValue/total*100).toFixed(1));
return label + ": " +currentValue + ' (' + percentage + '%)';
}
}
}
}
}
只需使用这个:
const options = {
responsive: true,
plugins: {
tooltip: {
callbacks: {
label: (Item) => '%' + (Item.formattedValue) + ' | ' + Item.label
}
}
},
};