Chart.js 教程:创建分组堆叠条形图


Chart.js 教程:创建分组堆叠条形图

本教程详细介绍了如何使用 chart.js 创建分组堆叠条形图,以可视化复杂的多维度数据。核心内容包括对原始嵌套数据的结构化转换,将其适配 chart.js 所需的 `labels` 和 `datasets` 格式,以及配置图表的堆叠选项。通过具体的代码示例,用户将学习如何将设备、用户和积分数据有效地呈现在一个清晰、专业的图表中。

理解 Chart.js 堆叠条形图的数据结构要求

在 Chart.js 中创建堆叠条形图,需要遵循特定的数据结构。通常,图表的 data 对象包含两个主要部分:

  • labels: 定义图表X轴的分类标签。对于分组堆叠图,这些通常是主分类(例如,设备名称)。
  • datasets: 一个数组,每个元素代表图表中的一个数据集。在堆叠条形图中,每个 dataset 对象通常代表一个堆叠层(例如,特定用户的数据),它包含:
    • label: 该数据集的名称(例如,用户名)。
    • data: 一个数组,其中每个值对应 labels 中相应位置的数据点。
    • backgroundColor: 该数据集的背景颜色。

对于本教程中的场景,我们需要在X轴上展示设备名称,并在每个设备对应的条形图中,堆叠显示不同用户的积分。这意味着每个用户将对应一个 dataset,而每个 dataset 的 data 数组将包含该用户在不同设备上的积分。

原始数据结构分析与挑战

我们原始的数据结构如下所示,其中包含设备名称和每个设备下用户及其对应积分的嵌套数组:

[
    {
        device: "Laptop",
        values: [
            {amckinlay: '30'},
            {cvu: '150'}
        ]
    },
    {
        device: "Phone",
        values: [
            {amckinlay: '100'}
        ]
    }
]

这种结构对 Chart.js 而言存在挑战:

  1. values 数组中的每个对象都以动态的键(用户名)存储数据,这使得直接提取 label 和 data 变得复杂。
  2. Chart.js 需要每个 dataset 的 data 数组与 labels 数组的长度匹配,且每个位置的数据点对应 labels 中的一个分类。

为了解决这些问题,我们需要对数据进行预处理和转换。

数据预处理与转换

数据转换的目标是将原始的嵌套结构扁平化为更易于处理的格式,例如:

[
    { device: "Laptop", category: "amckinlay", value: 30 },
    { device: "Laptop", category: "cvu", value: 150 },
    { device: "Phone", category: "amckinlay", value: 100 }
]

这种扁平化结构将每个设备、用户和积分的组合作为一个独立的对象,方便后续构建 Chart.js 的 datasets。

以下是实现数据转换的 J*aScript 代码:

LALAL.AI LALAL.AI

AI人声去除器和声乐提取工具

LALAL.AI 196 查看详情 LALAL.AI
// 假设 alldata 是从原始数据源获取的数组
var alldata = [
    {
        device: "Laptop",
        values: [
            {amckinlay: '30'},
            {cvu: '150'}
        ]
    },
    {
        device: "Phone",
        values: [
            {amckinlay: '100'}
        ]
    }
];

// 定义颜色设置,为每个用户(category)指定背景色
var colorSettings = [
  {
    category: 'amckinlay',
    backgroundColor: 'rgba(75, 192, 192, 0.6)',
  },
  {
    category: 'cvu',
    backgroundColor: 'rgba(255, 99, 132, 0.6)',
  },
];

// 1. 提取X轴标签(设备名称)
var labels = alldata.map((x) => x.device);

// 2. 扁平化数据结构
// 将原始数据转换为 { device, category, value } 的扁平数组
alldata = alldata
  .map((x) =>
    x.values.reduce((acc, cur) => {
      for (let k in cur) {
        acc.push({
          device: x.device,
          category: k,
          value: parseInt(cur[k], 10), // 确保值是数字
        });
      }
      return acc;
    }, [])
  )
  .flat();

// 3. 提取所有唯一的类别(用户名称),这将成为每个数据集的标签
var subLabels = [...new Set(alldata.map((x) => x.category))];

