D3相对位置逻辑,选择和翻译



虽然相对位置逻辑,选择和翻译声音乍看之下单独的问题,但在我的特殊情况下,您将看到它们如何相互关联。

构建我的动态按钮附加项目,我现在想制定transition()效果,您可以在任何顺序上附加事物,按任何顺序删除它们,如果从顶部删除某些东西,底部元素将优雅地滑动到顶部以填补空白空间。我只有半功能,问题是我找不到正确的逻辑来仅选择当前按钮事件下方的文本。

跳过逻辑,我确实通过简单地使用selectAll('text')成功地使用了过渡。这仅在您有2个项目的情况下才起作用,一旦您附加了3件事,它就会变得凌乱,因为它没有正确的逻辑来辨别哪个要过渡。

另一个翻译问题与使按钮移动有关。文本过渡正常,但是按钮固执地保持不变,无论使用.attr('top', new_value).attr('transform', 'translate(' + 0+','+new_value+')')

转到带有评论的实时示例,然后从下拉菜单中选择事物,单击以删除顶部,您将看到我的意思。

总结:

  1. 如何使if ()逻辑检查任何大于当前最高距离的文本?(即,如果页面上的文本元素高于当前的元素(

  2. 我如何告诉D3仅选择具有更大相对位置的文本(在垂直意义上,即页面上的较低(

  3. 如何使D3翻译或更新按钮的top?请注意,在示例中,我正在使用selectAll('button'),但理想情况下,我需要一个更敏感的选择。

您应该使用数据绑定来实现此目标,请参阅我的代码中的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>

最新更新