导读:本期聚焦于小伙伴创作的《JavaScript实现堆叠式进度条图表的详细教程与完整代码》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript实现堆叠式进度条图表的详细教程与完整代码》有用,将其分享出去将是对创作者最好的鼓励。

如何使用 JavaScript 创建堆叠式进度条图表

堆叠式进度条图表是数据可视化中常用的展示形式,它能够在一组进度条中同时展示多个维度的数据占比,直观呈现各部分在整体中的分布关系。相比单一进度条,堆叠式进度条可以在有限的空间内展示更多维度的信息,非常适合多分类数据的占比对比场景,比如不同产品的销售占比、项目各阶段进度占比等。

核心实现思路

要纯 JavaScript 实现堆叠式进度条,核心逻辑可以分为以下几个步骤:

  • 准备数据:定义每个进度条的总长度,以及每个堆叠部分的数值和对应的颜色
  • 创建容器:动态生成进度条的外层容器和内部堆叠块的元素
  • 计算占比:根据每个部分的数值计算其在总进度中的宽度占比
  • 渲染样式:为每个堆叠块设置宽度、背景色,完成进度条的绘制
  • 添加交互:可选实现鼠标悬停显示数值提示的功能

完整实现代码

下面的代码实现了一个可复用的堆叠式进度条图表,支持自定义数据和样式,代码中包含详细注释说明每一步的作用:

// 堆叠式进度条数据示例,每个对象代表一个独立的进度条
const stackProgressData = [
  {
    name: "产品A销售进度",
    total: 100, // 总进度值
    stacks: [
      { value: 30, color: "#4CAF50", label: "线上渠道" },
      { value: 25, color: "#2196F3", label: "线下渠道" },
      { value: 20, color: "#FFC107", label: "分销渠道" },
      { value: 25, color: "#9C27B0", label: "其他渠道" }
    ]
  },
  {
    name: "项目B完成进度",
    total: 100,
    stacks: [
      { value: 40, color: "#4CAF50", label: "需求阶段" },
      { value: 30, color: "#2196F3", label: "开发阶段" },
      { value: 20, color: "#FFC107", label: "测试阶段" },
      { value: 10, color: "#9C27B0", label: "上线阶段" }
    ]
  }
];

