【问题标题】:How to display data labels outside in pie chart with lines in ionic如何在饼图中用离子线显示数据标签
【发布时间】:2018-05-29 07:37:51
【问题描述】:

我正在处理图表,我想创建一个与下面显示的图像相同的饼图。我得到了一些使用 chart.js 的示例,但它不能用作 我想在图表外显示数据标签的图像,其中的线条表示数据标签的部分。

home.ts

this.doughnutChart = new Chart(this.doughnutCanvas.nativeElement, {

                 type: 'doughnut',
                 data: {
                     labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
                     datasets: [{
                         label: '# of Votes',
                         data: [12, 19, 3, 5, 2, 3],
                         backgroundColor: [
                             'rgba(255, 99, 132, 0.2)',
                             'rgba(54, 162, 235, 0.2)',
                             'rgba(255, 206, 86, 0.2)',
                             'rgba(75, 192, 192, 0.2)',
                             'rgba(153, 102, 255, 0.2)',
                             'rgba(255, 159, 64, 0.2)'
                         ],
                         hoverBackgroundColor: [
                             "#FF6384",
                             "#36A2EB",
                             "#FFCE56",
                             "#FF6384",
                             "#36A2EB",
                             "#FFCE56"
                         ]
                     }]
                 }

             });

home.html

<ion-card>
    <ion-card-header>
      Doughnut Chart
    </ion-card-header>
    <ion-card-content>
      <canvas #doughnutCanvas></canvas>
    </ion-card-content>
  </ion-card>

我想要的样子

使用 chart.js 的样子

那么谁能帮我解决这个问题?

【问题讨论】:

    标签: javascript ionic-framework charts ionic2 chart.js


    【解决方案1】:

    您必须编写一个插件才能做到这一点。 在afterDraw 钩子中,您必须遍历图表元素并计算 3 个点:

    1. Point1:当前圆弧的中心点
    2. Point2:通过连接图表的中心和Point1 创建,长度 = 半径 + X(x > 0 将提供更好的视觉效果)
    3. Point3:通过连接Point2 与基于Point2.x 的图表边缘(左/右)创建

    画两条线来连接 Point1 和 Point2,Point2 和 Point3 会给你这个图表:

    https://imgur.com/a/rWaV2x3

    chartjs 2.9.4 的示例代码:

    const DoughnutLabelPlugin = {
        afterDraw: (chart) => {
          const ctx = chart.chart.ctx;
          ctx.save();
          ctx.font = "10px 'Averta Std CY'";
          const chartCenterPoint = {
            x:
              (chart.chartArea.right - chart.chartArea.left) / 2 +
              chart.chartArea.left,
            y:
              (chart.chartArea.bottom - chart.chartArea.top) / 2 +
              chart.chartArea.top
          };
          chart.config.data.labels.forEach((label, i) => {
            const meta = chart.getDatasetMeta(0);
            const arc = meta.data[i];
            const dataset = chart.config.data.datasets[0];
    
            // Prepare data to draw
            // important point 1
            const centerPoint = arc.getCenterPoint();
            const model = arc._model;
            let color = model.borderColor;
            let labelColor = model.borderColor;
            if (dataset.polyline && dataset.polyline.color) {
              color = dataset.polyline.color;
            }
    
            if (dataset.polyline && dataset.polyline.labelColor) {
              labelColor = dataset.polyline.labelColor;
            }
    
            const angle = Math.atan2(
              centerPoint.y - chartCenterPoint.y,
              centerPoint.x - chartCenterPoint.x
            );
            // important point 2
            const point2X =
              chartCenterPoint.x + Math.cos(angle) * (model.outerRadius + 20);
            let point2Y =
              chartCenterPoint.y + Math.sin(angle) * (model.outerRadius + 20);
    
            let value = dataset.data[i];
            if (dataset.polyline && dataset.polyline.formatter) {
              value = dataset.polyline.formatter(value);
            }
            let edgePointX = point2X < chartCenterPoint.x ? 10 : chart.width - 10;
    
            //DRAW CODE
            // first line: connect between arc's center point and outside point
            ctx.strokeStyle = color;
            ctx.beginPath();
            ctx.moveTo(centerPoint.x, centerPoint.y);
            ctx.lineTo(point2X, point2Y);
            ctx.stroke();
            // second line: connect between outside point and chart's edge
            ctx.beginPath();
            ctx.moveTo(point2X, point2Y);
            ctx.lineTo(edgePointX, point2Y);
            ctx.stroke();
            //fill custom label
            const labelAlignStyle =
              edgePointX < chartCenterPoint.x ? "left" : "right";
            const labelX = edgePointX;
            const labelY = point2Y;
            ctx.textAlign = labelAlignStyle;
            ctx.textBaseline = "bottom";
    
            ctx.fillStyle = labelColor;
            ctx.fillText(value, labelX, labelY);
          });
          ctx.restore();
        }
      }
    

    【讨论】:

    • 谢谢你。请找到图表 js v3 link 的工作版本
    【解决方案2】:

    要拥有此插座,您必须将以下插件添加到您的项目中:

    chartjs-plugin-piechart-outlabels

    Read the documentation

    【讨论】:

      【解决方案3】:

      样式的问题是type: 'doughnut'。这将显示一个甜甜圈样式图表,如果您想要饼样式,您应该使用type: 'pie'

      欲了解更多信息:http://www.chartjs.org/docs/latest/charts/doughnut.html

      另外,关于数据标签,我认为chartJs目前不支持该样式,您可以尝试自定义:http://www.chartjs.org/docs/latest/configuration/tooltip.html#tooltip-configuration

      或者尝试一些选项.. https://github.com/chartjs/chartjs-plugin-datalabels

      【讨论】:

      • 我不想要饼图样式,我想在图表外显示数据标签,用线条表示数据标签
      • 是的,这就是为什么我在那里放了一些带有选项的链接。您可以尝试使用工具提示配置自定义数据标签,添加类并自己做,或者您可以尝试一些外部库@gaurang
      猜你喜欢
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多