使用 Chart.js 构建目标完成度堆叠柱状图

使用 Chart.js 构建目标完成度堆叠柱状图

本文将指导您如何利用 Chart.js 创建一种特殊的堆叠柱状图,以直观地展示任务或指标的当前进度及其距离预设目标(例如60)的差距。通过动态计算所需剩余量并将其作为独立的堆叠部分呈现,当目标达成或超越时,表示差距的红色柱状部分将自动消失,从而提供清晰的目标达成度可视化。

数据可视化中,展示一个值距离某个目标还有多远是一种常见的需求。传统的柱状图可能只显示当前值,但如果能同时在一个柱状图中直观地看到“已完成”和“还需完成”两部分,将大大提升图表的信息传达效率。本教程将详细介绍如何使用强大的 chart.js 库来实现这种带有目标完成度指示的堆叠柱状图。

核心概念:目标达成度可视化

我们的目标是创建一个堆叠柱状图,其中:

已完成量:代表当前的已完成进度,例如使用蓝色柱体。距离目标量:代表距离预设目标还需完成的量,例如使用红色柱体。智能隐藏:当当前完成量达到或超过目标时,表示“距离目标量”的红色柱体应自动消失,只显示已完成的蓝色柱体。

例如,假设我们的目标是 60。如果当前值是 40,图表应显示 40 的蓝色部分和 20 的红色部分。如果当前值是 60 或 70,则只显示 60 或 70 的蓝色部分,不显示红色部分。

Chart.js 基础设置回顾

在深入实现之前,我们先回顾一个基本的 Chart.js 柱状图结构。通常,我们需要一个 canvas> 元素作为图表的容器,并通过 JavaScript 初始化 Chart 实例,传入数据和配置。

(function() {  const ctx = document.getElementById("mychart");  const datas = {    labels: ['通过', '失败', '进行中'],    datasets: [{      label: '数据',      data: [10, 5, 80],      backgroundColor: [        "green",        "red",        "yellow"      ],    }, ]  };  const chr = new Chart(ctx, {    data: datas,    type: 'bar'  });})();

上述代码展示了一个简单的柱状图,但它并未实现我们所需的目标完成度可视化功能。

实现目标堆叠柱状图

要实现目标完成度堆叠柱状图,关键在于数据预处理。我们需要在将数据传递给 Chart.js 之前,计算出每个数据点距离目标的剩余量,并将其作为一个独立的 dataset 添加到图表中。

数据处理逻辑

假设我们的目标值是 60。对于原始数据集中的每个数据点 currentValue:

如果 currentValue 大于或等于 60(目标已达成或超越),那么剩余量为 0。如果 currentValue 小于 60(目标尚未达成),那么剩余量为 60 – currentValue。

这个计算可以通过 Array.prototype.map() 方法高效完成。

const targetValue = 60; // 定义目标值const originalData = datas.datasets[0].data; // 获取原始数据const remainingData = originalData.map(currentValue => {  return currentValue >= targetValue ? 0 : targetValue - currentValue;});

构建新的数据集

计算出 remainingData 后,我们需要将其作为一个新的 dataset 添加到 datas.datasets 数组中。这个新的数据集将代表“距离目标量”的部分,并应使用一个醒目的颜色,例如红色。

