0

I have a D3 stacked bar chart that is working great except that the last bar overhangs the right side of X axis and the left side of the axis is not touching the Y axis. This is because I had to move the bars so that they would be centered over the tick lines. I thought that if I padded the time scale by a date on either end that would take care of it, but instead the bars just spread out to take up the available space.

Here is a JSFiddle: http://jsfiddle.net/goodspeedj/cvjQq/

Here is the X scale:

var main_x = d3.time.scale().range([0, main_width-axis_offset - 5]);

This is my attempt to pad the X axis by a date on either end:

main_x.domain([
    d3.min(data.result, function(d) { 
        return d.date.setDate(d.date.getDate() - 1); 
    }), 
    d3.max(data.result, function(d) { 
        return d.date.setDate(d.date.getDate() + 1); 
    }
)]);

The calculation for the x attribute on the bars is:

.attr("x", function(d) { return main_x(d.date) - (main_width/len)/2; })

This is a minor thing, but it is really annoying me. Thanks!

JamesE
  • 3,833
  • 9
  • 44
  • 82
  • 1
    [This question](http://stackoverflow.com/questions/18835053/d3-js-calculate-width-of-bars-in-time-scale-with-changing-range) may help. – Lars Kotthoff Apr 08 '14 at 21:04
  • I tried the solution in that posting, but the last bar gets cut in half (must be doing something wrong). I'll try to post a fiddle in a bit. Thanks. – JamesE Apr 09 '14 at 18:26
  • I can see now that I'm using a smaller dataset that the issue is really the X axis is not lined up correctly: http://jsfiddle.net/goodspeedj/cvjQq/ I know this is because of the main_x time scale, but not sure what the best way to fix it is. – JamesE Apr 09 '14 at 19:06
  • 1
    The problem is that you're appending a clip path that clips the graph. It works fine if you remove it: http://jsfiddle.net/cvjQq/2/ – Lars Kotthoff Apr 09 '14 at 19:14
  • Good catch, but the last bar still hangs off the end of the X axis. Adding an additional day to the domain doesn't seem to help. – JamesE Apr 09 '14 at 19:29
  • OK, I have it working, but I don't think it is the best solution. Had to do this: `main_x.domain([d3.min(data.result, function(d) { return d.date.setDate(d.date.getDate() - 1); }), d3.max(data.result, function(d) { return d.date.setDate(d.date.getDate() + 2); })]);` and then this: `.attr("x", function(d) { return main_x(d.date.setDate(d.date.getDate() - 1)) - (main_width/len)/2; })` The fiddle has the working code. Do you think there a cleaner way to do this? – JamesE Apr 09 '14 at 19:34
  • Well the first bar hangs off the beginning of the start of the axis as well. If you don't want that, then something like you're doing is the way to go. – Lars Kotthoff Apr 09 '14 at 19:38
  • OK, thanks for the help. If you want to post an answer I'll mark it as accepted so you get the credit. Thanks again. – JamesE Apr 09 '14 at 19:44

1 Answers1

1

The main problem was that you had a clip path in your SVG that clipped parts of the plotting region. Once that is removed, you can see the full graph, but the first and last bars will still "hang" over the ends of the axis.

To change that, you have to extend the axis, e.g. by adding a day or two either way when computing the minimum and maximum for the scale.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204