0

提出问题的一种方法可能是:我如何重构这个示例以使其符合 d3 约定?(下面也包含代码)

也就是说,而不是像我那样写:

rotateTransition(line1, 90)

我宁愿写这样的东西:

line1.transition().attr("rotation-around-origin", 90)

所以问题是:用我的例子中的自定义转换来扩展 d3 的转换的正确方法是什么?或者:我将如何处理猴子修补“线”选择对象?

奖励问题:在第 6-16 行中,我创建了 2 个具有完全相同初始化的“行”选择。是否有 d3 方法可以根据另一个选择复制选择?就像是:line2 = line1.dup()

上面链接的示例源代码:

var centerX = centerY = 50
var radius = 200

var svg = d3.select("svg").attr("width", 600).attr("height",600)

var line1 = svg.append("line")
  .attr("x1", centerX)
  .attr("y1", centerY)
  .attr("x2", centerX + radius)
  .attr("y2", centerY);

var line2 = svg.append("line")
  .attr("x1", centerX)
  .attr("y1", centerY)
  .attr("x2", centerX + radius)
  .attr("y2", centerY);

line1.attr("transform", "translate(100,100) rotate(45 50 50)");

function rotateTransition(line, degrees) {

  var rotationString = function(angle, x1, x2) { return "rotate("+angle+" "+x1+" "+x2+")" };
  var retInterpolator, startAngle = 0, endAngle = degrees;
  var transformStart = line.attr("transform") ? line.attr("transform") : "";
  var curRotation = transformStart.match(/rotate\((\d+) /)

  if (curRotation)
    endAngle = parseInt(curRotation.pop()) + degrees;
  else
    transformStart += rotationString(0,line.attr("x1"),line.attr("y1"));

  var transformEnd = transformStart.replace(/(.*rotate\()(\d+)( .*)/,"$1"+endAngle+"$3")
      console.log(transformStart);
  console.log(transformEnd);
  line.transition()
  .duration(2000)
  .attrTween("transform", function() {
    return d3.interpolateString(transformStart, transformEnd);
  })
}

rotateTransition(line1, 90)
rotateTransition(line2, 45)
4

1 回答 1

1

对于您的两个问题,请在此处查看 d3 的selection.call()方法。

在线路旋转的情况下,你甚至不必改变rotateTransition' 身体。您将像这样使用它:

line1.call(rotateTransition, 90)

真正唯一的区别是这种方法允许您链接函数调用。

如果您想深入挖掘,对于普通教育,请查看 d3 源代码以了解如何d3.svg.axis()实现,因为此call()方法在将轴应用于 d3 选择时结合使用。

于 2013-03-01T20:11:23.790 回答