虽然相对位置逻辑,选择和翻译听起来像乍看之下的单独问题,但在我的特定情况下,您将看到它们是如何相互关联的。
建立我的dynamic button appending project,我现在想要制作transition()
效果,您可以按任意顺序追加内容,按任意顺序删除它们,如果从顶部删除了某些内容,则元素将优雅地向上滑动到顶部以填充空白空间。我只是半功能,问题是我找不到正确的逻辑来只选择当前按钮事件下面的文本。
跳过逻辑,我只需使用selectAll('text')
就可以成功地使用转换。这只适用于你有两个项目,一旦你附加了3件事情就会变得混乱,因为它没有正确的逻辑来辨别要转换的东西。
另一个翻译问题与按钮移动有关。文本转换正常,但无论使用.attr('top', new_value)
还是.attr('transform', 'translate(' + 0+','+new_value+')')
转到带有评论的live example,然后从下拉菜单中选择内容,点击删除最上面的内容,您就会看到我的意思。
总结一下:
如何对任何大于当前最远距离的文本进行if ()
逻辑检查? (即如果页面上的文字元素低于当前的文本元素)
如何告诉D3只选择相对位置较大的文本(垂直方向,即页面下方)
如何让D3翻译或更新按钮的top
?请注意,我使用的是selectAll('button')
示例,但理想情况下我需要更明智的选择。
答案 0 :(得分:2)
您应该使用数据绑定来实现此目的,请参阅我的代码中的render()
函数。
var margins = {
top: 200,
right: 80,
bottom: 30,
left: 50
};
var width = 500;
var height = 200;
var itemHeight = 30;
var totalWidth = width + margins.left + margins.right;
var totalHeight = height + margins.top + margins.bottom;
var y = d3.scaleOrdinal();
var options = [
'Add Text',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
];
d3.select('#choose')
.on('change', addText)
.selectAll('option')
.data(options)
.enter().append('option')
.attr('value', function(d) {
return d;
})
.text(function(d) {
return d;
});
var svg = d3.select('body')
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var graphGroup = svg.append('g')
.attr('transform', 'translate(' + margins.left + ',' + margins.top + ')');
svg.append('text')
.text('Mix and Match Text')
.attr('font-weight', 'bold')
.attr('x', 15)
.attr('y', 60)
.attr('font-size', '24px');
var count = 0;
var intCount = 0;
var textItems = [];
function addText() {
var chooseSel = document.getElementById('choose');
var choice = chooseSel.options[chooseSel.selectedIndex].value;
textItems.push(choice);
render();
}
function removeItem(item) {
textItems.splice(textItems.indexOf(item), 1);
render()
}
function render() {
y.range(textItems.map((item, i) => i * itemHeight + 10)).domain(textItems);
var items = graphGroup.selectAll('.item').data(textItems, d => d);
var enteringItems = items.enter()
.append('g')
.attr('class', 'item')
.attr('opacity', 0)
items.merge(enteringItems)
.transition()
.attr('opacity', 1)
.attr('transform', d => `translate(0, ${y(d)})`)
items.exit()
.transition()
.attr('opacity', 0)
.remove()
enteringItems
.append('text')
.text(d => d)
.style('text-align', 'center')
enteringItems
.append('text')
.attr('class', 'close-button')
.attr('transform', 'translate(20, 0)')
.text('x')
.on('click', d => removeItem(d))
}

text {
font-family: sans-serif, Play;
}
form .s1 {
position: absolute;
top: 180px;
left: 55px;
}
*:focus {
outline: none;
}
select {
background: #404040;
color: #ffffff;
}
select option:checked:after {
background: #ffffff;
color: #404040;
}
.item {
fill: black;
}
.close-button {
fill: darkgray;
cursor: pointer;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.min.js"></script>
<form>
<select id='choose' class='s1'></select>
</form>
&#13;