我想用以下代码绘制一些带阴影的单词:
function myText(g, data)
{
const update = g.selectAll('g').data(data, d => d.id);
const enter = update.enter().append('g');
// bottom element
enter.append('text')
.text(d => d.text)
.attr('fill', 'grey')
.attr('x', (d, i) => 40 * i + 100)
.attr('y', 100);
// top element
enter.append('text')
.text(d => d.text)
.attr('fill', 'red')
.attr('x', (d, i) => 40 * i + 99)
.attr('y', 99);
const all = update.merge(enter);
all.select('text').text(d => d.text);
const exit = update.exit();
exit.remove();
}
const g = d3.select( ... ) // some level in scene
.append('g');
const d1 =
[
{ id: 1, text: 'a' },
{ id: 2, text: 'b' },
{ id: 3, text: 'c' }
];
const d2 =
[
{ id: 1, text: 'one' },
{ id: 2, text: 'two' },
{ id: 5, text: 'five' }
];
myText(g, d1);
myText(g, d2);
myText
的逻辑来自Mike Bostock的Block "General Update Pattern, II"。
然后我得到了这些元素:
g
|
|- g
| |- text 'one'
| |- text 'a' <- not updated, expecting 'one'
|
|- g
| |- text 'two'
| |- text 'b' <- not updated, expecting 'two'
|
|- g
|- text 'five'
|- text 'five'
我已经尝试了#34; selectAll in each&#34;等也不起作用。
答案 0 :(得分:0)
尝试更新文本时,实际上永远不会更新绑定到它们的任何数据。相反,您正在更新绑定到父组的数据,这些数据工作正常,但从未传播到其现有的子元素。
在found新元素(强调我的)时,数据的传播有效:
每个新元素都会继承当前元素的数据
但是,在执行简单的<g>
或appending时,数据不会被子元素继承:
所选元素不会从此选择中继承数据;使用selection.data将数据传播给子节点。
当您尝试为更新选择设置文本时,会发生这种情况,即所选文本仍然绑定了旧数据。另一方面,不需要将相同的数据绑定到文本及其阴影文本;您也可以为此目的访问父all.selectAll('text')
.text(function() {
return d3.select(this.parentNode).datum().text;
});
数据:
function myText(g, data)
{
const update = g.selectAll('g').data(data, d => d.id);
const enter = update.enter().append('g');
// bottom element
enter.append('text')
// .text(d => d.text)
.attr('fill', 'grey')
.attr('x', (d, i) => 40 * i + 100)
.attr('y', 100);
// top element
enter.append('text')
// .text(d => d.text)
.attr('fill', 'red')
.attr('x', (d, i) => 40 * i + 99)
.attr('y', 99);
const all = update.merge(enter);
all.selectAll('text')
.text(function() {
return d3.select(this.parentNode).datum().text;
});
const exit = update.exit();
exit.remove();
}
const g = d3.select("body")
.append("svg")
.append('g');
const d1 =
[
{ id: 1, text: 'a' },
{ id: 2, text: 'b' },
{ id: 3, text: 'c' }
];
const d2 =
[
{ id: 1, text: 'one' },
{ id: 2, text: 'two' },
{ id: 5, text: 'five' }
];
myText(g, d1);
myText(g, d2);
看看这个有用的演示:
<script src="https://d3js.org/d3.v4.js"></script>
<div class="row-fluid custom-row-margin-10">
<div class="span12">
<ul class="unstyled inline">
<li class="filter-title">{{'FILTER_BY' | translate}}</li>
<li>
<button type="button" class="btn btn-large btn-filter" data-toggle="modal" data-target="#filter-boat-type">
{{'BOAT_TYPE' | translate}}
</button>
</li>
<li>
<button type="button" class="btn btn-large" ng-class="{'btn-filter': !filters.lengthMin && !filters.lengthMax, 'btn-filter-selected': filters.lengthMin || filters.lengthMax}" data-toggle="modal" data-target="#filter-length">
<span ng-hide="filters.lengthMin || filters.lengthMax">{{'LENGTH' | translate}}</span>
<span ng-show="filters.lengthMin || filters.lengthMax">{{'FROM_2' | translate}} {{filters.lengthMin}}m. {{'TO_2' | translate}} {{filters.lengthMax}}m.</span>
</button>
</li>
</ul>
...
<!-- MODAL TYPE -->
<div id="filter-boat-type" class="modal hide fade filters-wrapper">
<div class="row-fluid boat-filters custom-row-margin-10">
<div class="span12">
Modal content
</div>
</div>
</div>