I'm able to draw gridlines at the center point of my data in my chart using something like this:
startX = d3.min(x.domain()),
endX = d3.max(x.domain()),
startY = d3.min(y.domain()),
endY = d3.max(y.domain());
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}]
And then rendering the lines.
However, what I want are lines at the mean (and/or median depending on the case) value of the range of data. I tried this, but the line is the the same place as the code above yields. Below is my full code that I'm trying to draw the lines at the mean of the x and y data ranges. I think the problem is how I'm defining the variable x and y, but I'm not sure how to adjust them. What happens is that both lines are drawn at 44 (44 on the x axis vertically and 44 on the y axis horizontally). However, the mean of the datasets aren't both 44. This is the correct value for the horizontal line, but not the vertical line.
EDIT: Figured out that the issue is that the mean that I'm getting is the mean of the values on the axis line, which isn't the same as the mean of my data set. Not sure how to adjust for this though.
var margin = {t:30, r:20, b:20, l:40 },
w = 1000 - margin.l - margin.r,
h = 600 - margin.t - margin.b,
x = d3.scale.linear()
.range([0, w])
y = d3.scale.linear()
.range([h - 60, 0])
color = d3.scale.category10();
var svg = d3.select("#chart").append("svg")
.attr("width", w + margin.l + margin.r)
.attr("height", h + margin.t + margin.b);
fig = svg.append("g").attr("transform", "translate(40, 20)");
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");
ymean = d3.mean(y.domain());
xmean = d3.mean(x.domain());
lines = [{x1: startX, x2: endX, y1: ymean, y2: ymean},//horizontal
{x1: xmean, x2:xmean, y1: startY, y2: endY}] //vertical
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")
Any suggestions would be helpful. Thanks.
EDIT: As suggested, I have a different assessor now, but the lines simply aren't drawing. Here's the updated code:
ymean = d3.mean(data, function(d) { return d.incidence; });
xmean = d3.mean(data, function(d) { return d.variance; });
lines = [{x1: startX, x2: endX, y1: ymean, y2: ymean},
{x1: xmean, x2:xmean, y1: startY, y2: endY}]
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")
There are no errors for this, but the lines don't draw at all. If I substitute values in my lines variable, like below, the same result.
lines = [{x1: startX, x2: endX, y1: 50, y2: 50},
{x1: xmean, x2:xmean, y1: startY, y2: endY}]
This suggests to me that there's a problem with this piece, but I have no idea what it is.
You'll want to calculate the mean and median based on your data, instead of your scale:
These are generic accessor functions, if you need specific guidance on the accessor function (the
function(d) { return d.xVal; }
part), you'll need to provide the format of your input dataset