D3水平堆积条形图添加和删除数据

时间:2014-07-21 19:40:55

标签: javascript html5 d3.js

我有一个简单的水平D3堆叠条形图。我使用下拉菜单选择不同的数据集以更新图表值。

如果ds1和ds2具有相同的原点数,即ds1有2个数据点而ds2有2个数据点,则转换是平滑的,我的值会很好地更新。

但是,如果我有两个具有不同数据点数据的数据集,即ds1有3个数据点而ds2只有2个或者可能有4个数据点,我无法使Enter,Update和Exit正常工作。

我认为这与D3堆栈函数有关,它将值转换为不构成D3中更新和退出方法一部分的对象。

非常感谢你能告诉我应该做些什么吗?我的完整代码粘贴在下面。

<!DOCTYPE html>

    <html>
        <head>
            <title>Update horizontal stacked bar chart</title>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width">   
            <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    </head>

    <body>
             <div >
                  <select id="dropdown" onchange="updateData()">

                      <!--need blank value in order to have title in selection-->

                      <option value="ds1">ds1</option>
                      <option value="ds2">ds2</option>
                      <option value="ds3">ds3</option>
                      <option value="ds4">ds4</option>
                  </select>
              </div>        


      <script type="text/javascript">

            var w = 1500,
                    h = 300;

                var rectW = 100 * 5;

                var color = d3.scale.ordinal()
                            .range(["#1459D9", "#daa520","#F7C319"]);


    var ds1 = [[{x:0,y:15}],[{x:0,y:85}]];
    var ds2 = [[{x:0,y:35}],[{x:0,y:65}]];
    var ds3 = [[{x:0,y:10}],[{x:0,y:20}],[{x:0,y:70}]];
    var ds4 = [[{x:0,y:60}]];

        //Set up stack method
        var stack = d3.layout.stack();

        //Data, stacked
        stack(ds1);

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


        var appending = canvas.selectAll("q") 
                .data(ds1)                           
                .enter()                    
                .append("g")
                .style("fill", function(d,i){return color(i);})
        ;


        appending.selectAll("stackrect") 
                .data(function (d){return d;}) 
                .enter()
                .append("rect") 
                .attr("id","recth")
                .attr("x",function (d){return  (w *.50 - (rectW/2)) + d.y0 * 5 ;}) 

                .attr("y",90)
                .attr("width",function (d){return (d.y * 5 );})
                .attr("height",50);       




        function updateData() {

        stack(eval("("+dropdown.value+")")); 

        appending.data(eval("("+dropdown.value+")"));


        //ds1 and ds2 equal number of datum. Update works fine.
        appending.selectAll("#recth") 
                .data(function (d){return d;})
                .transition().duration(600)
                .style("opacity", 0.5)
                .transition().duration(600)
                .style("opacity", 1.0)    
                .attr("x",function (d){return  (w *.50 - (rectW/2)) + d.y0 * 5 ;}) 
                .attr("y",90)
                .attr("width",function (d){return (d.y * 5 );})
                .attr("height",50);

        //update method not working
        appending.selectAll("#recth")
             .data(function (d){return d;})
             .enter()
             .append("rect")
                .transition().duration(600)
                .style("opacity", 0.5)
                .transition().duration(600)
                .style("opacity", 1.0)    
                .attr("x",function (d){return  (w *.50 - (rectW/2)) + d.y0 * 5 ;}) 
                .attr("y",90)
                .attr("width",function (d){return (d.y * 5 );})
                .attr("height",50);               


       //exit method not working
        appending.selectAll("#recth")
        .data(function (d){return d;})     
        .exit()
        .transition().duration(600)
                .style("opacity", 0.5)
                .transition().duration(600)
                .style("opacity", 1.0)    
                .attr("x",function (d){return  (w *.50 - (rectW/2)) + d.y0 * 5 ;}) 
                .attr("y",90)
                .attr("width",function (d){return (d.y * 5 );})
                .attr("height",50)               
        .remove();        
        }

        </script>

    </body>
</html>

1 个答案:

答案 0 :(得分:0)

我没有看完整件事,但是我注意到了一些错误:

1)不要使用ID作为多个事物的选择器。 ID应该是唯一的,如果您有多个具有相同ID的内容,则选择器可能无法正常工作。改为使用类。

2)添加数据时,请确保您添加的内容与您在初始selectAll()方法中使用的选择项相匹配。例如,如果您有.selectAll('.rectClass'),请确保提供您创建类rectClass的所有元素,否则选择器和数据结构可能无法正常工作。

修复后,此示例显示更新/进入/退出模式的工作原理:example