Последняя ячейка в гистограмме имеет меньшую ширину, чем другие

#d3.js

#d3.js

Вопрос:

У меня есть D3.js график гистограммы, в котором есть проблема, из-за которой моя последняя ячейка по оси x значительно меньше, чем остальные ячейки одинаковой ширины. Сначала я подумал, что это проблема с осью, но ось установлена с типичным диапазоном ширины и высоты и доменами, что заставляет меня поверить, что это связано с моим штрих-кодом, но я не уверен, что создало бы только одну неправильную ширину для bing, в то время как другие ячейки имеют одинаковую ширину. Ниже приведен мой код. Любая помощь будет оценена!

Код:

 <meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<style>
    #sleep-dist-histo {
        stroke-width: 0.5;
        stroke: goldenrod;
    }
</style>

<script>

    var data = [
        { "x": "7.41" },
        { "x": "7.01" },
        { "x": "8.39" },
        { "x": "8.22" },
        { "x": "8.31" },
        { "x": "8.33" },
        { "x": "8.16" },
        { "x": "8.00" },
        { "x": "6.04" },
        { "x": "8.18" },
        { "x": "7.47" },
        { "x": "7.57" },
        { "x": "7.11" },
        { "x": "6.59" },
        { "x": "7.51" },
        { "x": "6.31" },
        { "x": "8.01" },
        { "x": "8.14" },
        { "x": "8.26" },
        { "x": "7.44" },
        { "x": "7.54" },
        { "x": "6.23" },
        { "x": "6.25" },
        { "x": "7.50" },
        { "x": "7.45" },
        { "x": "9.34" },
        { "x": "7.53" },
        { "x": "7.11" },
        { "x": "8.17" },
        { "x": "8.02" },
        { "x": "8.12" },
        { "x": "8.14" },
        { "x": "7.49" },
        { "x": "6.35" },
        { "x": "7.07" },
        { "x": "5.46" },
        { "x": "6.56" },
        { "x": "7.41" },
        { "x": "8.06" },
        { "x": "7.31" },
        { "x": "8.53" },
        { "x": "7.42" },
        { "x": "7.41" },
        { "x": "7.57" },
        { "x": "7.38" },
        { "x": "8.04" },
        { "x": "6.29" },
        { "x": "7.52" },
        { "x": "7.42" },
        { "x": "8.06" },
        { "x": "8.09" },
        { "x": "8.03" },
        { "x": "7.06" },
        { "x": "7.33" },
        { "x": "8.09" },
        { "x": "7.47" },
        { "x": "7.54" },
        { "x": "7.31" },
        { "x": "7.30" },
        { "x": "7.50" },
        { "x": "4.07" },
        { "x": "8.22" },
        { "x": "7.44" }
    ]



    // console.log(data)
    var margin = { top: 15, right: 30, bottom: 50, left: 60  }
    var width = 800 - margin.left - margin.right;
    var height = 800 - margin.top - margin.bottom;

    var svg = d3.select("#my_dataviz")
        .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   ")"); // translate(margin left, margin top)

    // Append x-scale and x-scale tick labels
    var xAxisGroup = svg.append("g")
        .attr("class", "y-axis")
        .attr("transform", "translate("   0   ","   height   ")");

    // Set x-scale range
    var x = d3.scaleLinear()
        .range([0, width]);

    // Append x-scale title
    svg.append("text")             
        .attr("transform",
                "translate("   (width/2)   " ,"   (height   margin.bottom)   ")")
        .style("text-anchor", "middle")
        .text("Time Asleep in Hours (Bins)");
    
    // Set y-scale range
    var y = d3.scaleLinear()
        .range([height, margin.top]);
    
    // Append y-scale
    var yAxisGroup = svg.append("g")
        .attr("class", "y-axis");
    
    // Append y-scale title
    svg.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - margin.left)
        .attr("x",0 - (height / 2))
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("Count of Days Asleep");

    d3.interval(function(){
        update(data)
    }, 1000);

    update(data);

    function update(data){

        // X and Y axis domains
        x.domain([0, d3.max(data, function(d) { return  d.x })])
        
        var xAxisCall = d3.axisBottom(x);
        var yAxisCall = d3.axisLeft(y);

        xAxisGroup.call(xAxisCall);
        yAxisGroup.call(yAxisCall);

        var histogram = d3.histogram()
            .value(function(d) { return d.x })
            .domain(x.domain())
            .thresholds(x.ticks());

        var bins = histogram(data);

        y.domain([0, d3.max(bins, function(d){ return d.length; })]);

        // Append bars
        svg.selectAll("bar")
            .data(bins)
            .enter()
            .append("rect")
                .attr("x", 1)
                .attr("transform", function(d) { return "translate("   x(d.x0)   ","   y(d.length)   ")"; })
                .attr("width", function(d) { return x(d.x1) - x(d.x0) - 1 ; })
                .attr("height", function(d) { return height - y(d.length); })
                .style("fill", "steelblue")
                .attr("id", "sleep-dist-histo");
                
        svg.selectAll("label")
            .data(bins)
            .enter()
            .append("text")
                .text(function(d){ return d.length })
                .attr("x", function(d){ return (x(d.x0)   x(d.x1)) / 2; })
                .attr("y", function(d){ return y(d.length) - 15; })
                .attr("class", "label")
                .attr("dy", ".71em")
                // .style("text-anchor", "end")
                ;
    }
