javascript - 防止 svg 组重叠(D3 js v4)

标签 javascript d3.js svg

当我拖动元素以切换/更改其位置时,如何防止 svg 的“g”元素与其他“g”元素重叠。 下面是代码的链接。

https://jsfiddle.net/3jxqgjcL/

var group = svg.selectAll('g')
  .data(rectangles)
  .enter().append("g")
  .attr("transform",
        "translate(" + margin.left + "," + margin.top + ")")
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

group.append("rect")
     .attr("x", function(d) { return d.x; })
     .attr("y", function(d) { return d.y; })
     .attr("height", 60)
     .attr("width", 300)
     .style("fill", function(d, i) { return color(i); });

group.append("text")
     .attr("x", function(d) { return d.x; })
     .attr("y", function(d) { return d.y; })
       .attr("text-anchor", "start")
       .style("fill", "steelblue")
       .text("Close");

function dragstarted(d) {
  d3.select(this).raise().classed("active", true);
}

function dragged(d) {
  d3.select(this).select("text")
    .attr("y", d.y = d3.event.y);
  d3.select(this).select("rect")
    .attr("y", d.y = d3.event.y);
}

function dragended(d) {
  d3.select(this).classed("active", false);
}

最佳答案

你的问题不是很清楚。我假设通过防止 svg 的“g”元素重叠,您希望在释放其中一个组时重新排列这些组。

既然如此,你可以得到所有的<g> dragended 中的元素函数,根据索引对它们进行排序和翻译:

function dragended(d) {
    d3.select(this).classed("active", false);
    var theseGroups = svg.selectAll(".groups").sort(function(a, b) {
        return d3.ascending(a.y, b.y);
    });
    theseGroups.attr("transform", function(d, i) {
        return "translate(" + margin.left / 2 + "," + (d.y = barHeight * i) + ")";
    })
}

这是一个演示:

var margin = {
    top: 10,
    right: 10,
    bottom: 30,
    left: 10
  },
  width = 500 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom
distance = 0, barHeight = 75, i = 0;

function yAxis() {
  if (i == 0) {
    i++;
    return 2;
  } else {
    distance = parseInt(barHeight) * i;
    i++;
    return distance;
  }
}
var rectangles = d3.range(5).map(function() {
  return {
    x: 5,
    y: Math.round(yAxis())
  };
});

var color = d3.scaleOrdinal(d3.schemeCategory10);

var svg = d3.select("body").append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

var group = svg.selectAll('g')
  .data(rectangles)
  .enter().append("g")
  .attr("class", "groups")
  .attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")"
  })
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

group.append("rect")
  .attr("height", 60)
  .attr("width", 300)
  .style("fill", function(d, i) {
    return color(i);
  });

group.append("text")
  .attr("text-anchor", "start")
  .style("fill", "steelblue")
  .text("Close");

function dragstarted(d) {
  d3.select(this).raise().classed("active", true);
}

function dragged(d) {
  d3.select(this).attr("transform", "translate(" + margin.left / 2 + "," + (d.y = d3.event.y) + ")");
}

function dragended(d) {
  d3.select(this).classed("active", false);
  var theseGroups = svg.selectAll(".groups").sort(function(a, b) {
    return d3.ascending(a.y, b.y);
  });
  theseGroups.attr("transform", function(d, i) {
    return "translate(" + margin.left / 2 + "," + (d.y = barHeight * i) + ")";
  })
}
svg {
  border: 1px solid #000;
}
<script src="https://d3js.org/d3.v4.min.js"></script>

关于javascript - 防止 svg 组重叠(D3 js v4),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44412796/

相关文章:

javascript - 在Javascript中,返回分号 'return;'是什么意思

javascript - 如何使用 yii2 下拉列表隐藏 block

javascript - DOM 中的节点和元素

javascript - 使用 d3.js 创建一条穿过某些点的线

javascript - 如何在 billboard.js 中使用更复杂的 svg 作为图表点?

javascript - 如何将不同的背景图像(.png)添加到 SVG 圆形,并设置描边?

javascript - Bootstrap-4 模态

javascript - D3 条形图对于所有负值和正值均无法正常工作

javascript - 如何限制没有轴的力导向图形布局上的平移? D3/JS

svg - 挤出具有多个孔的多个多边形并对组合形状进行纹理化