bitkorn
bitkorn

Reputation: 658

D3.js 4 histogram with JSON from AJAX

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): enter image description here

My data is not in histogram bins. The array objects are missing.

Here are the data from bl.ocks.org working example: enter image description here

...and the bins from histogram from bl.ocks.org example: enter image description here

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

Answers (1)

SteveR
SteveR

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

Related Questions