Chartjs 使用动态和可变 JSON 的多条形图

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

我正在尝试创建一个基于 json 数据的条形图,该数据根据过滤器动态变化。

我希望图表显示与 PERIOD 相关的 TYPE(如果存在)。如果没有,则不显示任何内容。

我能够根据此讨论获得显示数据的图表,但只有在数据的所有选项均可用时才有效,但事实并非如此。

但是,如果某个 PERIOD 中缺少 TYPE,它会将 TYPE 移回到前一个 PERIOD,这是我不希望的。

这里有两个例子

  1. 两个月有两种类型,但只有 3 个值(看起来正确)
 [
    {
        "Period": "2023-12",
        "Total": 2238.86,
        "Type": "Drinks"
    },
    {
        "Period": "2023-12",
        "Total": 4672.35,
        "Type": "Food"
    },
    {
        "Period": "2024-01",
        "Total": 1166.5,
        "Type": "Drinks"
    }
]

enter image description here

  1. 三个月,三种类型,4个值(第二期数据移至第一期)
[
    {
        "Period": "2023-11",
        "Total": 2782.13,
        "Type": "Other"
    },
    {
        "Period": "2023-12",
        "Total": 2238.86,
        "Type": "Drinks"
    },
    {
        "Period": "2023-12",
        "Total": 4672.35,
        "Type": "Food"
    },
    {
        "Period": "2024-01",
        "Total": 1166.5,
        "Type": "Drinks"
    }
]

data from second period shifted to the first period

我已经搜索了好几天,尝试了不同的方法,但似乎没有任何效果。

这是我根据前面提到的主题使用的代码

jQuery.ajax({
    url: "../../ajax/barGraph.php?period=<?= $period; ?>",
    type: "GET",
    dataType: 'json',
    success: function(soldeInfo) {



          let labels = [...new Set(soldeInfo.map((x) => x.Period))];
          let datasets = soldeInfo.reduce(function (acc, cur) {
            let Type = acc.find((x) => x.label == cur.Type);
            if (Type == null) {
              let color = '';

              switch (cur.Type) {
                case 'Food':
                  color = 'red';
                  break;
                case 'Drinks':
                  color = 'green';
                  break;
                default:
                  color ='gray';
              }

              Type = {
                label: cur.Type,
                data: [cur.Total],
                backgroundColor: color,
                borderColor: color,
                borderWidth: 1,
              };

              acc.push(Type);
            } else {
              Type.data.push(cur.Total);
            }

            return acc;
          }, []);

          var soldeInfo = {
            type: 'bar',
            data: {
              labels: labels,
              datasets: datasets,
            },
          };

            const soldeChart = document.getElementById('chartSolde');
            new Chart(soldeChart, soldeInfo);



    }
});

非常感谢:)

json chart.js bar-chart
1个回答
0
投票

每个数据集中的可用值从左到右绘制在空闲位置。 因此,每个

data
数组必须在不存在实际值的位置包含空值。

请查看您修改后的可运行代码,看看如何做到这一点。

const soldeInfo = [
    { "Period": "2023-11", "Total": 2782.13, "Type": "Other" },
    { "Period": "2023-12", "Total": 2238.86, "Type": "Drinks" },
    { "Period": "2023-12", "Total": 4672.35, "Type": "Food" },
    { "Period": "2024-01", "Total": 1166.5, "Type": "Drinks" }
];

const colorOf = (type) => {
  switch (type) {
    case 'Food':
      return 'red';
    case 'Drinks':
      return 'green';
    default:
      return 'gray';
  }
}

let labels = [...new Set(soldeInfo.map((x) => x.Period))];
let datasets = soldeInfo.reduce(function(acc, cur) {
  let type = acc.find((x) => x.label == cur.Type);
  if (type == null) {
    let color = colorOf(cur.Type);
    type = {
      label: cur.Type,
      data: new Array(labels.length).fill(0),
      backgroundColor: color,
      borderColor: color,
      borderWidth: 1,
    };
    acc.push(type);
  }
  type.data[labels.indexOf(cur.Period)] = cur.Total;  
  return acc;
}, []);

new Chart('chartSolde', {
  type: 'bar',
  data: {
    labels: labels,
    datasets: datasets,
  },
});
<script src="https://cdn.jsdelivr.net/npm/chart.js@^4"></script>
<canvas id="chartSolde" height="90"></canvas>

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