2

我想将 d3.svg.axis 重新用于需要刻度线大且可拖动的用途:

轴

例如,在上面代码在此处的轴的屏幕截图中,当您将鼠标悬停在 25 或 69 上时,我希望鼠标变为四角形状,然后能够向左拖动刻度线和按住鼠标右键。

我可以看到<svg>d3 自动生成的代码<line>为类为“tick”的每个刻度生成一个单独的元素:

轴代码

所以我认为有一种方法可以定位这些元素并使它们响应拖动,但我不清楚如何做到这一点。当然,线元素不应该在任何地方都可以拖动,而只能沿着水平轴左右滑动,并且不能移动到开始和结束刻度之外。

4

1 回答 1

2

我得到了这个工作:livecoding.io example

这里是相关的代码,不是特别干净但有效:

var w = h = 600;
var padding = 20;
var svg = d3.select("svg").attr("width", w).attr("height", h);

var xScale = d3.scale.linear()
             .domain([0, 100])
             .range([padding, w - padding * 2]);

var sharedAxis = function() {
  return d3.svg.axis()
            .scale(xScale)
            .tickValues([19,69])
            .tickSize(50);
}

var downAxis = sharedAxis()
            .orient("bottom");

var upAxis = sharedAxis()
            .orient("top");

var addPlayer = function(playerAxis) {
  svg.append("g")
   .attr("class", "axis")
   .attr("transform", "translate(0," + (100) + ")")
   .call(playerAxis);
}


addPlayer(downAxis);
addPlayer(upAxis);

var drag = d3.behavior.drag()
    .on("drag", dragmove);

function dragmove(d) {
  // move it
  var curX = d3.select(this).attr("transform").match(/\(([^,]+),/)[1];
  var newX = Math.max(xScale.range()[0], d3.event.x);
  newX = Math.min(xScale.range()[1], newX);
  var newTransform = d3.select(this).attr("transform").replace(/\([^,]+,/, "(" + newX + ",");
  d3.select(this).attr("transform", newTransform);
  // update text
  d3.select(this).select("text").text(parseInt(xScale.invert(newX)));
}

var allTicks = d3.selectAll(".axis g").call(drag);
于 2013-03-12T05:10:42.533 回答