1

I'm trying to create a scatterplot, which I've been able to do just fine. I'd like to separate this plot into four quadrants by drawing ticklines at a specific point on the x axis and specific point on the y axis. In my case, both axes are showing percentages, so I'd like to draw a line at the tick for 0.50 on both axes, but I haven't any clue how to do this and can't find any documentation that is working for me.

Here's what I have to define my axes:

var xAxis = d3.svg.axis()
    .scale(x)
    .ticks(20)
    .tickSubdivide(true)
    .tickSize(6, 3, 0)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .ticks(20)
    .tickSubdivide(true)
    .tickSize(6, 3, 0)
    .orient("left");

Any insight would be appreciated.

user229044
  • 232,980
  • 40
  • 330
  • 338
jonmrich
  • 4,233
  • 5
  • 42
  • 94

1 Answers1

3

The key point here is you're trying to append two lines that divide the scatterplot evenly into four quadrants. To do that, you can find the min/max of your x- and y-axes (using their corresponding scales), and then append lines at the midpoint:

var startX = d3.min(x.domain()),
    endX = d3.max(x.domain()),
    startY = d3.min(y.domain()),
    endY = d3.max(y.domain());
var lines = [{x1: startX, x2: endX, y1: (startY + endY)/2, y2: (startY + endY)/2},
             {x1: (startX + endX)/2, x2: (startX + endX)/2, y1: startY, y2: endY}]

Then you just need to append these lines to your figure:

fig.selectAll(".grid-line")
    .data(lines).enter()
    .append("line")
    .attr("x1", function(d){ return x(d.x1); })
    .attr("x2", function(d){ return x(d.x2); })
    .attr("y1", function(d){ return y(d.y1); })
    .attr("y2", function(d){ return y(d.y2); })
    .style("stroke", "#000")
    .style("stroke-dasharray", (10, 10));

Doing so gives you something like this (see corresponding complete JSFiddle):

scatterplot axes divided into quadrants

mdml
  • 22,442
  • 8
  • 58
  • 66
  • Thanks. This basically did the trick, but my horizontal line isn't in quite the right place because my data isn't perfectly ranged from 0-100. The lines always need to be placed at 50 on the x and 50 on the y. This corresponds to percentages, so I want a line always at 50 and 50. I tried this but it didn't work: `var lines = [{x1: 50, x2: 50, y1: 0, y2: 100}, {x1: 0, x2: 100, y1: 50, y2: 50}]` There ended up being no lines. – jonmrich Nov 21 '14 at 16:56
  • @jonmrich: I'm not sure I understand. Could you post your code? It'd be easier to understand what's going on. – mdml Nov 21 '14 at 17:00
  • Actually, I figured out that your approach is actually what I need. I want the chart divided into 4 equal quadrants and this should be defined by the ranges in the data. My issue now is that all my points fall in the lower-left quadrant because my axes ranges are wrong. How do you set the access ranges based on the data max and mins? – jonmrich Nov 21 '14 at 17:15
  • @jonmrich: I think you should post that as a separate question, along with your code. I'd be happy to take a look. – mdml Nov 21 '14 at 17:25
  • Unfortunately I can only post a question once every 90 minutes and was hoping to figure out something before then. I'll post the new question when I can, but in the meantime, I'm just trying to figure out how to set these values dynamically: `x.domain([0,100]); y.domain([0,100])` – jonmrich Nov 21 '14 at 17:36
  • @jonmrich: what does your data look like? Ideally you'd want something like `x.domain(d3.extent(data.map(function(d){ return d.x; })))`... – mdml Nov 21 '14 at 17:38
  • Here's the new question [http://stackoverflow.com/questions/27067550/set-axis-range-based-on-data-set-minimum-and-maximum-in-d3-js] Thanks for taking a look. – jonmrich Nov 21 '14 at 18:03