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

时间:2017-04-18 05:17:03

标签: d3.js

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

建立我的dynamic button appending project,我现在想要制作transition()效果,您可以按任意顺序追加内容,按任意顺序删除它们,如果从顶部删除了某些内容,则元素将优雅地向上滑动到顶部以填充空白空间。我只是半功能,问题是我找不到正确的逻辑来只选择当前按钮事件下面的文本。

跳过逻辑,我只需使用selectAll('text')就可以成功地使用转换。这只适用于你有两个项目,一旦你附加了3件事情就会变得混乱,因为它没有正确的逻辑来辨别要转换的东西。

另一个翻译问题与按钮移动有关。文本转换正常,但无论使用.attr('top', new_value)还是.attr('transform', 'translate(' + 0+','+new_value+')')

,按钮都会固定不动

转到带有评论的live example,然后从下拉菜单中选择内容,点击删除最上面的内容,您就会看到我的意思。

总结一下:

  1. 如何对任何大于当前最远距离的文本进行if ()逻辑检查? (即如果页面上的文字元素低于当前的文本元素)

  2. 如何告诉D3只选择相对位置较大的文本(垂直方向,即页面下方)

  3. 如何让D3翻译或更新按钮的top?请注意,我使用的是selectAll('button')示例,但理想情况下我需要更明智的选择。

1 个答案:

答案 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;
&#13;
&#13;