【问题标题】:Need another help to show up text on the screen dynamically需要其他帮助才能在屏幕上动态显示文本
【发布时间】:2017-04-15 08:38:18
【问题描述】:

现在我使用 d3.js 解决了我自己无法解决的第二个问题。我有一个动态数组“路径”,当我点击它时,它的长度总是会改变。然后我在 svg (112, 490) 的起始位置得到了一个“文本”变量。 在你们的帮助下,我现在使用 for 循环根据控制台上的切换长度显示“路径”数组的名称,并且它有效。但现在我希望名字出现在屏幕上。但是我的

 textNode.attr("dx", 112 + i*2);

行不工作。我希望每个节点从点 112 开始,文本在 x 刻度上向右移动一点。

这是正文

var text = svg.append("text")
.attr("dx", 112)
.attr("dy", 490)
.text("1. Node: " )

这是for循环

for (var i=0;i<path.length;i++) {
text.attr("dx", 112 + i*2);
text.text( +i+1+". Node: " + path[i].name);

【问题讨论】:

    标签: javascript arrays for-loop d3.js


    【解决方案1】:

    D3 中的一个非常基本的原则:不要使用循环,例如 for 循环来显示或显示数据(有时我们确实使用循环,但非常具体和复杂情况,不是这个)。在您的另一个问题中,建议的解决方案使用循环,因为问题中没有 d3.js 标记。但是,如果您使用的是 D3,那么使用这样的循环就没有什么意义了。它是为操作数据而创建的整个库,而您忽略了它最重要的方面。

    取而代之的是,绑定您的数据到一个选择。在您的情况下,由于您的数组不断变化,您将需要“进入”、“更新”和“退出”选择。

    首先,绑定你的数据:

    var texts = svg.selectAll(".texts")
        .data(data);
    

    然后,设置选择:

    textsExit = texts.exit().remove();
    
    textsEnter = texts.enter()
        .append("text")
        .attr("class", "texts");
    
    textsUpdate = texts.merge(textsEnter)
        .attr("x", 10)
        .attr("y", (d, i) => i * 16)
        .text(d => d.name);
    

    这是一个演示,向您展示它是如何工作的。我有一个数据数组,它的长度每秒都在变化:

    var svg = d3.select("body").append("svg");
    
    var dataset = [{
        name: "foo"
    }, {
        name: "bar"
    }, {
        name: "baz"
    }, {
        name: "lorem"
    }, {
        name: "ipsum"
    }, {
        name: "dolot"
    }, {
        name: "amet"
    }];
    
    print(dataset);
    
    setInterval(()=> {
        var data = dataset.slice(Math.random() * 6);
        print(data);
    }, 1000);
    
    function print(data) {
    
        var texts = svg.selectAll(".texts")
            .data(data);
    
        textsExit = texts.exit().remove();
    
        textsEnter = texts.enter()
            .append("text")
            .attr("class", "texts");
    
        textsUpdate = texts.merge(textsEnter).attr("x", 10)
            .attr("y", (d, i) => 20 + i * 16)
            .text((d,i) => "Node " + (i+1) + ", name: " + d.name);
    
    }
    &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 哇,这真的很有帮助!!非常感谢你们两个!! @sam:看起来你也不知道在 d3.js 中使用循环不好? :)
    • 完全忘记了,Gerado 好!这应该是答案。是的,我自己使用过 selectAll 和 Bind,但完全忘记了 d3js 的那一部分。
    【解决方案2】:

    不确定这对于您的特定用例是否不正确,但我认为您想使用“x”而不是“dx”。这就是我在 d3.js 中将对象向左/向右移动的方式:

    textNode.attr("x", 112 + i*2);
    

    编辑:这是一个添加文本对象并根据索引将它们向右移动的示例:

    for (var i = 0; i < path.length; i++) {
        var text = svg.append("text")
            .attr("x", 112 + i*2)
            .attr("y", 490)
            .text("1. Node: " )
    }
    

    EDIT2:见 Gerardo 的回答。 D3js 有自己的绑定和循环数据的方法。

    【讨论】:

    • 嘿山姆,我认为你是对的,但我的计划是不移动对象。我想根据数组的长度创建新的文本对象。
    • 这个可以,你只需要追加,然后修改x属性: var text = svg.append("text").attr("x", 112);你可以把它放在你的 for 循环中,这样它就会创建新对象并将它们向右移动。如果需要,只需添加“+ i*2”即可。
    • 谢谢山姆。您能解释一下如何将其放入循环中吗?计数器怎么用对吗?
    • 我编辑了我的答案,展示了如何将元素添加和向右移动。
    • 你的意思是直接粘贴到循环中? for (var i=0;i
    猜你喜欢
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多