Chart.js 教程:创建分组堆叠柱状图


Chart.js 教程:创建分组堆叠柱状图

本教程详细指导如何在 chart.js 中创建分组堆叠柱状图。我们将探讨如何将复杂的原始数据结构(包含设备、用户和积分)转换为 chart.js 所需的 `labels` 和 `datasets` 格式。重点在于数据预处理、动态生成数据集,以及配置 chart.js 的堆叠选项,以清晰展示多维度数据。

在数据可视化中,分组堆叠柱状图是一种强大的工具,能够在一个图表中同时展示多个类别的数据堆叠情况,并在不同的组之间进行比较。Chart.js 提供了灵活的配置选项来实现这种图表,但关键在于正确地准备数据结构。

1. 理解 Chart.js 对数据结构的要求

Chart.js 绘制柱状图时,通常需要以下两种核心数据:

  • labels: 对应图表的 X 轴标签,代表不同的分组(例如本例中的设备名称)。
  • datasets: 一个数组,每个元素代表图表中的一个数据集。对于堆叠柱状图,每个数据集通常代表堆叠中的一个组成部分(例如本例中的用户类别)。每个数据集对象包含:
    • label: 数据集的名称(例如用户 "amckinlay")。
    • data: 一个数组,其长度应与 labels 数组相同,每个值对应 labels 中相应位置的堆叠数值。
    • backgroundColor: 数据集的颜色。

原始数据结构分析

假设我们有以下原始数据 alldata,它包含设备名称和每个设备上不同用户的积分:

// 原始数据示例
const alldata = [
    {
        device: "Laptop",
        values: [
            { amckinlay: '30' },
            { cvu: '150' }
        ]
    },
    {
        device: "Phone",
        values: [
            { amckinlay: '100' }
        ]
    }
];
console.log(alldata);

这种结构对于 Chart.js 来说并不直接适用,因为 values 数组中的每个对象是一个键值对,难以直接提取 category(用户)和 value(积分)。为了更好地与 Chart.js 的 datasets 结构匹配,我们需要将数据转换为更扁平、更易于访问的形式。

2. 数据预处理与转换

为了满足 Chart.js 的要求,我们需要将原始数据 alldata 转换为适合 labels 和 datasets 的格式。

2.1 标准化数据结构

首先,我们将原始数据中的 values 数组扁平化,并为每个用户-设备-积分组合创建一个统一的对象结构。推荐的目标结构是 { device: "Laptop", category: "amckinlay", value: 30 }。

// 定义颜色配置,方便管理不同类别的颜色
const colorSettings = [
  {
    category: 'amckinlay',
    backgroundColor: 'rgba(75, 192, 192, 0.6)',
  },
  {
    category: 'cvu',
    backgroundColor: 'rgba(255, 99, 132, 0.6)',
  },
  // 可以添加更多类别及其颜色
];

// 将原始数据扁平化并标准化
let processedData = alldata
  .map((x) =>
    x.values.reduce((acc, cur) => {
      for (let k in cur) {
        acc.push({
          device: x.device,
          category: k,
          value: parseInt(cur[k]), // 确保值为数字类型
        });
      }
      return acc;
    }, [])
  )
  .flat();

console.log("标准化后的数据:", processedData);
/* 示例输出:
[
  { device: "Laptop", category: "amckinlay", value: 30 },
  { device: "Laptop", category: "cvu", value: 150 },
  { device: "Phone", category: "amckinlay", value: 100 }
]
*/

上述代码首先遍历 alldata 中的每个设备,然后遍历其 values 数组,将每个键值对转换为一个包含 device、category(用户)和 value(积分)的扁平对象。parseInt() 用于确保积分值是数字类型。

2.2 提取 X 轴标签

X 轴的标签将是所有不重复的设备名称。

芝士饼 芝士饼

芝士饼是一个一站式AI原生应用开发平台,简单几步即可完成应用的创建与发布。

芝士饼 84 查看详情 芝士饼
// 提取所有不重复的设备名称作为 X 轴标签
const labels = [...new Set(processedData.map((x) => x.device))];
console.log("X 轴标签:", labels); // 输出: ["Laptop", "Phone"]

2.3 构建 Chart.js 数据集

接下来,我们需要为 Chart.js 构建 datasets 数组。每个 category(用户)将对应一个 dataset 对象。

// 提取所有不重复的类别(用户)作为子标签
const subLabels = [...new Set(processedData.map((x) => x.category))];
console.log("子标签(数据集类别):", subLabels); // 输出: ["amckinlay", "cvu"]

