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

如何使用D3.js绘制带指定交互动效的自定义柱状图?

参考柱状图效果

实现效果说明

  • 页面加载后优先触发黄色柱状的入场动画,动画时长500ms,高度从0过渡到目标值
  • 黄色动画完成后延迟600ms,蓝色柱状按索引顺序依次执行入场动画,每个柱子间隔100ms触发
  • 点击X轴任意年份标签,会在对应年份位置绘制高亮参考骨线,自动替换上一次点击生成的骨线

完整实现代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>D3柱状图实现</title>
  <script src="https://d3js.org/d3.v7.min.js"></script>
  <style>
    .yellow-bar { fill: #ffc107; }
    .blue-bar { fill: #1976d2; }
    .axis-label { cursor: pointer; }
    .guide-line { stroke: #ff0000; stroke-width: 2; stroke-dasharray: 5,5; }
  </style>
</head>
<body>
  <svg width="800" height="500" id="chart"></svg>
  <script>
    // 模拟数据,可根据实际需求替换
    const data = [
      { year: '2018', yellowVal: 120, blueVal: 45 },
      { year: '2019', yellowVal: 150, blueVal: 62 },
      { year: '2020', yellowVal: 180, blueVal: 78 },
      { year: '2021', yellowVal: 220, blueVal: 95 },
      { year: '2022', yellowVal: 260, blueVal: 110 },
      { year: '2023', yellowVal: 300, blueVal: 135 }
    ]
    const margin = { top: 30, right: 30, bottom: 50, left: 50 }
    const width = 800 - margin.left - margin.right
    const height = 500 - margin.top - margin.bottom
    const svg = d3.select('#chart')
      .append('g')
      .attr('transform', `translate(${margin.left},${margin.top})`)
    // 比例尺
    const xScale = d3.scaleBand()
      .domain(data.map(d => d.year))
      .range([0, width])
      .padding(0.3)
    const yScale = d3.scaleLinear()
      .domain([0, d3.max(data, d => d.yellowVal)])
      .range([height, 0])
    // 绘制X轴
    const xAxis = svg.append('g')
      .attr('transform', `translate(0,${height})`)
      .call(d3.axisBottom(xScale))
      .selectAll('.tick text')
      .attr('class', 'axis-label')
    // 绘制黄色柱状
    const yellowBars = svg.selectAll('.yellow-bar')
      .data(data)
      .join('rect')
      .attr('class', 'yellow-bar')
      .attr('x', d => xScale(d.year))
      .attr('width', xScale.bandwidth())
      .attr('y', height)
      .attr('height', 0)
    // 黄色柱入场动画
    yellowBars.transition()
      .duration(500)
      .attr('y', d => yScale(d.yellowVal))
      .attr('height', d => height - yScale(d.yellowVal))
    // 绘制蓝色柱状
    const blueBars = svg.selectAll('.blue-bar')
      .data(data)
      .join('rect')
      .attr('class', 'blue-bar')
      .attr('x', d => xScale(d.year))
      .attr('width', xScale.bandwidth())
      .attr('y', height)
      .attr('height', 0)
    // 蓝色柱延迟入场动画
    blueBars.transition()
      .delay((d, i) => 1100 + i * 100)
      .duration(400)
      .attr('y', d => yScale(d.blueVal))
      .attr('height', d => height - yScale(d.blueVal))
    // 点击年份显示骨线逻辑
    let activeGuideline = null
    xAxis.on('click', (event, d) => {
      // 清除旧骨线
      if (activeGuideline) activeGuideline.remove()
      // 绘制新骨线
      const xPos = xScale(d) + xScale.bandwidth() / 2
      activeGuideline = svg.append('line')
        .attr('class', 'guide-line')
        .attr('x1', xPos)
        .attr('x2', xPos)
        .attr('y1', 0)
        .attr('y2', height)
    })
  </script>
</body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:18:04