常规更新模式无法按预期与d3.selection一起工作 [英] General update pattern not working as expected with d3.selection

查看:92
本文介绍了常规更新模式无法按预期与d3.selection一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑为什么以下简单的更新模式不起作用.据我所知,这遵循推荐的常规更新模式.

I am puzzling over why the following simple update pattern doesn't work. This follows the recommended General Update Pattern , as far as I can see.

    <script src="https://d3js.org/d3-selection.v1.min.js"></script>
...
    var dat = ["One","Two","Buckle my shoe"];
    var sel = d3.selectAll("p.test").data(dat);
    sel.enter().append("p").classed("test", true);
    sel.exit().remove();

    //update 1 ... doesn't work
    sel.text(function(d) { return d;})

可以很好地创建段落,但未设置文本.但是,如果我这样做:

The paragraphs get created fine, but the text isn't set. However, if I do this:

     //update 2 ... this works as expected
     d3.selectAll("p.test").text(function(d) { return d;});

...一切正常.第一个版本过去一直有效.

...everything works fine. The first version has always worked in the past.

更新:我尝试使用完整的d3库...

Update: I tried using the full d3 library ...

<script src="https://d3js.org/d3.v4.min.js"></script>

...,并且第一个版本可以再次使用.我是否需要超过d3.selection?

... and the first version works again. Do I need more than d3.selection?

为澄清起见,我过去的做法是定义一个单独的更新函数,该函数将选择内容作为参数.例如,function doUpdate(sel) { sel.text(...);}这是在以下情况下,我希望数据元素的 size 几乎没有变化,而 content 却有很多变化.将选择存储为变量并在其上反复运行更新的效果很好.

To clarify, my past practice has been to define a separate update function that takes the selection as a parameter. Eg, function doUpdate(sel) { sel.text(...);}This is for cases where I expect the data elements to have few changes in size, but many changes in content. Storing the selection as a variable and repeatedly running updates on it has worked well before.

推荐答案

因此,在研究了发行说明之后,出于某些良好的原因,这似乎不会向后兼容.首先,简短的答案:

So after studying the release notes, it seems this is not going to be backwardly compatible, for some good reasons. First, the short answer:

替换此:

sel.enter().append("p").classed("test", true);
...
sel.text(function(d) { return d;})     //update block

与此:

var update = sel.enter().append("p").classed("test", true).merge(sel);
...
update.text(function(d) { return d;})    //update block

本文(感谢@mbostock),并且针对v3中的空白选择器问题进行了修复.我最初错过的要点是enter()块需要首先运行,以便merge()块具有可填充的选择内容.这意味着merge()调用必须从enter()块链的末尾移出.

The reason for this is described in this article (thanks @mbostock) and is a fix for empty selector problems with v3. The point I missed at first was that the enter() block needs to run first so that the merge() block has a populated selection to work on. Which means that the merge() call must come off the end of the enter() block chain.

变更文档的格式隐藏了这一点,因为许多示例都使用函数调用链.我习惯将输入/更新块拆分为单独的变量. (通常)这有助于提高可读性,这意味着我可以将enter/update操作分配给单独的功能-这样可以重用更多代码.

The format of the change documents sort of hid that, because many examples use chains of function calls. I'm used to splitting the enter/update blocks into separate variables. This aids readability (usually) and means I can farm out the enter/update actions to separate functions - more reusable code that way.

因此,请记住,此无效:

var enter = sel.enter();
var update = enter.merge(sel); //Nope! Not populated at this point.
enter.append(...);             //too late! Update block uses an empty selection.

但这行得通

var enter = sel.enter();
enter.append(...);
var update = enter.merge(sel);  //defined after block is populated

这篇关于常规更新模式无法按预期与d3.selection一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