<bdo id='qZ8Yg'></bdo><ul id='qZ8Yg'></ul>
<tfoot id='qZ8Yg'></tfoot><legend id='qZ8Yg'><style id='qZ8Yg'><dir id='qZ8Yg'><q id='qZ8Yg'></q></dir></style></legend>

      1. <i id='qZ8Yg'><tr id='qZ8Yg'><dt id='qZ8Yg'><q id='qZ8Yg'><span id='qZ8Yg'><b id='qZ8Yg'><form id='qZ8Yg'><ins id='qZ8Yg'></ins><ul id='qZ8Yg'></ul><sub id='qZ8Yg'></sub></form><legend id='qZ8Yg'></legend><bdo id='qZ8Yg'><pre id='qZ8Yg'><center id='qZ8Yg'></center></pre></bdo></b><th id='qZ8Yg'></th></span></q></dt></tr></i><div id='qZ8Yg'><tfoot id='qZ8Yg'></tfoot><dl id='qZ8Yg'><fieldset id='qZ8Yg'></fieldset></dl></div>

        <small id='qZ8Yg'></small><noframes id='qZ8Yg'>

        如何在 Chart.JS 中显示饼图的数据子集,同时在悬停时仍显示超集?

        时间:2023-11-02

        <small id='3Aydn'></small><noframes id='3Aydn'>

        <legend id='3Aydn'><style id='3Aydn'><dir id='3Aydn'><q id='3Aydn'></q></dir></style></legend>

              <tbody id='3Aydn'></tbody>
          • <i id='3Aydn'><tr id='3Aydn'><dt id='3Aydn'><q id='3Aydn'><span id='3Aydn'><b id='3Aydn'><form id='3Aydn'><ins id='3Aydn'></ins><ul id='3Aydn'></ul><sub id='3Aydn'></sub></form><legend id='3Aydn'></legend><bdo id='3Aydn'><pre id='3Aydn'><center id='3Aydn'></center></pre></bdo></b><th id='3Aydn'></th></span></q></dt></tr></i><div id='3Aydn'><tfoot id='3Aydn'></tfoot><dl id='3Aydn'><fieldset id='3Aydn'></fieldset></dl></div>

              • <tfoot id='3Aydn'></tfoot>

                • <bdo id='3Aydn'></bdo><ul id='3Aydn'></ul>
                  本文介绍了如何在 Chart.JS 中显示饼图的数据子集,同时在悬停时仍显示超集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有一个饼图,当我将鼠标悬停在一块饼上时,它看起来像这样:

                  除了想要图例

                  我怎样才能把那一段数据(百分比)分解出来,然后画到每一块饼上?

                  这是我目前使用的代码:

                  var formatter = new Intl.NumberFormat("en-US");变量数据 = {标签: [香蕉(18%)",生菜,长叶莴苣(14%)",瓜,西瓜(10%)",菠萝(10%)",浆果(10%)",生菜,春季混合(9%)",西兰花(8%)",甜瓜,蜜露(7%)",葡萄(7%)",甜瓜、哈密瓜 (7%)"],数据集:[{数据:[2755、2256、1637、1608、1603、1433、1207、1076、1056、1048]、背景颜色: ["#FFE135","#3B5323","#fc6c85","#ffec89","#021c3d","#3B5323","#046b00","#cef45a","#421C52",#FEA620"]}]};var optionsPie = {响应式:真实,scaleBeginAtZero:真,工具提示:{回调:{标签:函数(工具提示项,数据){返回 data.labels[tooltipItem.index] + ": " +formatter.format(data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]);}}}};var ctx = $("#top10ItemsChart").get(0).getContext("2d");var top10PieChart = 新图表(ctx,{类型:'馅饼',数据:数据,选项:选项饼});$("#top10Legend").html(top10PieChart.generateLegend());

                  我是否需要添加 afterDraw() 事件,如果需要,它需要如何实现?

                  更新

                  我尝试在图表构造函数中添加一个 onAnimationComplete() 回调:

                  var top10PieChart = new Chart(ctx,{类型:'馅饼',数据:数据,选项:选项饼,onAnimationComplete: 函数 () {var ctx = this.chart.ctx;ctx.font = this.scale.font;ctx.fillStyle = this.scale.textColor;ctx.textAlign = "中心";ctx.textBaseline = "中心";this.datasets.forEach(函数(数据集){dataset.points.forEach(函数(点){ctx.fillText(points.value, points.x, points.y - 10);});});}});

                  ...但它什么也没做.

                  更新 2

                  我还尝试将以下内容附加到选项对象:

                  <代码>,tooltipTemplate: "<%= value %>",onAnimationComplete: 函数 () {this.showTooltip(this.datasets[0].bars, true);}

                  ...结果相同(没有变化).

                  更新 3

                  好的,我希望答案

                  I've got a pie chart that looks like this when hovering over a piece of pie:

                  Except for wanting the legend to the right instead of on top, I'm fairly content with this, but I want just the percentage value to display "all the time" in the pie pieces - and still have the <name> (<%val>): <data> displayed on hover.

                  In other words, I want the pie to look something like this:

                  How can I break that one piece of data out (the percentage) and draw that onto each piece of pie?

                  Here is the code I'm using so far:

                  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());
                  

                  Do I need to add an afterDraw() event and, if so, just how does it need to look to accomplish this?

                  UPDATE

                  I tried adding an onAnimationComplete() callback to the chart constructor:

                  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);
                              });
                          });
                      }
                  });
                  

                  ...but it does nothing.

                  UPDATE 2

                  I also tried appending the following to the options object:

                  ,
                  tooltipTemplate: "<%= value %>",
                  onAnimationComplete: function () {
                      this.showTooltip(this.datasets[0].bars, true);
                  }
                  

                  ...with the same results (no change).

                  UPDATE 3

                  Okay, I was hopeful that the answer here would work, and ended up with this new code for my pie chart based on the answer there:

                  Added to optionsPie:

                  showTooltips: false,
                  onAnimationProgress: drawSegmentValues
                  

                  Added after reference to element is retrieved:

                  var midX = canvas.width / 2;
                  var midY = canvas.height / 2
                  

                  Added after pie chart instance is constructed:

                  var radius = top10PieChart.outerRadius;
                  

                  Added function drawSegmentValues()

                  In context (no pun intended):

                          // 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);
                          }
                      }
                  

                  ...but it completely hosed all three charts, leaving nothing visible/drawing.

                  UPDATE 4

                  By the way, I tried the given answer, but with no result/change - it still displays data on hover, as designed, but there is nothing otherwise.

                  Also, the related fiddle shows both the value and the percentage; due to real estate restrictions, I want the percentage only to be "always on" - the "whole enchilada" is only to be seen when hovering.

                  解决方案

                  The following solution is using the same calculation as lamelemon's but using Chart.js plugins, which brings additional benefits :

                  • There is no longer this blink effect caused by the animation.onComplete since it occurs immediatly without waiting for antything.

                  • The tooltip is above the text, which is more natural.

                  Follows the plugin that does it :

                  Chart.pluginService.register({
                      afterDatasetsDraw: function(chartInstance) {
                  
                          // We get the canvas context
                          var ctx = chartInstance.chart.ctx;
                  
                          // And set the properties we need
                          ctx.font = Chart.helpers.fontString(14, 'bold', Chart.defaults.global.defaultFontFamily);
                          ctx.textAlign = 'center';
                          ctx.textBaseline = 'bottom';
                          ctx.fillStyle = '#666';
                  
                          // For ervery dataset ...
                          chartInstance.config.data.datasets.forEach(function(dataset) {
                  
                              // For every data in the dataset ...
                              for (var i = 0; i < dataset.data.length; i++) {
                  
                                  // We get all the properties & values we need
                                  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;
                  
                                  // We calculate the right positions for our text
                                  var x = mid_radius * 1.5 * Math.cos(mid_angle);
                                  var y = mid_radius * 1.5 * Math.sin(mid_angle);
                  
                                  // We calculate the percentage
                                  var percent = String(Math.round(dataset.data[i] / total * 100)) + "%";
                                  // And display it
                                  ctx.fillText(percent, model.x + x, model.y + y);
                              }
                          });
                      }
                  });
                  


                  You can check this plugin working on this jsFiddle, and here is the result :

                  这篇关于如何在 Chart.JS 中显示饼图的数据子集,同时在悬停时仍显示超集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何在 chart.js 中应用渐变颜色? 下一篇:chart.js 条形图根据值改变颜色

                  相关文章

                  1. <small id='xoO1B'></small><noframes id='xoO1B'>

                    <legend id='xoO1B'><style id='xoO1B'><dir id='xoO1B'><q id='xoO1B'></q></dir></style></legend>
                    • <bdo id='xoO1B'></bdo><ul id='xoO1B'></ul>
                    <i id='xoO1B'><tr id='xoO1B'><dt id='xoO1B'><q id='xoO1B'><span id='xoO1B'><b id='xoO1B'><form id='xoO1B'><ins id='xoO1B'></ins><ul id='xoO1B'></ul><sub id='xoO1B'></sub></form><legend id='xoO1B'></legend><bdo id='xoO1B'><pre id='xoO1B'><center id='xoO1B'></center></pre></bdo></b><th id='xoO1B'></th></span></q></dt></tr></i><div id='xoO1B'><tfoot id='xoO1B'></tfoot><dl id='xoO1B'><fieldset id='xoO1B'></fieldset></dl></div>
                      <tfoot id='xoO1B'></tfoot>