// 构建 Chart.js 的 datasets 数组
const datasets = subLabels.reduce((acc, currentCategory) => {
  // 为当前类别创建一个数据集对象
  const dataset = {
    label: currentCategory,
    data: [],
    backgroundColor: colorSettings.find((c) => c.category === currentCategory)?.backgroundColor || 'rgba(0,0,0,0.5)', // 从颜色配置中获取颜色
  };

  // 遍历所有设备,为当前类别填充数据
  for (const device of labels) {
    // 查找当前设备和当前类别对应的值,如果没有则默认为 0
    const value = processedData.find(
      (x) => x.device === device && x.category === currentCategory
    )?.value ?? 0;
    dataset.data.push(value);
  }

  acc.push(dataset);
  return acc;
}, []);

console.log("Chart.js 数据集:", datasets);
/* 示例输出:
[
  {
    label: 'amckinlay',
    data: [30, 100], // Laptop: 30, Phone: 100
    backgroundColor: 'rgba(75, 192, 192, 0.6)'
  },
  {
    label: 'cvu',
    data: [150, 0], // Laptop: 150, Phone: 0 (因为Phone没有cvu的数据)
    backgroundColor: 'rgba(255, 99, 132, 0.6)'
  }
]
*/

这段代码首先获取所有唯一的 category 作为 subLabels。然后,它遍历每个 subLabel,为它创建一个 dataset 对象。在构建 dataset.data 数组时,它会遍历所有的 labels(设备),查找对应设备和类别的积分值。如果某个设备没有某个类别的积分数据,则 find 方法会返回 undefined,此时使用 ?? 0 将其填充为 0,确保 data 数组的长度与 labels 数组一致。

3. Chart.js 配置与渲染

数据准备就绪后,最后一步是配置 Chart.js 并将其渲染到页面上。关键在于设置 options 中的 stacked 属性。

<!DOCTYPE html>
<html>
<head>
    <title>Chart.js 分组堆叠柱状图</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        body { font-family: sans-serif; }
        .chart-container {
            width: 80%;
            margin: 50px auto;
        }
    </style>
</head>
<body>
    <div class="chart-container">
        <canvas id="myChart"></canvas>
    </div>

    <script>
        // ... (此处粘贴上面 2.1, 2.2, 2.3 节的所有 J*aScript 代码,包括 alldata, colorSettings, processedData, labels, subLabels, datasets 的定义) ...

        // Chart.js 渲染配置
        const ctx = document.getElementById('myChart').getContext('2d');
        const myChart = new Chart(ctx, {
            type: 'bar', // 图表类型为柱状图
            data: {
                labels: labels, // X 轴标签
                datasets: datasets, // 数据集
            },
            options: {
                responsive: true, // 启用响应式布局
                plugins: {
                    title: {
                        display: true,
                        text: '设备用户积分分布图'
                    }
                },
                scales: {
                    x: {
                        stacked: true, // X 轴启用堆叠
                        title: {
                            display: true,
                            text: '设备'
                        }
                    },
                    y: {
                        stacked: true, // Y 轴启用堆叠
                        title: {
                            display: true,
                            text: '积分'
                        }
                    },
                },
            },
        });
    </script>
</body>
</html>

在 options 配置中:

  • scales.x.stacked: true 确保 X 轴上的每个分组(设备)内部的柱子是堆叠的。
  • scales.y.stacked: true 确保 Y 轴上的数值是累加的,对应堆叠效果。
  • responsive: true 让图表在容器大小变化时自动调整。

4. 注意事项

  • 数据类型一致性: 确保 data 数组中的值都是数字类型。原始数据中的 '30' 等字符串需要通过 parseInt() 或 parseFloat() 转换为数字。
  • 颜色管理: 建议将颜色配置集中管理(如 colorSettings 数组),这样可以方便地为不同的类别分配颜色,提高代码的可维护性和一致性。
  • 缺失数据处理: 当某个设备没有某个类别的堆叠数据时,应在 dataset.data 中填充 0,而不是省略,以保证 data 数组的长度与 labels 数组一致,避免图表渲染错误。
  • 性能优化: 对于非常大的数据集,数据预处理可能需要优化,例如使用更高效的查找算法或考虑在后端进行部分数据转换。

5. 总结

