简体   繁体   中英

d3 time scale - last bar on graph is appearing outside of the graph

I'm building a bar graph in D3 version 4, using a time scale as my x axis. The axis itself renders fine, but the bars are off; the last bar in the graph is appearing outside of the range of the axis. How do I specify the proper range and/or x values?

Working example

Code Snippet:

const xScale = (width, dates) =>
  scaleTime()
    .domain([new Date(dates[0]), new Date(last(dates))])
    .range([0, width])

svg.select('g')
  .selectAll(`.${styles['bar']}`)
  .data(series)
  .enter()
  .append('rect')
  .attr('class', styles['bar'])
  .attr('x', (d) => x(d.date))
  .attr('width', Math.floor(width / series.length))
  .attr('y', (d) => {
    const scaled = y(d.count)
      return height - scaled > 0 && height - scaled < 2
      ? height - 2
      : scaled
  })
  .attr('height', (d) => {
    const scaled = height - y(d.count)
    return scaled > 0 && scaled < 2
      ? 2
      : scaled
  })

不对齐吧

The problem is not the width of the bar, or the paddings, or the range... the problem is the very concept of scaleTime . For instance, your first value is (I'm referring to the working example):

Wed Sep 21 2016

Which starts before 2017 but, because of the width of the bars, goes after 2017. Your last value is (again, working example):

Sat Sep 21 2030

Which sits just before the end of the domain (2030) but, because the width of the bars, goes after the range for that scale.

You can easily see this is this fiddle, where I set the domain going up to 2032: https://jsfiddle.net/gerardofurtado/dnxc9cd9/

A simple solution: if you want a bar chart showing years in the x scale, parse your dates getting the years and use a band scale instead.

It looks like the left edge of the final bar is appearing inside the range. I guess you could fix this by making your range slightly wider than width. (Say width + expected width of one bar.)

const barWidth = width / series.length;


const xScale = (width, dates) =>
  scaleTime()
    .domain([new Date(dates[0]), new Date(last(dates))])
    .range([0, width - barWidth])

svg.select('g')
  .selectAll(`.${styles['bar']}`)
  .data(series)
  .enter()
  .append('rect')
  .attr('class', styles['bar'])
  .attr('x', (d) => x(d.date))
  .attr('width', Math.floor(barWidth))
  .attr('y', (d) => {
    const scaled = y(d.count)
      return height - scaled > 0 && height - scaled < 2
      ? height - 2
      : scaled
  })
  .attr('height', (d) => {
    const scaled = height - y(d.count)
    return scaled > 0 && scaled < 2
      ? 2
      : scaled
  })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM