如何创建自定义转换?

时间:2013-03-01 04:34:52

标签: d3.js

提问的一种方法可能是:如何重构this example以使其符合d3约定? (代码也包含在下面)

那就是,而不是像我一样写作:

rotateTransition(line1, 90)

我更愿意写点:

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

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

奖金问题:在第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)

1 个答案:

答案 0 :(得分:1)

对于你的两个问题,have a look here采用d3的selection.call()方法。

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

line1.call(rotateTransition, 90)

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

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