Como posso mostrar um subconjunto de dados em partes de torta no Chart.JS enquanto ainda exibe o superconjunto ao passar o mouse?
Eu tenho um gráfico de pizza que fica assim quando passa o mouse sobre um pedaço de torta:
Exceto por querer a lendapara a direita em vez de no topo, Estou bastante contente com isso, mas quero que apenas o valor percentual exiba "o tempo todo" nos pedaços de pizza - e ainda tenha o<name> (<%val>): <data>
exibido em foco.
Em outras palavras, quero que a torta pareça algo assim:
Como posso separar esses dados (a porcentagem) e desenhá-los em cada pedaço de pizza?
Aqui está o código que estou usando até agora:
var formatter = new Intl.NumberFormat("en-US");
var data = {
labels: [
"Bananas (18%)",
"Lettuce, Romaine (14%)",
"Melons, Watermelon (10%)",
"Pineapple (10%)",
"Berries (10%)",
"Lettuce, Spring Mix (9%)",
"Broccoli (8%)",
"Melons, Honeydew (7%)",
"Grapes (7%)",
"Melons, Cantaloupe (7%)"
],
datasets: [
{
data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076, 1056, 1048],
backgroundColor: [
"#FFE135",
"#3B5323",
"#fc6c85",
"#ffec89",
"#021c3d",
"#3B5323",
"#046b00",
"#cef45a",
"#421C52",
"#FEA620"
]
}
]
};
var optionsPie = {
responsive: true,
scaleBeginAtZero: true,
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
return data.labels[tooltipItem.index] + ": " +
formatter.format(data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]);
}
}
}
};
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var top10PieChart = new Chart(ctx,
{
type: 'pie',
data: data,
options: optionsPie
});
$("#top10Legend").html(top10PieChart.generateLegend());
Preciso adicionar um evento afterDraw () e, em caso afirmativo, como ele precisa para fazer isso?
ATUALIZARTentei adicionar um retorno de chamada onAnimationComplete () ao construtor de gráfico:
var top10PieChart = new Chart(ctx,
{
type: 'pie',
data: data,
options: optionsPie,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor;
ctx.textAlign = "center";
ctx.textBaseline = "center";
this.datasets.forEach(function(dataset) {
dataset.points.forEach(function(points) {
ctx.fillText(points.value, points.x, points.y - 10);
});
});
}
});
... mas não faz nada.
ATUALIZAÇÃO 2Também tentei anexar o seguinte ao objeto de opções:
,
tooltipTemplate: "<%= value %>",
onAnimationComplete: function () {
this.showTooltip(this.datasets[0].bars, true);
}
... com os mesmos resultados (sem alteração).
ATUALIZAÇÃO 3Ok, eu esperava que a respostaaqui funcionaria e acabou com este novo código para o meu gráfico de pizza com base na resposta:
Adicionado às opções
showTooltips: false,
onAnimationProgress: drawSegmentValues
Adicionado após a referência ao elemento ser recuperada:
var midX = canvas.width / 2;
var midY = canvas.height / 2
Adicionado depois que a instância do gráfico de pizza é construída:
var radius = top10PieChart.outerRadius;
Função adicionada drawSegmentValues ()
No contexto (sem trocadilhos):
// Top 10 Pie Chart
var formatter = new Intl.NumberFormat("en-US");
var data = {
labels: [
"Bananas (18%)",
"Lettuce, Romaine (14%)",
"Melons, Watermelon (10%)",
"Pineapple (10%)",
"Berries (10%)",
"Lettuce, Spring Mix (9%)",
"Broccoli (8%)",
"Melons, Honeydew (7%)",
"Grapes (7%)",
"Melons, Cantaloupe (7%)"
],
datasets: [
{
data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076
1056, 1048],
backgroundColor: [
"#FFE135",
"#3B5323",
"#fc6c85",
"#ffec89",
"#021c3d",
"#3B5323",
"#046b00",
"#cef45a",
"#421C52",
"#FEA620"
]
}
]
};
var optionsPie = {
responsive: true,
scaleBeginAtZero: true,
legend: {
display: false
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
return data.labels[tooltipItem.index] + ": " +
formatter.format
data.datasets[tooltipItem.datasetIndex].data[
tooltipItem.index]);
}
}
},
showTooltips: false,
onAnimationProgress: drawSegmentValues
};
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var midX = canvas.width / 2;
var midY = canvas.height / 2
, var top10PieChart = new Chart(ctx,
{
type: 'pie',
data: data,
options: optionsPie//,
});
var radius = top10PieChart.outerRadius;
$("#top10Legend").html(top10PieChart.generateLegend());
// </ Top 10 Pie Chart
// Price Compliance Bar Chart
. . . this horizontal bar chart code elided for brevity, bu
unchanged from their working state
// Forecast/Impact Analysis Bar chart
. . . this horizontal bar chart code also elided for brevity, bu
unchanged from their working state
function drawSegmentValues() {
for (var i = 0; i < top10PieChart.segments.length; i++) {
ctx.fillStyle = "white";
var textSize = canvas.width / 10;
ctx.font = textSize + "px Verdana";
// Get needed variables
var value = top10PieChart.segments[i].value;
var startAngle = top10PieChart.segments[i].startAngle;
var endAngle = top10PieChart.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 by middle
var w_offset = ctx.measureText(value).width / 2;
var h_offset = textSize / 4;
ctx.fillText(value, posX - w_offset, posY + h_offset);
}
}
... mas mangueira completamente todos os três gráficos, deixando nada visível / desenho.
ATUALIZAÇÃO 4A propósito, tentei a resposta dada, mas sem resultado / alteração - ele ainda exibe dados em foco, conforme planejado, mas não há nada de diferente.
Além disso, o violino relacionado mostra o valor e a porcentagem; devido a restrições imobiliárias, quero que a porcentagem esteja "sempre ativa" - a "enchilada inteira" deve ser vista apenas quando estiver pairando.