Reputation: 177
I have this json array which is returned in this format from a mySQL database using PHP:
[{"dateTimeTaken":"2013-02-28 05:04:16","reading":"10.7","parameterType":"Flouride"},
{"dateTimeTaken":"2013-02-28 05:04:21","reading":"10.5","parameterType":"Flouride"},
{"dateTimeTaken":"2013-02-28 05:04:26","reading":"15.1","parameterType":"pH"},
{"dateTimeTaken":"2013-02-28 05:04:31","reading":"4.4","parameterType":"Temperature"}...
I have two dropdown lists - where the user will select a) "parameterType" and then b) "month". I would like to return the mean/average reading for each day within the selected month for the selected parameterType.
Not sure how I can do this in D3 - but thought it may be something along the lines of:
Not sure if I'm completely off the mark though - or how I can even achieve this?
UPDATE:
d3.select("#parameterType").on("change", function() { filterData(); });
d3.select("#dateTimeTaken").on("change", function() { filterData(); });
function filterData()
{
var selectedParameter = document.getElementById("parameterType").value;
var selectedMonth = document.getElementById("dateTimeTaken").value;
var selectedData = data.filter(function(d)
{
return d.parameterType == selectedParameter &&
d.dateTimeTaken.getMonth() == (selectedMonth-1);
});
console.log(selectedData);//RETURNING EMPTY ARRAY?
mean = d3.mean(selectedData,function(d) { return d.reading})
//UPDATE GRAPH
x.domain(d3.extent(data, function(d) { return d.dateTimeTaken; }));
y.domain(d3.extent(data, function(d) { return d.reading; }));
svg.select("path.line")
.attr("d", line(data));
svg.select(".x.axis")
.transition()
.duration(750)
.ease("linear")
.call(xAxis);
svg.select(".y.axis")
.transition()
.duration(750)
.ease("linear")
.call(yAxis);
}
});
});
Upvotes: 3
Views: 14304
Reputation: 2206
What you are looking for is standard javascript Array.filter method:
See https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter
For each "redraw" you would create a filtered subset:
var selectedData = data.filter(function(d) {
return d.parameterType == selectedParameter &&
+d.dateTimeTaken.slice(5,7) == selectedMonth;
})
and the mean can be easily calculated
mean = d3.mean(selectedData,function(d) { return +d.reading})
Please note that by putting a plus sign (+) in front of a variable a conversion to a numeric value is attempted.
However at this point you might realize that it's quite inconvenient to work with dates in string format. What you might do is do a little preprocessing before any filtering:
var dateFmt = d3.time.format("%Y-%m-%d %H:%M:%S");
data.forEach(function(d) {
d.reading = +d.reading; // convert to number
d.dateTimeTaken = dateFmt.parse(d.dateTimeTaken); // convert to javascript date
});
Here I'm using the d3.time.format functionality to convert a string date into a javascript date (see https://github.com/mbostock/d3/wiki/Time-Formatting)
In this case your filter (see above) would be slightly different:
var selectedData = data.filter(function(d) {
return d.parameterType == selectedParameter &&
+d.dateTimeTaken.getMonth() == (selectedMonth-1);
})
Please note that because getMonth() is 0 for January and 11 for December, I have to substract one from selectedMonth to get a proper comparison.
Upvotes: 4