计算宽度以在 D3.js 中创建连续水平条

我有一个水平时间线,我在 D3.js 中绘制随时间变化的事件:

http://img.mukewang.com/64a6876b000137a306540150.jpg

现在,我想“填充”事件之间的间隙,因此计算每个条形的宽度(类似于甘特图)。这就是我想要实现的目标:

http://img1.mukewang.com/64a6877500015ce106550152.jpg

我的逻辑是让 i+1 的位置减去位置,如下所示:


.attr('width', function(d,i){ 

        barWidth = xScale(barData2[i+1].eventTime) - xScale(barData2[i].eventTime);

        return barWidth;

     })

(其中 barWidth 是空变量,barData2 是数据)


这完成了工作,但也破坏了代码,因为它不会继续代码的其余部分:

http://img4.mukewang.com/64a68783000137cb06470146.jpg

我尝试过以各种方式计算这一点,但没有成功。有什么建议么?


var barData2 = [{

  eventTime: new Date("Mon May 11 2020 18:25:43 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Mon May 11 2020 18:34:14 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Mon May 11 2020 22:10:42 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Mon May 11 2020 22:14:46 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Mon May 11 2020 22:22:25 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Mon May 11 2020 22:30:35 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Tue May 12 2020 00:40:00 GMT+0100 (British Summer Time)")

}, {

  eventTime: new Date("Tue May 12 2020 05:00:57 GMT+0100 (British Summer Time)")

}];




var barWidth = 0;



var height = 200,

  width = 900,

  barHeight = 10;



var xScale = d3.time.scale()

  .domain([barData2[0].eventTime, barData2[(barData2.length - 1)].eventTime])

  .range([0, width - 85]);



var xScale2 = d3.time.scale()

  .domain([barData2[0].eventTime, barData2[(barData2.length - 1)].eventTime])

  .range([0, width - 85]);



var xAxisTicks = d3.axisBottom(xScale)

  .ticks(d3.timeHour.every(1));



var toolTip = d3.select('body')

  .append('div')

  .style('position', 'absolute')

  .style('padding', '0 10px')

  .style('background', 'white')

  .style('opacity', 0);


d3.select('#viz').append('svg')

  .attr('width', width)

  .attr('height', height)

  .style('background', '#aaa')


  .append('g')

  .selectAll('rect').data(barData2)

  .enter().append('rect')

  .attr('y', function(d, i) {

    return i * barHeight;

  })



ibeautiful
浏览 93回答 1
1回答

四季花海

实现这一点的最简单方法是提前稍微转换一下数据。请注意,如果我们有n事件,我们想要绘制n - 1条形。var barData2 = [{&nbsp; eventTime: new Date("Mon May 11 2020 18:25:43 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Mon May 11 2020 18:34:14 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Mon May 11 2020 22:10:42 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Mon May 11 2020 22:14:46 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Mon May 11 2020 22:22:25 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Mon May 11 2020 22:30:35 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Tue May 12 2020 00:40:00 GMT+0100 (British Summer Time)")}, {&nbsp; eventTime: new Date("Tue May 12 2020 05:00:57 GMT+0100 (British Summer Time)")}];// .slice(1) removes the first entry, because we have n events,// we want to draw n-1 barsbarData2Processed = barData2.slice(1).map(function(d, i) {&nbsp; return {&nbsp; &nbsp; // Note that because we removed the first entry, this is&nbsp; &nbsp; // actually the previous element, not the current one&nbsp; &nbsp; start: barData2[i].eventTime,&nbsp; &nbsp; end: d.eventTime&nbsp; }});var barWidth = 0;var height = 200,&nbsp; width = 900,&nbsp; barHeight = 10;var xScale = d3.time.scale()&nbsp; .domain([barData2[0].eventTime, barData2[(barData2.length - 1)].eventTime])&nbsp; .range([0, width - 85]);var xAxisTicks = d3.axisBottom(xScale)&nbsp; .ticks(d3.timeHour.every(1));var toolTip = d3.select('body')&nbsp; .append('div')&nbsp; .style('position', 'absolute')&nbsp; .style('padding', '0 10px')&nbsp; .style('background', 'white')&nbsp; .style('opacity', 0);d3.select('#viz').append('svg')&nbsp; .attr('width', width)&nbsp; .attr('height', height)&nbsp; .style('background', '#aaa')&nbsp; .append('g')&nbsp; .selectAll('rect').data(barData2Processed)&nbsp; .enter().append('rect')&nbsp; .attr('y', function(d, i) {&nbsp; &nbsp; return i * barHeight;&nbsp; })&nbsp; .attr('height', barHeight)&nbsp; .attr('width', function(d, i) {&nbsp; &nbsp; return xScale(d.end) - xScale(d.start);&nbsp; })&nbsp; .attr('x', function(d, i) {&nbsp; &nbsp; return xScale(d.start);&nbsp; })xGuide = d3.select('#viz svg').append('g')&nbsp; .attr('transform', 'translate(0,' + (height - 25) + ')')&nbsp; .call(xAxisTicks);<script src="https://d3js.org/d3.v3.min.js"></script><script src="https://d3js.org/d3.v4.js"></script><script src="https://d3js.org/d3-time.v2.min.js"></script><script src="https://d3js.org/d3-time-format.v3.min.js"></script><div id="viz"></div>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript