You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中Chart.js水平条形图数据传递:解决重复项与颜色统一问题

Angular中Chart.js水平条形图数据处理问题解决

问题场景

需要将给定的JSON响应数据传入Chart.js水平条形图,但现有代码运行后出现两个问题:

  • 同一渠道在不同阶段被重复显示为独立数据集
  • 同一渠道在不同阶段的颜色不一致

原始响应数据

{
  "Response": [
    {
      "Description": "Prima Fase",
      "Id": 49,
      "Items": [
        {"Id": -1, "Description": "Nessun Canale", "Number": 7},
        {"Id": 5, "Description": "Altro Canale", "Number": 3},
        {"Id": 21, "Description": "Collaboratore Enzo", "Number": 1}
      ]
    },
    {
      "Description": "Seconda Fase",
      "Id": 70,
      "Items": [
        {"Id": -1, "Description": "Nessun Canale", "Number": 3},
        {"Id": 3, "Description": "Web", "Number": 3},
        {"Id": 5, "Description": "Altro Canale", "Number": 3},
        {"Id": 27, "Description": "15C", "Number": 1}
      ]
    }
  ]
}

现有代码问题

原代码遍历每个阶段的每个渠道,每次都向barChartData中添加新数据集,导致同一渠道(如"Nessun Canale")被拆分为多个独立数据集,既出现重复,又无法保证颜色一致。

修正后的代码

getDataForFunnel() {
  this.barChartData = [];
  this.barChartLabels = [];
  // 预定义颜色池,为每个渠道分配固定颜色
  const colorPool = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40'];
  let colorIndex = 0;

  this.funnelService.getFunnelGraph(this.funnelForm.value).subscribe(
    (response) => {
      const phases = response.Response || [];
      this.funnelService.allDatasFunnel = phases;
      this.currentResponseMessage = response.Response?.Message;

      // 提取所有阶段名称作为图表横轴标签
      this.barChartLabels = phases.map(phase => phase.Description);

      // 用Map收集所有唯一渠道,按ID去重并分配固定颜色
      const uniqueChannels = new Map();
      phases.forEach(phase => {
        phase.Items.forEach(channel => {
          if (!uniqueChannels.has(channel.Id)) {
            uniqueChannels.set(channel.Id, {
              ...channel,
              color: colorPool[colorIndex++ % colorPool.length]
            });
          }
        });
      });

      // 为每个唯一渠道构建对应的数据集
      uniqueChannels.forEach(channel => {
        // 遍历所有阶段,填充当前渠道在该阶段的数值,无数据则填0
        const channelData = phases.map(phase => {
          const matchedItem = phase.Items.find(item => item.Id === channel.Id);
          return matchedItem ? matchedItem.Number : 0;
        });

        this.barChartData.push({
          data: channelData,
          stack: "a",
          label: channel.Description,
          backgroundColor: channel.color, // 固定颜色,保证同一渠道颜色一致
          channelID: channel.Id,
          phaseIds: phases.map(p => p.Id) // 可选:保存所有阶段ID用于后续逻辑
        });
      });
    }
  );
}

关键优化点

  • 去重处理:使用Map按渠道ID收集唯一渠道,避免重复创建数据集
  • 固定颜色:为每个唯一渠道分配预定义颜色池中的颜色,确保同一渠道在所有阶段颜色一致
  • 数据对齐:遍历所有阶段为渠道填充数值,无对应数据时填0,保证数据集长度与阶段数量匹配
  • 修正响应解析:原代码错误解析了响应结构(response.Response是数组而非包含Items的对象),现已修正

内容的提问来源于stack exchange,提问作者Hamza Marwani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:06:32