javascript - d3 : How to append nested elements on enter()? 我的元素被附加,但后续的选择看不到它们

标签 javascript d3.js

示例 fiddle :https://jsfiddle.net/tomaskafka/w1acm8ox/

这是我的更新循环:

var output = d3.select('#output')
    .selectAll('p')
    .data(data)
    ;

output
    .enter()
        .append('p')
        .call(function(parent) {
            parent.append('a')
        });
        ;

output
    .exit()
        .remove()
    ;

// PROBLEM: at this point, element addded right now isn't selected, and so it's attr and text isn't set.
output
    .select('a')
        .attr('href', function(d) { return 'http://www.google.com?q=' + d; })
        .text(function(d) { return d; })
    ;

你能帮忙吗?我知道由于某些优化,d3 不会立即更新 DOM,那么添加嵌套元素并在更新时设置其属性的正确方法是什么?

谢谢!

最佳答案

您没有正确使用更新、进入、退出模式。

您输入的选择已附加:

output
    .enter()
        .append('p')
        .call(function(parent) {
            parent.append('a')
        });

但是,你会在这里遇到问题:

output
    .select('a')
        .attr('href', function(d) { return 'http://www.google.com?q=' + d; })
        .text(function(d) { return d; })
    ;

只有创建选择时存在的元素才会更新。因此,您新创建的元素(输入选择的一部分)不受影响。这是更新选择,与输入选择互斥 - 这与 v3 中不同,需要使用合并方法将更新选择与输入选择合并

这就是为什么您必须使用超时 - 第一次运行更新函数时会附加功能,第二次则更新它们。

尝试:

output
  .enter()
    .append('p')
    .call(function(parent) { parent.append('a') })
  .merge(output).select('a')
    .attr('href', function(d) { return 'http://www.google.com?q=' + d; })
    .text(function(d) { return d; });

输入选择将导致附加 p,然后我们合并输入和更新选择,以便使用特定文本更新所有元素。现在您可以删除超时功能,并且在移动 slider 时,更新应该正确显示。

以下是更新的片段:

var items = [1,2,3,4,5,6,7,8,9,10,11,12,13]

var slider = d3.select('#slider')
	.attr('min', 0)
	.attr('max', items.length)
	.attr('value', items.length - 1)
	.attr('step', 1)
	.attr('disabled', null) // enable
	;

function update(data) {
	var output = d3.select('#output')
		.selectAll('p')
		.data(data)
		;

	output
		.enter()
			.append('p')
			.call(function(parent) {
				parent.append('a')
			})
      .merge(output).select('a')
			.attr('href', function(d) { return 'http://www.google.com?q=' + d; })
			.text(function(d) { return d; });
			;

	output
		.exit()
			.remove()
		;
}
update(['a', 'b', 'c']);

slider.on('input', function() {
	var val = +this.value;
	var newData = items.slice(0, val);

	update(newData);
});
body {
		font-family: sans-serif;
	}

	p {
		outline: 1px red solid;
	}
	a {
		display: inline-block;
		outline: 1px blue solid;
		min-width: 1em;
		min-height: 1em;
	}

	.small {
		font-size: 66%;
	}

	#slider {
		width: 100%;
	}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
<div id="wrap">
	<input type="range" id="slider" disabled="disabled" />
	<div class="small" id="output">static content</div>
</div>

关于javascript - d3 : How to append nested elements on enter()? 我的元素被附加,但后续的选择看不到它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44637594/

相关文章:

javascript通过从另一个集合中查找来更新mongodb记录多个字段

javascript - 在 D3.js 中使用时间刻度时,x(i) 返回错误值

d3.js - D3 轴中的离群值(混合数值和分类规范)

javascript - scaleTime() 上的刻度线不起作用

javascript - 未捕获的 TypeError : $(. ..).steps 不是函数

javascript - 将 Extjs 与 HAL 集成

javascript - D3 中的嵌套缩放问题

javascript - 如何垂直分离Material UI Gridded Paper组件?

javascript - 如何克隆 dom 的元素或 block ?

css - 我可以使用带背景色的 SVG 图案吗?