Reputation: 658
With help from https://bl.ocks.org histogram example I try to create a histogram with JSON from AJAX.
It seems like my data is not suitable for the histogram() function.
My Data in dev tools (top = my data; bottom = bins from the histogram):
My data is not in histogram bins. The array objects are missing.
Here are the data from bl.ocks.org working example:
...and the bins from histogram from bl.ocks.org example:
You can see it clearly. In my experiment, the data is not in the bins. In the working example of bl.ocks.org you can see the additional objects as an array from index 1 to 13 in the histogram bins.
Here is my full source code:
$(function () {
var updateStatistic = function () {
var dateFrom = $('#date_from').val();
var dateTo = $('#date_to').val();
var parseDate = d3.timeParse('%Y-%m-%d %H:%M:%S'), formatCount = d3.format(',.0f');
var margin = {top: 10, right: 10, bottom: 20, left: 10},
width = 1800 - margin.left - margin.right,
height = 200 - margin.top - margin.bottom;
var dataset = [];
d3.json('/statistic-sizearchive/' + dateFrom + '/' + dateTo, function (data) {
dataset = data.sizeArchive;
dataset.columns = ['date'];
var datetimeFrom = parseDate(dataset[0].archive_time_sql);
var datetimeTo = parseDate(dataset[dataset.length - 1].archive_time_sql);
$(dataset).each(function (index, element) {
element.date = parseDate(element.archive_time_sql);
delete element.archive_time_sql;
});
console.log(dataset);
var x = d3.scaleTime()
.domain([datetimeFrom, datetimeTo])
.rangeRound([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
var histogram = d3.histogram()
.value(function (d) {
return d.length;
})
.domain(x.domain())
.thresholds(x.ticks(d3.timeWeek));
var bins = histogram(dataset);
console.log(bins);
y.domain([0, d3.max(bins, function (d) {
return d.length;
})]);
/*
* ### SVG
*/
var svg = d3.select('#statistic_size_archive').append('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
var bar = svg.selectAll(".bar")
.data(bins)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function (d) {
return "translate(" + x(d.x0) + "," + y(d.length) + ")";
})
;
bar.append("rect")
.attr("x", 1)
.attr("width", function (d) {
return x(d.x1) - x(d.x0); // x(d.x1) - x(d.x0) - 1
})
.attr("height", function (d) {
return height - y(d.length); // height - y(d.length)
});
bar.append("text")
.attr("dy", ".75em")
.attr("y", 0)
.attr("x", function (d) {
return (x(d.x1) - x(d.x0)) / 2;
})
.attr("text-anchor", "middle")
.text(function (d) {
return formatCount(d.length);
});
});
};
updateStatistic();
$('button#update_statistic').click(function () {
updateStatistic();
});
});
I do not see anything that I'm doing wrong.
Upvotes: 2
Views: 616
Reputation: 1131
Without your actual data, I'm not able to test this code... however, it appears that your histogram call function is returning the wrong value from the data. Instead of returning d.length
, shouldn't the code be:
var histogram = d3.histogram()
.value(function (d) {
return d.date;
})
...
This way, the histogram will put each data point into a bin determined by its date?
Upvotes: 2