D3.js 3D柱状图开发问题:柱状未贴合X轴且重叠
解决D3.js 3D柱状图贴合X轴及重叠问题
问题分析
你遇到的两个核心问题:
- 柱子不贴合X轴:柱子的Y起始位置设置错误,未对齐X轴坐标点
- 视觉重叠感:源于柱子X起始位置偏移,以及SVG路径的语法错误
修改后的完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>D3.js 3D Bar Chart</title> <script src="https://d3js.org/d3.v7.min.js"></script> </head> <body> <div id="my_dataviz"></div> <script> const add3DBar = (parent, xPos, yPos, width, height, depth, duration) => { const g = parent.append('g').attr('transform', `translate(${xPos}, ${yPos})`); // 正面 g.append('path') .attr('d', `M 0,0 V 0 H ${width} V 0 H 0 Z`) .style('fill', '#000081') .transition() .duration(duration) .attr('d', `M 0,0 V ${-height} H ${width} V 0 H 0 Z`); // 顶面 g.append('path') .attr('d', `M 0,0 L ${depth},${-depth} H ${depth + width} L ${width},0 Z`) .style('fill', '#0000FF') .transition() .duration(duration) .attr('d', `M 0,${-height} L ${depth},${-height-depth} H ${depth + width} L ${width},${-height} Z`); // 右侧面(修复路径多余逗号) g.append('path') .attr('d', `M ${width},0 L ${width + depth},${-depth} V ${-depth} L ${width},0 Z`) .style('fill', '#0000C0') .transition() .duration(duration) .attr('d', `M ${width},0 L ${width + depth},${-depth} V ${-height-depth} L ${width},${-height} Z`); } // 设置图表尺寸与边距 var margin = { top: 30, right: 30, bottom: 70, left: 60 }, width = 460 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; // 创建SVG容器 var svg = d3.select("#my_dataviz") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // 定义比例尺 var x = d3.scaleBand() .range([0, width]) .padding(0.1); var y = d3.scaleLinear() .range([height, 0]); // 加载并处理数据 d3.csv("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/7_OneCatOneNum_header.csv") .then(function(data) { // 设置比例尺定义域 x.domain(data.map(d => d.Country)); y.domain([0, d3.max(data, d => +d.Value)]); // 绘制每个3D柱子 data.forEach(function(d) { const xPos = x(d.Country); // 修正:柱子起始位置对齐X轴刻度 const yPos = height; // 修正:柱子底部对齐X轴(height为X轴Y坐标) const barHeight = height - y(d.Value); // 柱子高度:X轴到数据点的距离 add3DBar(svg, xPos, yPos, x.bandwidth(), barHeight, 10, 1500); }); // 绘制X轴 svg.append("g") .attr("transform", `translate(0,${height})`) .call(d3.axisBottom(x)) .selectAll("text") .attr("transform", "translate(-10,0)rotate(-45)") .style("text-anchor", "end"); // 绘制Y轴 svg.append("g") .call(d3.axisLeft(y)); }) .catch(function(error) { console.log("数据加载错误:", error); }); </script> </body> </html>
关键修改说明
柱子贴合X轴:
将柱子Y起始位置yPos从y(d.Value)改为height,D3中height是X轴所在的Y坐标(Y比例尺range为[height, 0]),确保柱子底部精准对齐X轴。修正X轴位置偏移:
将xPos从x(d.Country)+x.bandwidth()/2改为x(d.Country),让柱子起始位置与X轴刻度起始位置完全对齐,消除偏移导致的视觉重叠。修复SVG路径语法错误:
删除右侧面路径中多余的逗号(${-depth}, V),避免路径渲染异常,保证3D面显示正确。冗余资源清理:
移除头部重复引入的D3脚本,避免重复加载。
内容的提问来源于stack exchange,提问作者Mohit
相关产品推荐
相关产品推荐

