d3.js无法更新图表 - 使用json数据

时间:2013-08-20 16:26:28

标签: d3.js

我一直试图让更新图表功能正常工作......我做错了什么?

我已经创建了一个构建图表的功能。

然后更改输入框后更新功能 - 所以如果用户更改数据然后点击更新。

我无法尝试访问现有的饼图并使用正确的数据对其进行更新/动画处理。

$.Core.doughnutCommon ={
    init: function(){
        var that = this;

        var colourtheme = {
            "spectrum" :  ["#e87424", "#ebb700", "#007c92"]
        };

        $('[data-doughnut-pie-common="true"]').each(function(index) {
            that.bindInputEvents($(this));
            var holder = $(this)[0];
            var data = that.generateData(holder);

            console.log("data", data);      
            var theme = $(this).data("theme");
            var colours = colourtheme[theme];
            var radius = 64;    
            that.buildchart(holder, index, data, colours, radius);          
        });
    },
    bindInputEvents: function(holder){
        var that = this;
        holder.find('.updatechart').click(function(e) {
            e.preventDefault();
            that.updatechart(holder);
        });

        holder.find('.dataset li input').keyup(function() {
            $(this).parent().parent().find('.value').text($(this).val());
        });         
    },
    generateData: function(holder){
        var that = this;

        var json = new Array();

        var keysObj = {};
        var legendsarray = new Array();

                $(holder).find('.dataset li').each(function(index) {

                      var key = $(this).find('.key').text();
                      var value = $(this).find('.value').text();

                        //__key obj
                        var localKeyObj = {};
                        localKeyObj[key] = "";                

                        //__legend array build
                        var stream = {
                            "name" : key,
                            "population" : value
                        }

                      jQuery.extend(keysObj, localKeyObj);

                      legendsarray.push(stream);      
                });     

                var obj ={
                    "legends": legendsarray
                };

                jQuery.extend(obj, keysObj);

                json.push(obj);     
                return json;
    },
    updatechart: function(holder){
        var that = this;

        console.log("holder", holder);

        var data = that.generateData(holder);
        console.log("data hold", data);

        var pieId = holder.find(".pie").attr("id");


        //draw arc paths
        //var svg = d3.select('#'+pieId);

        var arc_group = d3.select('#'+pieId+' .sliceholder');



        var color = d3.scale.ordinal();

        var arc = d3.svg.arc()
            .outerRadius(64)
            .innerRadius(64 - 20);      

        paths = arc_group.selectAll("path").data(data[0].legends);


        paths.enter().append("svg:path")
            .attr("class", "arc")
            .attr("d", arc)
            .style("fill", function(d) { 

                console.log("d", d);
                return color(d.name); 

            })
            .transition()
            .duration(500);
            //.attrTween("d", arcTween);

        paths
            .transition()
            .duration(500);
            //.attrTween("d", arcTween);

        paths.exit()
            .transition()
            .duration(500)
            //.attrTween("d", arcTween);
            .remove();




        function arcTween(d) {
          var i = d3.interpolate(this._current, d);
          this._current = i(0);
          return function(t) { return arc(i(t)); };
        }


    },
    buildchart: function(holder, index, data, colours, radius){
        var padding = 10;

        var color = d3.scale.ordinal()
            .range(colours);

        var arc = d3.svg.arc()
            .outerRadius(radius)
            .innerRadius(radius - 20);

        var pie = d3.layout.pie()
            .sort(null)
            .value(function(d) { return d.population; });


        color.domain(
            d3.keys(data[0]).filter(function(key) {
                return key !== "legends"; 
            })
        );      

        var svg = d3.select(holder).selectAll(".pie")
            .data(data)
            .enter().append("svg")
            .attr("class", "pie")
            .attr("id", "pie"+index)
            .attr("width", radius * 2)
            .attr("height", radius * 2)
            .append("g")
            .attr("class", "sliceholder")
            .attr("transform", "translate(" + radius + "," + radius + ")");

        svg.selectAll(".arc")
            .data(function(d) { return pie(d.legends); })
            .enter().append("path")
            .attr("class", "arc")
            .attr("d", arc)
            .style("fill", function(d) { return color(d.data.name); });

        var legend = d3.select(holder).append("svg")
            .attr("class", "legend")
            .attr("width", radius * 1.7)
            .attr("height", radius * 2)
            .selectAll("g")
            .data(color.domain().slice().reverse())
            .enter().append("g")
            .attr("transform", function(d, i) { return "translate(0," + i * 25 + ")"; });

        legend.append("rect")
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", color);

        legend.append("text")
            .attr("x", 24)
            .attr("y", 9)
            .attr("dy", ".35em")
            .text(function(d) { return d; });   

        var totalUnits = svg.append("svg:text")
            .attr("class", "units")
            .attr("dy", 5)
            .attr("text-anchor", "middle") // text-align: right
            .text("Chart title");
    }
};

html如下

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>   
<script type="text/javascript" src="d3.v3.min.js"></script>

<script>
    $.Core ={
                init: function(){
                    console.log("test");
                    $.Core.doughnutCommon.init();//iniate doughnut read only
                }
            };
</script>           
<script type="text/javascript" src="doughnut.common.js"></script>   

<script>            
    $(document).ready(function() {
        $.Core.init();
    });
</script>

<div class="doughnut_pie common" data-doughnut-pie-common="true" data-theme="spectrum">
    <form>
        <ul class="dataset">
            <li>
                <span class="key">Equities</span>
                <span class="value">50</span>
                <span class="varbox"><input type="text" value="50"></span>
            </li>
            <li>
                <span class="key">Bonds</span>
                <span class="value">30</span>
                <span class="varbox"><input type="text" value="30"></span>
            </li>
            <li>
                <span class="key">Gilts</span>
                <span class="value">20</span>
                <span class="varbox"><input type="text" value="20"></span>
            </li>
        </ul>

        <button class="updatechart">UPDATE</button>
    </form>
</div>

1 个答案:

答案 0 :(得分:0)

您的代码存在一些问题。首先,选择器

var arc_group = d3.select('#'+pieId+' .sliceholder');

不起作用,因为具有类g的{​​{1}}元素是SVG的子元素。你需要

sliceholder

其次,在更新时无法传递原始数据,您需要先使用饼图布局处理它。也就是说,

var arc_group = d3.select('#'+pieId+' > .sliceholder');

不起作用,你需要

paths = arc_group.selectAll("path").data(data[0].legends);

第三,在复制var pie = d3.layout.pie() .sort(null) .value(function(d) { return d.population; }); paths = arc_group.selectAll("path").data(pie(data[0].legends)); 代码时,您错过了一些初始化。您需要设置arcTween的初始值:

._current

工作jsfiddle here