创建 Chart.js 分组堆叠柱状图的关键在于数据预处理。通过将复杂的原始数据结构转换为 Chart.js 所需的 labels 和 datasets 格式,我们能够灵活地展示多维度数据。核心步骤包括:

  1. 标准化原始数据: 将嵌套的、键值对形式的数据扁平化为统一的对象结构。
  2. 提取 X 轴标签: 从标准化数据中获取所有唯一的设备名称。
  3. 动态构建数据集: 遍历所有唯一的类别(用户),为每个类别创建一个 dataset 对象,并填充对应设备的数据。
  4. 配置 Chart.js 选项: 在 options.scales 中设置 x.stacked: true 和 y.stacked: true 以启用堆叠功能。

遵循这些步骤,您就可以在 Chart.js 中创建出清晰、信息丰富的分组堆叠柱状图。

以上就是Chart.js 教程:创建分组堆叠柱状图的详细内容,更多请关注其它相关文章!


# 大庆seo优化案例  # 原始数据  # 键值  # 芝士  # 创建一个  # 多维  # 是一个  # 关键词排名考察易速达  # 网站建设静态代码  # 转换为  # 营口市网站建设  # 网站seo优化的方案  # 长安网站建设找哪家  # 河南别墅图纸网站建设  # 哪个网站能做推广赚钱  # 网站推广--html关键词代码解说  # 口碑营销首选乐云seo  # javascript  # 柱状图  # 遍历  # 数据结构  # 键值对  # 响应式布局  # 数据可视化  # cdn  # ai  # 后端  # 工具  # npm  # go  # js  # html  # java 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894 】


相关推荐: 抖音火山版注销账号抖音会注销吗 抖音火山版与抖音账号注销关系  mysql怎么导入sql文件_mysql导入sql文件的方法与技巧  Chart.js 教程:自定义插件实现图表与图例间距调整  Win10通知横幅停留时间修改 Win10自定义通知显示时长【技巧】  Python实战:高效处理实时数据流中的最小/最大值  《友玩*》创建群聊方法  花生壳内网映射新方案  《红果免费短剧》下载观看方法  《下一站江湖2》武器获取方法  Highcharts雷达图轴线交点数值标注指南  Yandex无需登录畅游 俄罗斯搜索引擎最新官网指南  键盘保修需要什么_键盘售后维修流程  《广发易淘金》国债逆回购操作教程  被称为海蜈蚣的海洋动物是  《桃源记2》资源采集攻略  J*aScript二进制处理_ArrayBuffer与Blob  《狐友》联系客服方法  mysql如何限制远程访问_mysql远程访问限制方法  如何在mysql中比较InnoDB和MyISAM区别  C++ switch case字符串_C++如何实现字符串switch匹配  抖音视频如何添加标题?添加标题有哪些好处?  C++ bind函数使用教程_C++参数绑定与函数适配器的应用  青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法  Go语言反射机制:如何访问被嵌入结构体遮蔽的方法  CSS绝对定位与溢出控制:实现背景元素局部显示不触发滚动条  Coolpad5890 ROM刷机包  怎样让Windows 11的开始菜单恢复经典样式_Open-Shell工具使用指南【怀旧】  如何在CSS中使用伪类选择器_hover实现悬停效果  如何使用 composer 和 aop-php 实现 AOP 编程?  yy漫画官方网站登录入口_yy漫画在线阅读页面地址  《全民k歌》网页版最新登录入口一览  PHP中实现JSON数据数组分页的教程  使用AI在VS Code中将代码从一种语言翻译成另一种  TikTok网页版入口快速访问 TikTok官网账号登录方法  192.168.1.1路由器后台入口 192.168.1.1默认登录入口  Animex动漫社正版在线入口 Animex动漫社动漫官方观看网  快手极速版在线体验区 快手极速版网页体验入口  Cassandra中复合主键、二级索引与ORDER BY排序的限制与解决方案  CSS过渡如何实现按钮悬停效果_transition属性控制背景颜色变化  电脑从睡眠中被自动唤醒怎么办_Windows唤醒源事件查看与禁用【解决】  解决PHP MySQL数据库更新无响应:SQL查询语法错误解析  Flexbox布局实践:实现底部页脚与顶部粘性导航条的完美结合  以下哪一个是适应长期护理制度发展而设立的新职业  豆包AI怎样为教育场景定制答疑逻辑_为教育场景定制豆包AI答疑逻辑方案【方案】  使用逻辑应用(Logic Apps)自动处理邮件附件中的XML到Excel  更换小红书群背景怎么换?小红书群规则怎么设置?  小米倒班助手添加日历提醒  Word如何将文字快速转成表格 Word文本转换成表格功能使用技巧【效率】  vivo云服务一直提示空间不足怎么办 怎么办vivo云服务老是提示空间不足  c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化 

 2025-11-06

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.