datas.datasets.push({  label: '距离目标', // 新数据集的标签  backgroundColor: 'red', // 剩余量的颜色  data: remainingData // 剩余量数据});

Chart.js 在处理多个 type: ‘bar’ 的 dataset 时,默认会将其堆叠起来,除非显式设置 options.scales.x.stacked: false 或 options.scales.y.stacked: false。这正是我们想要的效果。

完整代码示例

将上述逻辑整合到 Chart.js 的初始化代码中:

  Chart.js 目标完成度堆叠柱状图        body { font-family: sans-serif; margin: 0; padding: 20px; background-color: #f4f7f6; }    .chart-container {      width: 80%; /* 调整图表容器宽度 */      max-width: 800px; /* 最大宽度限制 */      height: 400px; /* 调整图表容器高度 */      margin: 20px auto;      background-color: #ffffff;      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0,0,0,0.1);      padding: 20px;      box-sizing: border-box;    }    h1 { text-align: center; color: #333; margin-bottom: 30px; }    

Chart.js 目标完成度堆叠柱状图示例

(function() { const ctx = document.getElementById("mychart"); const targetValue = 60; // 定义目标值 const datas = { labels: ['任务A', '任务B', '任务C', '任务D', '任务E'], datasets: [{ label: '当前进度', data: [10, 65, 40, 60, 25], // 示例数据:任务B已超目标,任务D刚好达到目标 backgroundColor: [ "rgba(54, 162, 235, 0.8)", // 蓝色 "rgba(54, 162, 235, 0.8)", "rgba(54, 162, 235, 0.8)", "rgba(54, 162, 235, 0.8)", "rgba(54, 162, 235, 0.8)" ], }] }; // 计算距离目标的剩余量 const remainingData = datas.datasets[0].data.map(currentValue => { return currentValue >= targetValue ? 0 : targetValue - currentValue; }); // 添加表示剩余量的新数据集 datas.datasets.push({ label: '距离目标', backgroundColor: 'rgba(255, 99, 132, 0.8)', // 红色 data: remainingData }); const chr = new Chart(ctx, { data: datas, type: 'bar', options: { responsive: true, maintainAspectRatio: false, plugins: { title: { display: true, text: '任务进度与目标达成度', font: { size: 18, weight: 'bold' }, color: '#333' }, legend: { position: 'top', labels: { font: { size: 14 } } }, tooltip: { callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) { label += ': '; } if (context.dataset.label === '当前进度') { label += context.raw; } else { // 距离目标 if (context.raw > 0) { label += context.raw; } else { label += '目标已达成'; } } return label; } } } }, scales: { x: { stacked: true, // 确保X轴堆叠 title: { display: true, text: '任务', font: { size: 16 }, color: '#555' }, ticks: { font: { size: 12 } } }, y: { stacked: true, // 确保Y轴堆叠 beginAtZero: true, // 动态设置Y轴最大值,确保目标值可见且图表不过高 max: Math.max(targetValue, ...datas.datasets[0].data) + 10, title: { display: true, text: '进度值', font: { size: 16 }, color: '#555' }, ticks: { font: { size: 12 }

以上就是使用 Chart.js 构建目标完成度堆叠柱状图的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1580708.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月22日 21:41:43
下一篇 2025年12月22日 21:41:58

相关推荐

  • HTML表格鼠标悬停行高亮的CSS格式实现和交互效果

    使用CSS :hover伪类可实现表格行高亮,通过#data-table tbody tr:hover设置背景色和手型光标,并添加transition实现平滑过渡,提升数据浏览体验。 要实现HTML表格中鼠标悬停时整行高亮的效果,可以通过CSS的 :hover 伪类来完成。这种方式无需JavaScr…

    2025年12月22日
    000
  • 利用CSS text-shadow 实现按钮点击即时、释放缓动过渡效果

    本文将探讨如何利用CSS实现按钮在点击(:active)时颜色即时变化,而在释放(:hover或默认状态)时则呈现平滑过渡效果。通过巧妙地结合text-shadow属性管理文本颜色过渡,并配合color属性处理激活状态,我们可以精确控制按钮在不同交互状态下的视觉反馈,从而提升用户体验。 在网页交互设…

    2025年12月22日
    000
  • JavaScript 无法从新打开的 HTML 页面中读取元素的问题解决

    本文针对 JavaScript 无法从通过 window.open() 打开的新 HTML 页面中读取元素的问题,提供了详细的解决方案。核心在于理解同源策略以及 DOM 加载时机。针对同源情况,需要确保在新窗口的 DOM 加载完成后再进行元素访问。对于非同源情况,由于安全限制,直接访问 DOM 是不…

    2025年12月22日
    000
  • PHP中实现表单数据追加到现有文件:避免覆盖与最佳实践

    本教程详细讲解如何在PHP中通过表单提交将数据追加到现有文件,而非覆盖。核心在于利用 file_put_contents 函数的 FILE_APPEND 模式,并智能管理 php 标签以确保文件格式正确。文章将提供代码示例,并探讨这种数据存储方式的局限性及更专业的替代方案,以帮助开发者实现持久化数据…

    2025年12月22日
    000
  • 创建响应式表单输入框和按钮:优化你的网站用户体验

    本文将帮助开发者解决在网页设计中遇到的响应式布局问题,特别是针对表单中的输入框和按钮在不同屏幕尺寸下的适配问题。我们将通过分析HTML结构和CSS样式,提供一种简单有效的解决方案,确保你的网站在各种设备上都能提供良好的用户体验。重点在于使用媒体查询来调整元素在不同屏幕尺寸下的显示方式,从而实现真正的…

    2025年12月22日
    000
  • ASP.NET MVC中基于模型值动态改变HTML元素背景色

    本教程详细阐述了在ASP.NET MVC(VB.NET Razor视图)中,如何根据模型(Model)中的用户类型(UserType)动态地改变HTML 元素的背景颜色。通过在Razor视图中使用内联样式结合IIf条件表达式,可以直接覆盖或补充现有CSS样式,实现不同用户或条件下的个性化UI展示。文…

    2025年12月22日
    000
  • HTML代码怎么实现版本回滚_HTML代码版本回滚方法与历史记录管理技巧

    HTML代码版本回滚依赖外部工具,核心是通过Git等版本控制系统实现。首先将HTML文件纳入Git管理,每次修改提交并记录信息;使用git revert或git reset可回滚到指定版本,git checkout可恢复单个文件;团队协作需推送至远程仓库,配合CI/CD可自动化备份与回滚;此外,ID…

    2025年12月22日 好文分享
    000
  • 限制双滑块范围:防止最小值超过最大值

    本文档旨在提供一种使用 JavaScript 实现双滑块范围限制的方法,以防止用户在调整滑块时出现最小值超过最大值,或最大值低于最小值的情况。通过监听滑块的 input 事件,并动态调整另一个滑块的值,确保范围的有效性。本文将提供详细的代码示例和解释,帮助开发者轻松实现这一功能。 实现原理 核心思路…

    2025年12月22日
    000
  • 使用 Video.js 在响应式模式下向 ControlBar 添加自定义按钮

    本文将指导您如何在 Video.js 视频播放器的控制栏中添加自定义按钮,并确保这些按钮在各种设备上都能正常工作,尤其是在响应式模式下。正如摘要所述,关键在于使用 clickHandler 选项,它能同时响应鼠标点击和触摸事件,从而保证按钮在移动设备上的可交互性。 添加自定义按钮 Video.js …

    2025年12月22日
    000
  • Knockout.js ViewModel中引用未定义属性的解决方案

    本文旨在解决Knockout.js ViewModel内部初始化时,因属性相互引用顺序导致Cannot read properties of undefined的常见错误。核心解决方案在于将相互依赖的Observable变量提升到ViewModel外部进行定义,从而确保在ViewModel属性初始化…

    2025年12月22日
    000
  • WordPress多级下拉菜单样式定制指南

    本文详细介绍了如何在WordPress中实现多级下拉菜单的样式定制。通过分析WordPress默认菜单输出的结构,我们发现其所有子菜单都统一使用sub-menu类。针对这一挑战,本教程提供了一套纯CSS解决方案,利用层级选择器精确控制不同级别子菜单的样式、定位和显示逻辑,无需修改WordPress核…

    2025年12月22日
    000
  • 使用单个按钮提交多个表单:Flask 后端数据处理指南

    本文档旨在解决使用单个按钮提交多个 HTML 表单时,Flask后端如何正确接收和处理所有表单数据的问题。通过JavaScript异步提交表单数据,并在Flask后端利用request.form访问这些数据,本文将提供一个清晰的实现方案,并附带代码示例,帮助开发者理解和应用该技术。 问题描述 在We…

    2025年12月22日
    000
  • 解决 ASP.NET 中的 HTTP 414 请求 URL 过长错误

    本文旨在帮助开发者解决 ASP.NET 应用中遇到的 “HTTP Error 414. The request URL is too long.” 错误。通过分析错误原因,我们将探讨如何通过将 GET 请求转换为 POST 请求来有效规避 URL 长度限制,并提供相关注意事项…

    2025年12月22日
    000
  • 在.NET Razor视图中根据模型值动态设置HTML元素背景色

    本教程介绍如何在.NET Razor视图中,利用模型数据(如用户类型)动态地为HTML元素(例如导航栏的)设置背景颜色。通过在HTML标签内直接应用内联样式,并结合Razor的条件表达式,可以轻松实现基于不同条件展示差异化视觉效果,同时兼顾现有CSS样式。 核心概念与场景分析 在web应用开发中,根…

    2025年12月22日
    000
  • 通过ID选择器定制Angular ng-select组件样式

    本教程详细阐述了如何在Angular应用中,利用CSS的ID选择器精确地定位并修改特定ng-select组件的样式。文章将通过具体的HTML和CSS代码示例,指导读者如何调整ng-select的宽度、边框、高度等外观属性,并探讨了CSS特异性、组件样式封装等相关注意事项,旨在帮助开发者实现精细化的组…

    2025年12月22日
    000
  • CSS按钮高级过渡:实现点击即时、释放平滑的交互效果

    本教程探讨如何为CSS按钮实现不同的过渡效果,即点击时颜色即时变化,而释放时颜色平滑过渡。通过巧妙利用text-shadow属性来控制默认和悬停状态的文本颜色,并结合color属性在:active状态下即时覆盖,我们能够精确控制按钮在不同交互阶段的视觉反馈,从而提升用户体验。 1. 按钮交互过渡的挑…

    2025年12月22日
    000
  • Python字典内容转换为字符串的实用指南

    本文详细阐述了在Python中,特别是进行Web抓取时,如何有效地将字典数据转换为字符串。教程涵盖了将BeautifulSoup标签列表转换为可读文本、构建结构化的字典,以及最终利用str()或json.dumps()方法将整个字典序列化为字符串,旨在提供清晰、实用的数据处理方案。 理解字典到字符串…

    2025年12月22日
    000
  • WordPress 多级下拉菜单样式定制指南

    本文详细介绍了如何在 WordPress 中为多级下拉菜单实现自定义样式。针对 wp_nav_menu 默认输出所有子菜单为 sub-menu 类名的问题,教程演示了如何通过巧妙运用 CSS 层级选择器 (ul ul, ul ul li ul) 精准定位并美化不同深度的子菜单,从而打破类名限制,实现…

    2025年12月22日
    000
  • JavaScript 无法从 HTML 中读取 Div 元素的解决方案

    本文旨在解决 JavaScript 无法从新打开的 HTML 页面中读取 Div 元素的问题。通常,这个问题源于 DOM 未加载完成或跨域访问限制。文章将提供相应的解决方案,包括使用 DOMContentLoaded 事件确保 DOM 加载完成,以及解释跨域访问限制及其影响。 在 JavaScrip…

    2025年12月22日
    000
  • CSS按钮状态过渡精细控制:点击瞬时,释放缓变

    本文旨在解决CSS按钮在点击(active)状态和释放/悬停(hover)状态下,实现不同过渡效果的挑战。通过巧妙运用text-shadow属性模拟文本颜色,并结合color属性在active状态下的瞬时改变,我们能够实现按钮点击时颜色即刻变化,而释放或悬停时则平滑过渡的专业用户体验。 按钮状态过渡…

    2025年12月22日
    000

发表回复

登录后才能评论
关注微信