javascript - SVG 圆圈在 d3 中堆积

标签 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; });
}

最佳答案

这是一个没有正确定义“进入”和“更新”选择(以及“退出”,如果有的话)的典型案例。不幸的是,快速浏览一下您的 menuChanged 函数,它在我看来,你必须做很多改变,才能使其成为“D3方式”。此外,你可以将变量部分存储在......好吧,变量!

我做了一个简单的演示来向您展示“输入”和“更新”选择如何工作(我在这里使用 v4)。首先,绑定(bind)数据:

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

“输入”和“更新”选择都依赖于此绑定(bind)数据。

然后,设置“enter”选择(这里,我将其放在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);

最后,选择“更新”。更新选择仅适用于以前存在的元素:

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

这是演示:

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);



}
<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>

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

rT = svg.selectAll("rTcircle")

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

关于javascript - SVG 圆圈在 d3 中堆积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40776273/

相关文章:

javascript - 通过 javascript/html 中的按钮下载图像?

javascript - 如何在 JavaScript 中格式化正则表达式

graphics - 获取字体字形作为矢量,操作和生成 SVG 或位图

css - 核心图标样式错误

javascript - 使用描述对时间戳进行分组

javascript - 使用 JQuery 和 MVC4 上传多个文件

javascript - 无法使用 D3.js 读取外部文件

javascript - 找到位于 ARC 的起始 Angular 和结束 Angular 之间的点。

d3.js - D3 不渲染或绘制 DOM 元素

javascript - 如何在 d3.js 的 Pack Layout 中插入饼图?