// 4. 构建 Chart.js 的 datasets 数组
var datasets = subLabels.reduce((acc, curCategory) => {
  // 对于每个类别(用户),构建一个数据集
  let dataset = {
    label: curCategory,
    data: [],
    backgroundColor: colorSettings.find((x) => x.category === curCategory)?.backgroundColor || 'rgba(0, 0, 0, 0.2)', // 查找对应颜色,没有则使用默认
  };

  // 遍历所有设备,为当前类别填充数据
  for (let device of labels) {
    const value = alldata.find(
      (x) => x.device === device && x.category === curCategory
    )?.value ?? 0; // 如果没有找到对应数据,则默认为0
    dataset.data.push(value);
  }
  acc.push(dataset);
  return acc;
}, []);

// 最终的 labels 和 datasets 结构将如下:
// labels: ["Laptop", "Phone"]
// datasets: [
//   { label: "amckinlay", data: [30, 100], backgroundColor: "..." },
//   { label: "cvu", data: [150, 0], backgroundColor: "..." }
// ]

代码解释:

  • colorSettings: 预定义了每个用户类别的颜色,这使得图表颜色管理更加灵活和可维护。
  • labels: 使用 map 方法从原始数据中直接提取所有设备名称作为X轴标签。
  • 扁平化 alldata:
    • 外层的 map 遍历每个设备。
    • 内层的 reduce 遍历 values 数组,将 {"user": "points"} 形式的对象转换为 {"device": "...", "category": "user", "value": points}。
    • flat() 方法将多层嵌套的数组扁平化为一层。
  • subLabels: 使用 Set 结合 map 提取所有不重复的用户名称,这些将作为每个堆叠部分的标签。
  • 构建 datasets:
    • 使用 reduce 遍历 subLabels(即每个用户)。
    • 为每个用户创建一个 dataset 对象,包括 label (用户名) 和 backgroundColor。
    • 在内部循环中,遍历所有的 labels (设备),查找当前用户在每个设备上的积分。如果找不到,则默认为 0,确保 data 数组的长度与 labels 数组匹配。

Chart.js 配置与渲染

数据准备就绪后,接下来是配置 Chart.js 以渲染堆叠条形图。关键在于在 options 中设置 scales 的 stacked 属性为 true。

// 获取 Canvas 元素
const ctx = document.getElementById('myChart').getContext('2d');

// 初始化 Chart.js
const myChart = new Chart(ctx, {
  type: 'bar', // 图表类型为条形图
  data: {
    labels: labels,     // 使用前面生成的设备标签
    datasets: datasets, // 使用前面生成的堆叠数据集
  },
  options: {
    responsive: true, // 使图表响应式
    scales: {
      x: {
        stacked: true, // X轴(类别轴)启用堆叠
      },
      y: {
        stacked: true, // Y轴(值轴)启用堆叠
      },
    },
    plugins: {
        tooltip: {
            mode: 'index', // 鼠标悬停时显示所有堆叠层的数据
            intersect: false,
        }
    }
  },
});

关键配置解释:

  • type: 'bar': 指定图表类型为条形图。
  • data: { labels, datasets }: 绑定我们预处理好的 labels 和 datasets。
  • options.scales.x.stacked: true: 告诉 Chart.js X轴上的条形图应该堆叠显示。
  • options.scales.y.stacked: true: 告诉 Chart.js Y轴上的值也应该堆叠计算。这两个设置共同实现了堆叠条形图的效果。
  • plugins.tooltip: 可选配置,用于优化工具提示的显示,mode: 'index' 和 intersect: false 使得鼠标悬停在一个条形图上时,会显示该条形图所有堆叠层的数据。

总结与注意事项

创建 Chart.js 分组堆叠条形图的关键在于数据预处理。原始数据结构往往不直接符合 Chart.js 的要求,尤其是当数据包含多层嵌套或动态键时。通过将数据扁平化并重构为 labels 和 datasets 的标准格式,可以极大地简化 Chart.js 的配置过程。

注意事项:

  • 数据类型一致性: 确保 data 数组中的所有值都是数字类型,否则 Chart.js 可能无法正确渲染或计算。在数据转换时,我们使用了 parseInt(cur[k], 10) 来确保这一点。
  • 数据完整性: 如果某个用户在某个设备上没有数据,确保在构建 datasets 时将其值设置为 0 (或 null,具体取决于你希望 Chart.js 如何处理缺失值),以保持 data 数组与 labels 数组长度的一致性。
  • 颜色管理: 对于多个堆叠层,为每个层指定清晰且区分度高的颜色非常重要,可以通过预定义的 colorSettings 对象来实现。
  • 响应式设计: 在 options 中设置 responsive: true 可以使图表更好地适应不同屏幕尺寸。

