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

如何基于现有数据用C3.js生成指定样式的班次条形图?

使用C3.js实现目标班次堆叠柱状图

看了你提供的需求、数据和目标样式,你想要的应该是按日期分组的堆叠柱状图——每个日期下堆叠展示itemA、itemB、itemC的数量,同时附带班次时间信息。之前的示例可能没针对你的数据结构做适配,所以效果达不到预期,我来给你整理数据调整建议和完整的实现代码。

一、数据结构调整建议

你当前的dataItems结构里,每个日期的班次信息和物品数量是分散存储的,C3.js无法直接解析这种嵌套格式。我们需要把它转换成C3兼容的扁平结构:

  1. 提取所有日期作为x轴的分类标签
  2. 把每个物品的数量按日期整理成独立的数值数组
  3. 班次的起止时间可以作为元数据,用于tooltip或x轴标注

手动转换后的示例结构

// 转换后的C3兼容数据
var transformedData = {
  x: 'dates',
  columns: [
    ['dates', '2017/02/04', '2017/04/04', '2017/05/04'],
    ['itemA', 600, 720, 450],
    ['itemB', 400, 1000, 800],
    ['itemC', 500, 850, 1000]
  ],
  // 存储班次时间元数据,用于tooltip展示
  shiftTimes: {
    '2017/02/04': '05:30:00 - 05:30:00',
    '2017/04/04': '05:30:00 - 05:30:00',
    '2017/05/04': '05:30:00 - 05:30:00'
  }
};

自动转换原始数据的函数

如果后续会新增数据,推荐用代码自动转换,避免手动整理:

// 从原始dataItems转换为C3格式的工具函数
function transformRawData(rawData) {
  const dates = [];
  const itemA = ['itemA'];
  const itemB = ['itemB'];
  const itemC = ['itemC'];
  const shiftTimes = {};

  rawData.forEach(dateItem => {
    dates.push(dateItem.title);
    // 提取当前日期的班次时间(假设每个日期只有一个班次)
    const targetShift = dateItem.shifts[0];
    shiftTimes[dateItem.title] = `${targetShift.startTime} - ${targetShift.endTime}`;
    // 提取每个物品的数量
    targetShift.items.forEach(item => {
      if (item.quantities.itemA !== undefined) {
        itemA.push(item.quantities.itemA);
      } else if (item.quantities.itemB !== undefined) {
        itemB.push(item.quantities.itemB);
      } else if (item.quantities.itemC !== undefined) {
        itemC.push(item.quantities.itemC);
      }
    });
  });

  return {
    x: 'dates',
    columns: [['dates', ...dates], itemA, itemB, itemC],
    shiftTimes
  };
}

// 调用函数转换原始数据
var c3Data = transformRawData(dataItems);

二、C3.js完整实现示例

基于转换后的数据,我们可以配置出匹配目标样式的堆叠柱状图:

// 初始化C3图表
var chart = c3.generate({
  bindto: '#chart', // 绑定页面上的DOM元素ID
  data: {
    x: 'dates',
    columns: c3Data.columns,
    type: 'bar',
    groups: [['itemA', 'itemB', 'itemC']], // 设置堆叠分组
    colors: {
      itemA: '#3366CC',
      itemB: '#DC3912',
      itemC: '#FF9900'
    },
    tooltip: {
      // 自定义tooltip,添加班次时间显示
      contents: function(d, defaultTitleFormat, defaultValueFormat, color) {
        const currentDate = d[0].x;
        const shiftTime = c3Data.shiftTimes[currentDate];
        let tooltipHtml = `<table class="c3-tooltip">
          <thead>
            <tr><th colspan="2">${currentDate}</th></tr>
            <tr><th colspan="2">班次时间:${shiftTime}</th></tr>
          </thead>
          <tbody>`;
        d.forEach(item => {
          tooltipHtml += `<tr>
            <td style="color:${color(item.id)}">${item.id}</td>
            <td class="value">${item.value}</td>
          </tr>`;
        });
        tooltipHtml += '</tbody></table>';
        return tooltipHtml;
      }
    }
  },
  axis: {
    x: {
      type: 'category',
      tick: {
        rotate: 45, // 旋转日期标签避免重叠
        multiline: false
      },
      label: {
        text: '日期',
        position: 'outer-center'
      }
    },
    y: {
      label: {
        text: '数量',
        position: 'outer-middle'
      }
    }
  },
  legend: {
    position: 'right' // 图例放在右侧
  },
  bar: {
    width: {
      ratio: 0.6 // 调整柱子宽度,让布局更宽松
    }
  }
});

三、关键配置说明

  • 堆叠效果:通过data.groups将三个物品设置为同一组,实现柱状堆叠
  • 自定义Tooltip:新增了班次时间的展示,让图表信息更完整
  • 样式优化:设置了柱子颜色、宽度,旋转x轴标签,让视觉效果更接近目标样式
  • 动态适配:自动转换函数支持后续新增数据,无需手动修改图表配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:11:31