防止svg组重叠(D3 js v4)

时间:2017-06-07 12:35:29

标签: 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);
}

1 个答案:

答案 0 :(得分:1)

你的问题并不完全清楚。我假设通过防止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>