通过遵循本教程中的数据转换和配置步骤,您可以有效地利用 Chart.js 创建出专业且易于理解的分组堆叠条形图,从而更好地展示复杂的数据关系。

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


# java  # 枣庄律师网站推广公司  # seo干些什么  # 康佳网站优化专员实训表  # 合川网站推广方案  # 关键在于  # 转换为  # 有效地  # 重构  # 鼠标  # 有什么  # 遍历  # javascript  # js  # go  # 工具  # 响应式设计  # canva  # red  # 数据结构  # 条形图  # 扁平化  # 杭州seo俱乐部seo顾问  # 跨界营销推广表现形式  # 网站建设教程有哪些模块  # 东昌网站建设  # 广德seo网站优化  # 安阳网络营销推广策划 


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


相关推荐: 实现二叉树的层序插入:基于树大小的路径导航  RxJS中如何高效地在一个函数内处理和合并多个数据集合  Linux如何开发轻量级数据服务模块_Linux服务化设计  《饿了么》拼好饭点外卖教程2025  第五人格PC版怎么避免被封号_第五人格PC版防封号注意事项  tiktok国际版入口_tiktok官网网页版链接  Google Drive API服务器端访问指南:服务账户认证详解  外卖小程序对接第三方配送  Golang如何操作指针参数_Go pointer参数传递规则  秋风萧瑟洪波涌起中的萧瑟指的是什么  使用AI在VS Code中将代码从一种语言翻译成另一种  win11怎么启用或禁用休眠 Win11 powercfg命令管理休眠文件【技巧】  青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法  192.168.1.1路由器后台入口 192.168.1.1默认登录入口  vivo云服务一直提示空间不足怎么办 怎么办vivo云服务老是提示空间不足  在Django单元测试中优雅处理信号:基于环境的条件执行策略  J*a中导出MySQL表为SQL脚本的两种方法  利用Flexbox实现图片元素的二维布局:2x2网格排列指南  PHP动态导航按钮:根据用户登录状态切换链接与文本  如何在CSS中使用过渡制作按钮边框渐变_border-color transition实现  从HTML表单获取逗号分隔值并转换为NumPy数组进行预测  FotoBalloon图片左右镜像教程  mysql触发器如何编写_mysql触发器编写规范与代码示例讲解  《雷电模拟器》截图方法介绍  Excel如何快速合并单元格内容_Excel文本合并与函数操作技巧  网易云音乐闹钟铃声设置教程  汽水音乐在线入口 汽水音乐网页端官方页面快速打开  铁路12306座位怎么选_12306官方选座操作方法  windows10怎么关闭自动安装应用_windows10禁止推广应用下载  Animex动漫社正版在线入口 Animex动漫社动漫官方观看网  《蓝色星原:旅谣》坐骑获取攻略  支付宝如何解绑云闪付_支付宝与云闪付账户关联解除方法  《豆瓣》私信用户方法  《荔枝fm》导出文件教程  《磁力猫》最好用的磁官网  搜狗浏览器如何查找页面中的文字 搜狗浏览器Ctrl+F页面搜索功能  Yandex浏览器官方入口_Yandex搜索引擎中文版  申通快递物流信息查询 申通快递包裹状态追踪  邮编号码查询app有哪些_邮编号码查询推荐app及使用体验  我的世界官方网址入口 我的世界游戏主页直达入口  《书耽》更换手机号方法  处理含命名空间的XML文件 Power Query中的高级技巧  手机坏了微信聊天记录怎么导出来 新手机恢复聊天记录技巧  苹果自助维修计划支持哪些设备机型  Golang如何使用gRPC拦截器实现日志收集_Golang gRPC拦截器日志收集实践  《我的恋爱逃生攻略》中文名字输入方法  Python测试中模块导入路径解析的最佳实践  Win11便笺在哪打开 Win11桌面便笺(Sticky Notes)使用方法【详解】  windows10怎么开启卓越性能_windows10电源选项代码激活  纯CSS实现滚动时动态时间轴线条颜色填充效果 

 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.