如何在饼图中用离子线中的线条显示数据标签

时间:2017-12-15 05:46:06

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

我正在制作图表,我想要创建一个与下面显示的图像相同的饼图。我有一些使用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

的样子

所以有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:3)

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

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

画 2 条线连接 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();
    }
  }

答案 1 :(得分:1)

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

chartjs-plugin-piechart-outlabels

Read the documentation

答案 2 :(得分:0)

样式的问题是type: 'doughnut'。这将显示圆环样式图表,如果您想要饼图样式,则应使用type: 'pie'

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

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

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