D3js退出()并更新工作,无法输入()

时间:2015-06-07 14:51:46

标签: javascript d3.js

我有D3的散点图,我正在尝试根据更改的数据为选区添加圆圈。我将数据选择传递给两个函数:renderupdaterender函数是初始呈现,update具有enter()exit()方法。我可以轻松添加初始数据集,并使数据集中的圆圈不再退出。我使用d.id作为d3占位符。

问题:当我尝试enter()添加的数据点时,没有任何反应。我检查了新数据选择的长度,它比预先存在的大。在DOM上,较小的数据集仍然存在(已存在的circle),但即使数据集已更改,也不会输入新的圆圈。

我查看过很多关于数据连接的教程,我认为我已经适当调用了enter()exit()方法。是什么给了什么?

这是我的代码:

            var container = angular.element(document.querySelector('.chart-container'))[0];
            var margin = {
                    top: container.clientHeight / 12, 
                    right: container.clientWidth / 14, 
                    bottom: container.clientHeight / 10, 
                    left: container.clientWidth / 11
                };
            var w = container.clientWidth - margin.left - margin.right;
            var h = container.clientHeight - margin.top - margin.bottom;

            // ******** **************** ******** //  
            // ******** INITIAL RENDER ******** //
            function render(input) {

                console.log(Object.keys(input).length);

                var xScale = d3.scale.linear()
                    .domain([0, d3.max(input, function(d) { return d["ctc"]; })])
                    .range([0, w])
                    .nice();

                var yScale = d3.scale.linear()
                    .domain([0, d3.max(input, function(d) { return d["ttc"]; })])
                    .range([h, 0])
                    .nice();

                var rScale = d3.scale.linear()
                    .domain([0, d3.max(input, function(d) { return d["effective"]; })])
                    .range([2, 15]);

                // *********** //
                // SVG ELEMENT //  
                var svg = d3.select('.chart-container')
                    .append('svg')
                    .attr('class', 'scatter')
                    .attr('viewBox', '0, 0, ' + Math.round(w + margin.left + margin.right) + ', ' + Math.round(h + margin.top + margin.bottom))
                    .attr('preserveAspectRatio', 'xMinYMin')
                    // used to center element and make use of margins
                    .append('g')
                    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

                // add circles in group
                var circles = svg.append('g')
                    .attr('class','circles')
                    .attr('clip-path','url(#chart-area)');

                // add individual circles
                var circle = circles.selectAll('circle')
                    .data(input, function(d) {return d.id;})
                    .enter()
                    .append('circle')
                    .attr('class', 'circle')
                    .attr('cx', function(d) { return xScale(d["ctc"]); })
                    .attr('cy', function(d) { return yScale(d["ttc"]); })
                    .attr('r', function(d) { return rScale(d["effective"]); })
                    .attr('fill', function(d, i) { return d["effective"]; })
                    .on('mouseover', function(d) {
                        tooltip.style('visibility', 'visible');
                        return tooltip.text(d["technology"]);
                     })
                    .on("mousemove", function(){ return tooltip.style("top",
                        (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
                    .on("mouseout", function(){return tooltip.style("visibility", "hidden");})


                // append clip path
                svg.append('clipPath')
                    .attr('id','chart-area')
                    .append('rect')
                    .attr('class', 'rect')
                    .attr('x', 0)
                    .attr('y', 0)
                    .attr('width', w)
                    .attr('height', h);

            };

            // ******** **************** ******** //  
            // ******** UPDATE ******** //
            function update(updateObject) {

                var input = updateObject;

                var xScale = d3.scale.linear()
                    .domain([0, d3.max(input, function(d) { return d["ctc"]; })])
                    .range([0, w])
                    .nice();

                var yScale = d3.scale.linear()
                    .domain([0, d3.max(input, function(d) { return d["ttc"]; })])
                    .range([h, 0])
                    .nice();

                var rScale = d3.scale.linear()
                    .domain([0, d3.max(input, function(d) { return d["effective"]; })])
                    .range([2, 15]);

                var svg = d3.select('svg')
                    .data(input)
                    .attr('viewBox', '0, 0, ' + Math.round(w + margin.left + margin.right) + ', ' + Math.round(h + margin.top + margin.bottom))
                    .attr('preserveAspectRatio', 'xMinYMin')
                    .append('g')
                    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

                // BIND TO DATA
                var circles = d3.selectAll('circle')
                    .data(input, function(d) { return d.id; });

                // Circles Enter
                circles.enter()
                    .insert('svg:circle')
                    .attr('class', 'circle')
                    .attr('cx', function(d) { return xScale(d["ctc"]); })
                    .attr('cy', function(d) { return yScale(d["ttc"]); })
                    .attr('r', function(d) { return rScale(d["effective"]); });
                    /*
                    .on('mouseover', function(d) {
                        tooltip.style('visibility', 'visible');
                        return tooltip.text(d["technology"]);
                     })

                    .on("mousemove", function(){ return tooltip.style("top",
                        (d3.event.pageY-10)+"px").style("left",(d3.event.pageX+10)+"px");})
                    .on("mouseout", function(){return tooltip.style("visibility", "hidden");})
                    */

                // UPDATE
                circles.transition()
                    .duration(1000)
                    .attr('cx', function(d) { return xScale(d["ctc"]); })
                    .attr('cy', function(d) { return yScale(d["ttc"]); })
                    .attr('r', function(d) { return rScale(d["effective"]); });


                // EXIT
                circles.exit()
                    .transition()
                    .duration(500)
                    .attr('r', 0)
                    .style('opacity', 0)
                    .style('fill', 'gray')
                    .remove();      

            }

更新 这是一个用于测试的codepen:http://codepen.io/himmel/pen/JdNJMM

1 个答案:

答案 0 :(得分:1)

代码的问题是,您正在尝试将对象用作数据。 d3.selection.data()采用数组,而不是对象。有关data()功能的详细信息,请参阅the d3 wiki

我已经为您的codepen创建了updated版本。我将数据更改为数组并应用了正确的conventional margin。此外,我通过删除scale和svg元素的双重初始化来简化代码。