d3拖动模糊/抖动手柄

时间:2018-12-07 15:41:49

标签: javascript d3.js

这是在d3 v4上。

我正在尝试创建一个带有边界的可扩展矩形区域(一种受约束的d3-brush)。我添加了一个在鼠标悬停时显示的句柄。

var rectHeight = 80, rectWidth = 100, maxWidth = 200;
var svg = d3.select("svg");

var brect = svg.append("g")
  .attr("id", "brect");

brect.append("rect")
  .attr("id", "dataRect")
  .attr("width", rectWidth)
  .attr("height", rectHeight)
  .attr("fill", "green");

var handleResizeGroup = brect.append("g")
  .attr("id", "handleResizeGroup")
  .attr("transform", `translate(${rectWidth})`)
  .call(d3.drag()
    .on("start", dragStarted)
    .on("drag", dragged)
    .on("end", dragEnded));

function dragStarted() {
  d3.select(this.previousSibling).classed("active", true);
}

function dragEnded() {
  d3.select(this.previousSibling).classed("active", false);
}

function dragged(d) {
  var h = d3.select(this);
  var r = d3.select(this.previousSibling);
  var currWidth = r.attr("width");

  var t = (d3.event.x >= 0 && d3.event.x <= maxWidth) ? d3.event.x : currWidth;

  r.attr("width", t);
  h.attr("transform", `translate(${t})`)
}

handleResizeGroup.append("path")
  .attr("fill-opacity", 0)
  .attr("stroke-opacity", 0)
  .attr("stroke", "grey")
  .attr("cursor", "ew-resize")
  .attr("d", resizePath);

handleResizeGroup.append("rect")
  .attr("id", "resizeRect")
  .attr("width", "8")
  .attr("fill-opacity", 0)
  .attr("cursor", "ew-resize")
  .attr("height", rectHeight)
  //.attr("pointer-events", "all")
  .on("mouseover", function(){
    d3.select(this.previousSibling)
      .attr("stroke-opacity", "100%");
  })
  .on("mouseout", function() {
    d3.select(this.previousSibling)
      .attr("stroke-opacity", "0");
  });

function resizePath(d) {
  var e = 1,
    x = e ? 1 : -1,
    y = rectHeight / 3;
  return "M" + (.5 * x) + "," + y
    + "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6)
    + "V" + (2 * y - 6)
    + "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y)
    + "Z"
    + "M" + (2.5 * x) + "," + (y + 8)
    + "V" + (2 * y - 8)
    + "M" + (4.5 * x) + "," + (y + 8)
    + "V" + (2 * y - 8);
}
rect.active {
  stroke-width: 1;
  stroke: rgb(0,0,0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width=1200 height=500></svg>

我注意到2个问题

  1. 拖动手柄时,手柄本身会出现抖动(大概是因为仅在鼠标悬停时才显示手柄?)
  2. 如果我拖动鼠标的速度太快-向左说,矩形将无法赶上

有人可以帮助您了解正在发生的事情以及如何解决这些问题吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

对于您的第一个问题,添加.attr('pointer-events', 'none') to the green rect`。手柄抖动,因为您的光标移动的速度比手柄稍快-因此,您在移动时会不断地移出并插入到手柄中,然后追上去。

我真的看不到您对resizePath做的事情。这是在矩形周围增加灰色笔触吗?为什么不只是添加/删除笔划?您的第二个问题可能是由于不断调整该路径的大小。