SVG圈子在d3中堆积

时间:2016-11-24 00:20:37

标签: javascript d3.js svg geometry

我正在编写一个d3程序,该程序从csv文件读取NFL团队的统计数据,用户从下拉菜单中选择要查看的团队。然后,该程序在该团队的统计数据的攻击和防御形成中创建圈子并显示它。到目前为止,我的程序能够显示其中的一些,但是当我选择另一个团队时,旧的圆圈会留在屏幕上,而新的圆圈会被添加到顶部。我的问题是如何解决这个问题?我尝试在下面的函数末尾添加删除,但它只是完全删除了那个圆

function menuChanged() 
{
var selectedValue = d3.event.target.value;
var picked;

for(var i = 0; i < 32; i++)
    if(nest[i].key == selectedValue)
        picked = i;

rT = svg.selectAll("rTcircle")
            .data(nest)
            .enter().append("circle")
            .attr("class", "dot")
            .attr("r", function() { return Math.sqrt(nest[picked].values[0].rushing) * 0.7; })
            .attr("cx", 40)
            .attr("cy", 300)
            .style("fill", function () { return nest[picked].values[0].color1; })
            .style("stroke", function () { return nest[picked].values[0].color2; });
rG = svg.selectAll("rGcircle")
            .data(nest)
            .enter().append("circle")
            .attr("class", "rGdot")
            .attr("r", function() { return Math.sqrt(nest[picked].values[0].rushing) * 0.7; })
            .attr("cx", 190)
            .attr("cy", 300)
            .style("fill", function () { return nest[picked].values[0].color1; })
            .style("stroke", function () { return nest[picked].values[0].color2; });
cO = svg.selectAll("oCcircle")
            .data(nest)
            .enter().append("circle")
            .attr("class", "oCdot")
            .attr("r", function() { return Math.sqrt(nest[picked].values[0].rushing) * 0.7; })
            .attr("cx", 340)
            .attr("cy", 300)
            .style("fill", function () { return nest[picked].values[0].color1; })
            .style("stroke", function () { return nest[picked].values[0].color2; });
lG = svg.selectAll("lGcircle")
            .data(nest)
            .enter().append("circle")
            .attr("class", "lGdot")
            .attr("r", function() { return Math.sqrt(nest[picked].values[0].rushing) * 0.7; })
            .attr("cx", 490)
            .attr("cy", 300)
            .style("fill", function () { return nest[picked].values[0].color1; })
            .style("stroke", function () { return nest[picked].values[0].color2; });
lT = svg.selectAll("lTcircle")
            .data(nest)
            .enter().append("circle")
            .attr("class", "lTdot")
            .attr("r", function() { return Math.sqrt(nest[picked].values[0].rushing) * 0.7; })
            .attr("cx", 640)
            .attr("cy", 300)
            .style("fill", function () { return nest[picked].values[0].color1; })
            .style("stroke", function () { return nest[picked].values[0].color2; });

var oLineT = svg.selectAll(".text")
            .data(nest)
            .enter().append("text")
            .attr("class","text")
            .style("text-anchor", "middle")
            .attr("x", 40)
            .attr("y", 300)
            .style("fill", function() { return nest[picked].values[0].color1; })
            .style("stroke", function() { return nest[picked].values[0].color2; })
            .style("font-family", "verdana")
            .style("stroke-width", 0.7)
            .text(function () {return nest[picked].values[0].team; });

rT.data(nest).transition()
    .duration(500)
    .attr("class", "dot")
    .attr("r", function() { return Math.sqrt(nest[picked].values[0].passing) * 0.7; })
    .attr("cx", 40)
    .attr("cy", 300)
    .style("fill", function () { return nest[picked].values[0].color1; })
    .style("stroke", function () { return nest[picked].values[0].color2; });
rG.data(nest).transition()
    .duration(500)
    .attr("class", "rGdot")
    .attr("r", function() { return Math.sqrt(nest[picked].values[0].passing) * 0.7; })
    .attr("cx", 190)
    .attr("cy", 300)
    .style("fill", function () { return nest[picked].values[0].color1; })
    .style("stroke", function () { return nest[picked].values[0].color2; });
cO.data(nest).transition()
    .duration(500)
    .attr("class", "oCdot")
    .attr("r", function() { return Math.sqrt(nest[picked].values[0].passing) * 0.7; })
    .attr("cx", 340)
    .attr("cy", 300)
    .style("fill", function () { return nest[picked].values[0].color1; })
    .style("stroke", function () { return nest[picked].values[0].color2; });
lG.data(nest).transition()
    .duration(500)
    .attr("class", "lGdot")
    .attr("r", function() { return Math.sqrt(nest[picked].values[0].passing) * 0.7; })
    .attr("cx", 490)
    .attr("cy", 300)
    .style("fill", function () { return nest[picked].values[0].color1; })
    .style("stroke", function () { return nest[picked].values[0].color2; });
lT.data(nest).transition()
    .duration(500)
    .attr("class", "lTdot")
    .attr("r", function() { return Math.sqrt(nest[picked].values[0].passing) * 0.7; })
    .attr("cx", 640)
    .attr("cy", 300)
    .style("fill", function () { return nest[picked].values[0].color1; })
    .style("stroke", function () { return nest[picked].values[0].color2; });

oLineT.data(nest).transition()
    .duration(500)
    .attr("class","text")
    .style("text-anchor", "middle")
    .attr("x", 40)
    .attr("y", 300)
    .style("fill", function() { return nest[picked].values[0].color1; })
    .style("stroke", function() { return nest[picked].values[0].color2; })
    .style("font-family", "verdana")
    .style("stroke-width", 0.7)
    .text(function () {return nest[picked].values[0].team; });
}

