当阵列长度改变时,D3自动更新

时间:2013-12-21 18:52:03

标签: d3.js

我在Scott Murray的Interactive Data Visualization中有一些简单的代码,只有很小的改动。我更改的是初始数据的长度5dataset1函数中25的长度click不同。

但是,每次单击和更新时,它都会生成随机的新数字,但长度仅显示5个条形。

这是什么原因?我怎么能修改它呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <script type="text/javascript" src="../d3/d3.v3.js"></script>
    <title>D3  index01 </title>
    <style type="text/css">
    div.bar{
        display: inline-block;
        width: 20px;
        height: 75px;
        background-color: teal;
        margin-right: 2px;

    }
    </style>
</head>
    <body>
    <p> click it </p>

        <script type = "text/javascript">
        var w=600;
        var h = 250;
        var dataset = [5,10,13,14,15];

        var xScale = d3.scale.ordinal()
            .domain(d3.range(dataset.length)).rangeRoundBands([0,w],0.05);

        var yScale = d3.scale.linear()
            .domain([0,d3.max(dataset)]).range([0,h]);

        var svg = d3.select("body")
                    .append("svg")
                    .attr("width",w)
                    .attr("height",h);

        svg.selectAll("rect")
                .data(dataset)
                .enter()
                .append("rect")
                .attr("x", function(d,i){
                    return xScale(i);
                })
                .attr("y",function(d){return (h-yScale(d));})
                .attr("width",xScale.rangeBand())
                .attr("height",function(d){return yScale(d);});

        svg.selectAll("text")
               .data(dataset)
               .enter()
               .append("text")
               .text(function(d) {
                    return d;
               })
               .attr("text-anchor", "middle")
               .attr("x", function(d, i) {
                    return xScale(i)+xScale.rangeBand() / 2;
               })
               .attr("y", function(d) {
                    return h - yScale(d) + 14;
               })
               .attr("font-family", "sans-serif")
               .attr("font-size", "11px")
               .attr("fill", "white");

        d3.select("p")
            .on("click",function(){
                var dataset1  = [];
                for(var i=0; i<25; i++){
                    var newNumber = Math.floor(Math.random()*25);
                    dataset1.push(newNumber);
                }

                svg.selectAll("rect").data(dataset1)
                .transition()
                .delay(function(d,i){
                    return i*100;
                })
                .duration(500)
                .attr("x",function(d,i){
                    return xScale(i);
                })
                .attr("y",function(d){
                    return h-yScale(d);
                })
                .attr("x", function(d,i){
                    return xScale(i);
                })
                .attr("height",function(d){
                    return yScale(d);
                })
                .attr("fill",function(d){
                    return "rgb(0,0, " + (d*10) + ")";
                });

                svg.selectAll("text").data(dataset1).
                text(function(d) {
                    return d;
                })
                   .attr("x", function(d, i) {
                            return xScale(i) + xScale.rangeBand() / 2;
                })
                   .attr("y", function(d) {
                   return h - yScale(d) + 14;
                });
            });
        </script>
    </body>
</html>

1 个答案:

答案 0 :(得分:0)

我认为,问题在于,使用此声明更新rect时使用新号码

svg.selectAll("rect").data(dataset1)

selectAll仅选择根据rect

创建的原始5 dataset
var dataset = [5,10,13,14,15];

您可以从一开始就使用同样大小的起始dataset创建它们,或者此时附加新的rect svgs。

由于您正在对原始rect进行转换,我认为从最开始的25开始是最有意义的。您可以编写一个函数来自动生成它并将其放在dataset的位置定义如下:

var dataset = [];
var numBars = 25; // This is the number of bars you want
var maxHeight = 25;  // Seems like this is independent and needed as a ceiling
for(var i =0;i < N;i++){
   var newNumber = Math.floor(Math.random()* maxHeight);
   dataset.push(newNumber);
}

然后,您也可以在numBars函数中用onclick替换25。