Draw grid lines at mean (or median) range value in d3.js
I can draw grid lines 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, I want the rows to be in the mean (and / or median as appropriate) of the data range. I tried this, but the line is the same place as the above code. Below is my complete code that I am trying to draw lines on average from the x and y data ranges. I think the problem is how I define the x and y variable, but I'm not sure how to set it up. It happens that both lines are drawn at 44 (44 on the x-axis vertically and 44 on the y-axis horizontally). However, the average of the datasets is not 44. This is correct for a horizontal line, but not for a vertical line.
EDIT: It turned out that the problem is that the mean I am getting is the mean for the axis of the axis, which is not the same as the mean of my dataset. Not sure how to adjust to 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. Thank.
EDIT: As suggested, I have another evaluator now, but the lines just don't get drawn. 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 no lines are drawn at all. If I replace the values in my string like below, the same result.
lines = [{x1: startX, x2: endX, y1: 50, y2: 50},
{x1: xmean, x2:xmean, y1: startY, y2: endY}]
This tells me there is a problem with this part, but I have no idea what it is.
source to share
You want to calculate mean and median based on data instead of scale:
ymean = d3.mean(inputData, function(d) { return d.xVal; });
xmean = d3.mean(inputData, function(d) { return d.yVal; });
These are generic accessor functions, if you need specific guidance on accessor function (part function(d) { return d.xVal; }
) you need to provide the format of your input dataset
source to share