1 个答案:

答案 0 :(得分:1)

这是一个经典案例,没有正确定义&#34;输入&#34;并且&#39;更新&#34;选择(&#34;退出&#34;,如果有的话)。不幸的是,只是快速浏览你的menuChanged功能,在我看来你必须做很多改动,才能使它成为&#34; D3方式&#34;。此外,您可以将变量部分存储在......好吧,变量!

我做了一个简单的演示,向您展示&#34;进入&#34;并且&#34;更新&#34;选择工作(我在这里使用v4)。首先,绑定数据:

var circles = svg.selectAll(".teamCircles")
    .data(data[0][team].positions);

两者&#34;进入&#34;和&#34;更新&#34;选择依赖于这个绑定数据。

然后,设置&#34;输入&#34;选择(在这里,我把它放在menuChanged函数中,但是如果玩家的数量永远不会改变,那么它可以在函数之外):

circlesEnter = circles.enter()
    .append("circle")
    .attr("class", "teamCircles")
    .attr("cx", d => d.x)
    .attr("cy", d => d.y)
    .attr("r", 8)
    .attr("fill", data[0][team].color);

最后,&#34;更新&#34;选择。更新选择仅适用于以前存在的元素:

circlesUpdate = circles.transition()
    .duration(1000)
    .attr("cx", d => d.x)
    .attr("cy", d => d.y)
    .attr("r", 8)
    .attr("fill", data[0][team].color);

以下是演示:

&#13;
&#13;
var w = 500,
    h = 300;

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

var data = [{
    "San Francisco 49": {
        color: "red",
        positions: [{
            x: 110,
            y: 50
        }, {
            x: 35,
            y: 56
        }, {
            x: 230,
            y: 200
        }, {
            x: 431,
            y: 50
        }, {
            x: 310,
            y: 250
        }]
    },
    "Green Bay Packers": {
        color: "green",
        positions: [{
            x: 360,
            y: 120
        }, {
            x: 51,
            y: 156
        }, {
            x: 30,
            y: 60
        }, {
            x: 130,
            y: 210
        }, {
            x: 410,
            y: 250
        }]
    },
    "Baltimore Ravens": {
        color: "purple",
        positions: [{
            x: 200,
            y: 200
        }, {
            x: 34,
            y: 236
        }, {
            x: 390,
            y: 98
        }, {
            x: 330,
            y: 66
        }, {
            x: 10,
            y: 210
        }]
    }
}];

d3.select("#selection").on("change", menuChanged);

function menuChanged() {
    var team = this.value;
    var circles = svg.selectAll(".teamCircles")
        .data(data[0][team].positions);

    circlesEnter = circles.enter()
        .append("circle")
        .attr("class", "teamCircles")
        .attr("cx", d => d.x)
        .attr("cy", d => d.y)
        .attr("r", 8)
        .attr("fill", data[0][team].color);

    circlesUpdate = circles.transition()
        .duration(1000)
        .attr("class", "teamCircles")
        .attr("cx", d => d.x)
        .attr("cy", d => d.y)
        .attr("r", 8)
        .attr("fill", data[0][team].color);



}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<select name="select" id="selection">
	<option value="">Select</option>
	<option value="San Francisco 49">San Francisco 49</option>
	<option value="Green Bay Packers">Green Bay Packers</option>
	<option value="Baltimore Ravens">Baltimore Ravens</option>
</select>
<div id="svg"></div>
&#13;
&#13;
&#13;

PS :顺便说一句,您的圈子堆积的原因是因为在您的输入选择中您选择了不存在的内容。例如:

rT = svg.selectAll("rTcircle")

rTcircle不存在,因此您的输入选择永远不会为空。