// 创建堆叠式进度条图表的主函数
function createStackProgressChart(containerId, data) {
  // 获取图表容器
  const container = document.getElementById(containerId);
  if (!container) {
    console.error("未找到指定的容器元素");
    return;
  }
  // 清空容器原有内容
  container.innerHTML = "";

  // 遍历每个进度条数据
  data.forEach(item => {
    // 创建单个进度条的容器
    const progressItem = document.createElement("div");
    progressItem.style.marginBottom = "20px";

    // 创建进度条标题
    const title = document.createElement("div");
    title.textContent = item.name;
    title.style.marginBottom = "8px";
    title.style.fontSize = "14px";
    title.style.color = "#333";
    progressItem.appendChild(title);

    // 创建进度条外层轨道
    const progressTrack = document.createElement("div");
    progressTrack.style.width = "100%";
    progressTrack.style.height = "24px";
    progressTrack.style.backgroundColor = "#f0f0f0";
    progressTrack.style.borderRadius = "4px";
    progressTrack.style.overflow = "hidden";
    progressTrack.style.display = "flex";

    // 遍历堆叠块数据,计算宽度并创建元素
    item.stacks.forEach(stack => {
      const stackBlock = document.createElement("div");
      // 计算当前块占总进度的百分比
      const percent = (stack.value / item.total) * 100;
      stackBlock.style.width = `${percent}%`;
      stackBlock.style.backgroundColor = stack.color;
      stackBlock.style.height = "100%";
      stackBlock.style.transition = "width 0.3s ease";
      // 存储当前块的提示信息,用于鼠标悬停展示
      stackBlock.dataset.label = stack.label;
      stackBlock.dataset.value = stack.value;
      stackBlock.dataset.percent = percent.toFixed(1);

      // 添加鼠标悬停提示事件
      stackBlock.addEventListener("mouseenter", function(e) {
        // 创建提示框
        let tooltip = document.getElementById("stack-tooltip");
        if (!tooltip) {
          tooltip = document.createElement("div");
          tooltip.id = "stack-tooltip";
          tooltip.style.position = "absolute";
          tooltip.style.backgroundColor = "rgba(0,0,0,0.8)";
          tooltip.style.color = "#fff";
          tooltip.style.padding = "6px 10px";
          tooltip.style.borderRadius = "4px";
          tooltip.style.fontSize = "12px";
          tooltip.style.zIndex = "1000";
          tooltip.style.pointerEvents = "none";
          document.body.appendChild(tooltip);
        }
        tooltip.textContent = `${this.dataset.label}: ${this.dataset.value} (${this.dataset.percent}%)`;
        tooltip.style.left = `${e.pageX + 10}px`;
        tooltip.style.top = `${e.pageY + 10}px`;
        tooltip.style.display = "block";
      });

      stackBlock.addEventListener("mousemove", function(e) {
        const tooltip = document.getElementById("stack-tooltip");
        if (tooltip) {
          tooltip.style.left = `${e.pageX + 10}px`;
          tooltip.style.top = `${e.pageY + 10}px`;
        }
      });

      stackBlock.addEventListener("mouseleave", function() {
        const tooltip = document.getElementById("stack-tooltip");
        if (tooltip) {
          tooltip.style.display = "none";
        }
      });

      progressTrack.appendChild(stackBlock);
    });

    progressItem.appendChild(progressTrack);

    // 创建图例区域
    const legend = document.createElement("div");
    legend.style.display = "flex";
    legend.style.gap = "16px";
    legend.style.marginTop = "8px";
    legend.style.flexWrap = "wrap";

    item.stacks.forEach(stack => {
      const legendItem = document.createElement("div");
      legendItem.style.display = "flex";
      legendItem.style.alignItems = "center";
      legendItem.style.fontSize = "12px";
      legendItem.style.color = "#666";

      const colorBox = document.createElement("span");
      colorBox.style.width = "12px";
      colorBox.style.height = "12px";
      colorBox.style.backgroundColor = stack.color;
      colorBox.style.marginRight = "6px";
      colorBox.style.borderRadius = "2px";

      const text = document.createElement("span");
      text.textContent = `${stack.label}: ${stack.value}`;

      legendItem.appendChild(colorBox);
      legendItem.appendChild(text);
      legend.appendChild(legendItem);
    });

    progressItem.appendChild(legend);
    container.appendChild(progressItem);
  });
}

// 页面加载完成后初始化图表
document.addEventListener("DOMContentLoaded", function() {
  createStackProgressChart("stack-progress-container", stackProgressData);
});

HTML 结构示例

需要在页面中准备一个容器元素,用来挂载生成的堆叠式进度条,对应的 HTML 结构如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>堆叠式进度条示例</title>
  <style>
    /* 可选的基础样式,可自定义调整 */
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
    }
    #stack-progress-container {
      max-width: 800px;
      margin: 0 auto;
    }
  </style>
</head>
<body>
  <h2>堆叠式进度条图表展示</h2>
  <div id="stack-progress-container"></div>
  <script src="stack-progress.js"></script>
</body>
</html>

功能说明与扩展

上述实现的堆叠式进度条包含以下特性:

  • 支持多组进度条同时渲染,每组进度条独立计算占比
  • 每个堆叠块通过不同颜色区分,下方自动生成对应图例
  • 鼠标悬停在堆叠块上时,会显示该块的标签、数值和占比百分比
  • 进度条宽度变化带有过渡动画,视觉效果更平滑

如果需要扩展功能,可以基于现有代码进行调整:比如支持动态更新数据、自定义进度条高度和圆角、添加点击交互事件,或者适配移动端响应式布局。只需要修改对应的配置参数和样式逻辑即可,核心的占比计算逻辑不需要大改。

JavaScript堆叠进度条数据可视化图表实现百分比展示鼠标悬停提示

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。