D3.js直方图柱子宽度适配日期范围问题求助
D3.js 直方图柱子宽度适配日期范围问题
我正在调整D3.js直方图的柱子宽度,目前用d.date.start或d.date.end作为.value()的返回值时,只能得到对应时间点的柱子,无法覆盖完整日期范围。想知道是否需要把解析后的起止时间转成Unix时间并计算差值?以及该怎么写.value()方法?我查过Github、ObservablesHQ、Stackoverflow、VizHub和Youtube都没解决,附上两种尝试代码,期望柱子宽度能和日期范围成比例。
尝试代码1
const parser = d3.timeParse("%Y-%m-%d"); const bins = d3 .bin() .value((d) => parser(d.date.start)) .domain(x.domain()) .thresholds(x.ticks(20))(events);
尝试代码2
const parser = d3.timeParse("%Y-%m-%d"); const bins = d3 .bin() .value((d) => parser(d.date.end)) .domain(x.domain()) .thresholds(x.ticks(20))(events);
解决思路与实现
你不需要把时间转成Unix时间再算差值,核心问题是D3的bin()默认处理的是单个时间点,但你的需求是让柱子对应时间区间,因此得换个思路:
1. 直接绘制时间区间柱子(无聚合需求)
如果只是想让每个柱子对应一条数据的起止时间区间,完全不用bin(),直接基于解析后的时间绘制即可:
第一步:预处理数据,解析时间并计算柱子宽度
const parser = d3.timeParse("%Y-%m-%d"); // 给每条数据解析起止时间,并计算柱子的像素宽度 const processedEvents = events.map(d => { const start = parser(d.date.start); const end = parser(d.date.end); return { ...d, start, end, width: x(end) - x(start) // 用x比例尺转成像素宽度 }; });
第二步:绑定数据绘制矩形
svg.selectAll(".bar") .data(processedEvents) .enter() .append("rect") .attr("class", "bar") .attr("x", d => x(d.start)) .attr("y", d => y(d.yField)) // 替换成你需要映射到y轴的字段 .attr("width", d => d.width) .attr("height", d => height - y(d.yField)) // 基于y轴高度计算柱子高度 .attr("fill", "steelblue");
2. 按时间区间聚合(需bin分组)
如果需要把重叠的时间区间按规则聚合(比如统计每个时间段内的事件数量),可以用bin()结合区间中点分组,再手动调整柱子宽度:
const bins = d3.bin() .value(d => { // 用每个时间区间的中点作为分组依据 const start = parser(d.date.start); const end = parser(d.date.end); return new Date((start.getTime() + end.getTime()) / 2); }) .domain(x.domain()) .thresholds(x.ticks(20))(events); // 绘制聚合后的柱子,宽度取bin区间的像素差值 svg.selectAll(".bin-bar") .data(bins) .enter() .append("rect") .attr("x", d => x(d.x0)) .attr("y", d => y(d.length)) // 用bin内的事件数量作为y轴值 .attr("width", d => x(d.x1) - x(d.x0)) .attr("height", d => height - y(d.length)) .attr("fill", "steelblue") .attr("opacity", 0.7);
关键说明
bin()的设计初衷是处理单个数据点的分组,面对时间区间类数据,直接绘制是更直观的方案。- 柱子宽度完全由D3时间比例尺自动转换,不需要手动处理Unix时间戳,比例尺会帮你完成时间到像素的映射。
内容的提问来源于stack exchange,提问作者Anthony Zornig
相关产品推荐
相关产品推荐

