D3图表转换得到正确的数字或​​宽度,但不是两者

时间:2015-03-09 03:09:19

标签: javascript d3.js

我刚拿起D3并开始玩条形图动画。当我点击时,我有5个过渡到3和后面的栏。我可以:

  1. 将5个条形图变为3并返回5条,条形宽度无动态变化,或
  2. 动态更改条宽但只有3条(通过注释掉.enter()和.append())。
  3. 非常感谢有关如何获得两者的任何帮助!完整的文件在这里:

    https://github.com/datapress/learningD3/blob/master/chart.html

                var sortOrder = false;
    
                d3.selectAll("rect")
                  .on("click", function() {       
    
                    sortOrder = !sortOrder
    
                    var rectID = d3.select(this).attr("id");
    
                    var dataset0 = [1, 2, 3, 4, 5];
    
                    var dataset1 = [5, 1, 1];
                    var dataset2 = [1, 5, 1];
                    var dataset3 = [1, 1, 5];
                    var dataset4 = [5, 5, 1];
                    var dataset5 = [1, 5, 5];
    
                    if (sortOrder) {
                        if (rectID == 0) { dataset = dataset1 };
                        if (rectID == 1) { dataset = dataset2 };
                        if (rectID == 2) { dataset = dataset3 };
                        if (rectID == 3) { dataset = dataset4 };
                        if (rectID == 4) { dataset = dataset5 };
                    } else {
                        dataset = dataset0
                    }
    
                    xScale.domain(d3.range(dataset.length))
    
                    yScale.domain([0, d3.max(dataset, function(d) { return d; })])
    
                    svg.selectAll("rect")
                        .data(dataset)
                        .exit()
                        .remove()
    
                    svg.selectAll("rect")
                        .data(dataset)
                        .enter()
                        .append("rect")
                        .transition()   
                        .duration(1000)  
                        .attr({
                            x: function(d, i) { return xScale(i); }, 
                            y: function(d) { return h - yScale(d); },
                            width: xScale.rangeBand(),
                            height: function(d) { return yScale(d); },
                            fill: function(d) { return "rgb(0, 0, " + (255 - Math.round(d) * 36) + ")"; }
                            });
                        });
    

1 个答案:

答案 0 :(得分:2)

它很直率但是这里修复了你的代码以更新两者:

http://jsfiddle.net/TheMcMurder/r0ptsfLr/

注意:您没有遵循d3的输入,更新,退出方法。您有输入和退出,但是您没有在页面上存在的条形图的任何位置进行隐式更新,但需要使用新数据进行更改。

这是一个简单的例子:

        var data =[45, 10]

        var data2 =[45, 10, 20, 25, 30, 45]




        /*The purpose of this JSfiddle is to show how enter, update, and exit works in d3js.  The data values above are the data. The image had three manually created black circles.  My update will resize them to the appropriate size (based on data) and change their color to blue.  All newly drawn objects will be turned green and any object that is exiting will be turned red.

        The transitions are delayed to make it easier to see.  No delay is needed for this to work.

        */

        //creating the svg so I can draw objects on it
        var svg = d3.select("body").append("svg")
            .attr("width", 500)
            .attr("height", 5000)

        //creating initial circle objects
        var circle1 = svg.append("circle")
            .attr("cx", 100)
            .attr("cy", 100)
            .attr("r", 25)

        // another circle object
        var circle2 = svg.append("circle")
            .attr("cx", 100)
            .attr("cy", 200)
            .attr("r", 25)


        // another circle object
        var circle3 = svg.append("circle")
            .attr("cx", 100)
            .attr("cy", 300)
            .attr("r", 25)


        setTimeout( function(){
            enter_update_exit(data)
        }, 2500 )


        setTimeout( function(){
            enter_update_exit(data2)
        }, 10000 )

        setTimeout( function(){
            enter_update_exit(data)
        }, 15000 )



        function enter_update_exit (data){



            var circle_array = svg.selectAll("circle")
                .data(data);


            //**********************************************************************************
            // Enter: all pieces of data that do not have a node to bind to. In this case where
            // there are already three circles ('nodes') there would have to be more than 3 
            // data points in our dataset to have enter run at all;
            //**********************************************************************************
            circle_array.enter()
                .append("circle")
                .attr("cx", 100)
                .attr("cy", function(d, i){
                    return (i + 1)*100
                })
                .attr("r", 0)
                .attr("fill", "#78AB46")
                .transition()
                .duration(1500)
                .attr("r", function (d){return d;});
            //**********************************************************************************
            // Update: Every node that is bound to data, in this case that is everything we've
            // entered and everything that has just been bound from the .data(data) bind.
            //**********************************************************************************

            circle_array.transition()
            .duration(1500)
            .delay(1500)
            .style('fill', 'steelblue')
            .attr('r', function (d){
                return d;
            });

            //**********************************************************************************
            // Exit: Every node ('circles') that exists in your selection that you don't have
            // bound data to
            //**********************************************************************************
            circle_array.exit()
            .transition().duration(1500).delay(1500)
            .style("fill", "red")
            .transition().duration(1500).delay(3000)
            .attr("r", 0).transition().remove();
        }

http://jsfiddle.net/TheMcMurder/H3HTe/

我希望有所帮助!