</script>  

Ответ №1:

Это потому, что домен x равен [0, 9.34], поэтому в итоге получилось 9.34 вместо 10 (чтобы сохранить ту же ширину)

Решение:

  1. добавьте .nice() к x к «Расширяет домен, чтобы он начинался и заканчивался хорошими круглыми значениями «. (Смотрите здесь);
  2. удалите последний элемент новых bin данных, иначе будет ноль от 10 до 11

 <meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<style>
    #sleep-dist-histo {
        stroke-width: 0.5;
        stroke: goldenrod;
    }
</style>

<script>

    var data = [
        { "x": "7.41" },
        { "x": "7.01" },
        { "x": "8.39" },
        { "x": "8.22" },
        { "x": "8.31" },
        { "x": "8.33" },
        { "x": "8.16" },
        { "x": "8.00" },
        { "x": "6.04" },
        { "x": "8.18" },
        { "x": "7.47" },
        { "x": "7.57" },
        { "x": "7.11" },
        { "x": "6.59" },
        { "x": "7.51" },
        { "x": "6.31" },
        { "x": "8.01" },
        { "x": "8.14" },
        { "x": "8.26" },
        { "x": "7.44" },
        { "x": "7.54" },
        { "x": "6.23" },
        { "x": "6.25" },
        { "x": "7.50" },
        { "x": "7.45" },
        { "x": "9.34" },
        { "x": "7.53" },
        { "x": "7.11" },
        { "x": "8.17" },
        { "x": "8.02" },
        { "x": "8.12" },
        { "x": "8.14" },
        { "x": "7.49" },
        { "x": "6.35" },
        { "x": "7.07" },
        { "x": "5.46" },
        { "x": "6.56" },
        { "x": "7.41" },
        { "x": "8.06" },
        { "x": "7.31" },
        { "x": "8.53" },
        { "x": "7.42" },
        { "x": "7.41" },
        { "x": "7.57" },
        { "x": "7.38" },
        { "x": "8.04" },
        { "x": "6.29" },
        { "x": "7.52" },
        { "x": "7.42" },
        { "x": "8.06" },
        { "x": "8.09" },
        { "x": "8.03" },
        { "x": "7.06" },
        { "x": "7.33" },
        { "x": "8.09" },
        { "x": "7.47" },
        { "x": "7.54" },
        { "x": "7.31" },
        { "x": "7.30" },
        { "x": "7.50" },
        { "x": "4.07" },
        { "x": "8.22" },
        { "x": "7.44" }
    ]



    // console.log(data)
    var margin = { top: 15, right: 30, bottom: 50, left: 60  }
    var width = 800 - margin.left - margin.right;
    var height = 800 - margin.top - margin.bottom;

    var svg = d3.select("#my_dataviz")
        .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   ")"); // translate(margin left, margin top)

    // Append x-scale and x-scale tick labels
    var xAxisGroup = svg.append("g")
        .attr("class", "y-axis")
        .attr("transform", "translate("   0   ","   height   ")");

    // Set x-scale range
    var x = d3.scaleLinear()
        .range([0, width]);

    // Append x-scale title
    svg.append("text")             
        .attr("transform",
                "translate("   (width/2)   " ,"   (height   margin.bottom)   ")")
        .style("text-anchor", "middle")
        .text("Time Asleep in Hours (Bins)");
    
    // Set y-scale range
    var y = d3.scaleLinear()
        .range([height, margin.top]);
    
    // Append y-scale
    var yAxisGroup = svg.append("g")
        .attr("class", "y-axis");
    
    // Append y-scale title
    svg.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - margin.left)
        .attr("x",0 - (height / 2))
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("Count of Days Asleep");

   /*  d3.interval(function(){
        update(data)
    }, 1000);
     */
    update(data);

    function update(data){

        // X and Y axis domains
        x.domain([0, d3.max(data, function(d) { return ( d.x) })]).nice()
        
        var xAxisCall = d3.axisBottom(x);
        var yAxisCall = d3.axisLeft(y);

        xAxisGroup.call(xAxisCall);
        yAxisGroup.call(yAxisCall);

        var histogram = d3.histogram()
            .value(function(d) { return  d.x })
            .domain(x.domain())
            .thresholds(x.ticks());

        var bins = histogram(data);

        y.domain([0, d3.max(bins, function(d){ return d.length; })]);
  bins = bins.slice(0, bins.length-1)
        // Append bars
        svg.selectAll("bar")
            .data(bins)
            .enter()
            .append("rect")
                .attr("x", 1)
                .attr("transform", function(d) { return "translate("   x(d.x0)   ","   y(d.length)   ")"; })
                .attr("width", function(d) { return x(d.x1) - x(d.x0) - 1 ; })
                .attr("height", function(d) { return height - y(d.length); })
                .style("fill", "steelblue")
                .attr("id", "sleep-dist-histo");
                
        svg.selectAll("label")
            .data(bins)
            .enter()
            .append("text")
                .text(function(d){ return d.length })
                .attr("x", function(d){ return (x(d.x0)   x(d.x1)) / 2; })
                .attr("y", function(d){ return y(d.length) - 15; })
                .attr("class", "label")
                .attr("dy", ".71em")
                // .style("text-anchor", "end")
                ;
    }
</script>