需要使用chart.js在分组条形图中表示给定数据,并且无法为每个条形指定名称

问题描述 投票:0回答:1

我有以下数据集

const javaData = [
  { name: "NASC-02", type: "Interface", value: 6, bgColor: "red" },
  { name: "NASC-03", type: "Interface", value: 7, bgColor: "green" },
  { name: "NASC-04", type: "Interface", value: 9, bgColor: "blue" },
  { name: "FUNC-01", type: "Function", value: 3, bgColor: "red" },
  { name: "FUNC-02", type: "Function", value: 10, bgColor: "green" },
  { name: "FUNC-03", type: "Function", value: 1, bgColor: "blue" },
];

我想使用 Chart.js 创建分组条形图。 x 轴应代表对象的类型,在本例中为“接口”和“函数”。每个条的值和颜色应由各自的对象确定。

我已使用提供的数据成功创建了分组图表。但是,我在为每个栏指定名称时遇到困难。具体来说,我希望“Interface”组中每个栏的名称对应于名称“NASC-02”、“NASC-03”等,而“Function”组中的每个栏的名称对应于“FUNC-01” 、“FUNC-02”等

如果需要,我也可以从后端更改数据格式

    var javaData = {
  "Interface": {
    "NASC-01": 2,
    "NASC-02": 5,
    "NASC-03": 8
  },
  "Function": {
    "FUNC-01": 20,
    "FUNC-02": 25,
    "FUNC-03": 18
  }
};

下面是我尝试使用上面给出的数组格式数据的代码,图表正确,但无法为每个条形指定名称

    <!DOCTYPE html>
<html>
<head>
  <title>Defect Closure Duration by Type</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
</head>
<body>
  <canvas id="defectChart" width="600" height="300"></canvas>

  <script>
    var javaData = [
      { name: "NASC-02", type: "Interface", value: 6, bgColor: "red" },
      { name: "NASC-03", type: "Interface", value: 7, bgColor: "green" },
      { name: "NASC-04", type: "Interface", value: 9, bgColor: "blue" },
      { name: "FUNC-01", type: "Function", value: 3, bgColor: "red" },
      { name: "FUNC-02", type: "Function", value: 10, bgColor: "green" },
      { name: "FUNC-03", type: "Function", value: 1, bgColor: "blue" },
    ];
    

    // Group data by month
    const groupedData = javaData.reduce((acc, item) => {
      if (!acc[item.type]) {
        acc[item.type] = {};
      }
      acc[item.type][item.name] = item.value;
      return acc;
    }, {});

    // Extract labels and values for each month
    const labels = Object.keys(groupedData);
    const interfaceValues = Object.values(groupedData["Interface"]);
    const functionValues = Object.values(groupedData["Function"]);
    
    const datas = [];

   for (let i = 0; i < interfaceValues.length; i++) {
    datas.push([interfaceValues[i], functionValues[i]]);
   }

const dataset = datas.map((data, index) => {
    return {
        data: data,
        backgroundColor: index === 0 ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)',
        borderColor: index === 0 ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)',
        borderWidth: 1
    };
});

    var ctx = document.getElementById("defectChart").getContext("2d");
    var chart = new Chart(ctx, {
      type: 'bar',
      data: {
        labels: labels,
        datasets: dataset
      },
      options: {
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }]
        }
      }
    });
  </script>
</body>
</html>

下面是我需要酒吧名称的屏幕

javascript chart.js
1个回答
0
投票

这很棘手,因为每个组/类别都有其数据集,并且带有条形图/数据集的 Chart.JS 示例/设计将具有多个类别。

  1. 在每个数据集中,您可以提供
    datalabels
    属性来设置每个条中显示的数据标签的位置。更多信息和配置可以参考定位| Chartjs-plugin-datalabels 文档.
const dataset = datas.map((data, index) => {
  return {
    data: data,
    backgroundColor:
      index === 0 ? 'rgba(255, 99, 132, 0.2)' : 'rgba(54, 162, 235, 0.2)',
    borderColor:
      index === 0 ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)',
    borderWidth: 1,
    datalabels: {
      align: 'top',
      anchor: 'end',
    },
  };
});
  1. 实现一个函数以通过位置获取
    name
    。您需要确保
    javaData
    type
    排序以确保正确性。公式:
function getBarLabelName(dataIndex, datasetIndex) {
  return javaData[2 * dataIndex + dataIndex + datasetIndex].name;
}

datalabels
中添加
plugins
对象,用于在每个栏中显示标签。

plugins: {
  ...,
  datalabels: {
    color: 'black', // Set the color of the data labels
    font: {
      weight: 'bold',
    },
    formatter: function (value, context) {
      return getBarLabelName(context.dataIndex, context.datasetIndex);
    },
  }
}

不要忘记注册

ChartDataLabels
插件。

new Chart(ctx, {
  ...,
  plugins: [ChartDataLabels],
});
  1. (可选)如果您想自定义工具提示以在悬停时显示每个栏的标签名称:
plugins: {
  ...,
  tooltip: {
    callbacks: {
      label: function (context) {
        let label = getBarLabelName(
          context.dataIndex,
          context.datasetIndex
        );

        label += ': ';
        label += context.parsed.y;

        return label;
      }
    }
  }
}
  1. 请注意,您的
    yAxes
    配置带有数组
    []
    。这是 Chart.js 版本 2.X 的旧配置。对于版本 4,它应该是:
options: {
  scales: {
    y: {
      ticks: {
        beginAtZero: true,
      },
      max: Math.max(...javaData.map((x) => x.value)) + 2,
    }
  }
}

当值为 y 轴最大值时,您可能会遇到数据标签溢出的情况。在这种情况下,您需要增加 y 轴的

max
值。

演示@StackBlitz

© www.soinside.com 2019 - 2024. All rights reserved.