如何在导入的SVG上使用d3.js Fisheye

时间:2019-02-21 16:02:48

标签: d3.js

此刻,我已经成功导入了要在其上添加鱼眼效果的SVG。我想做类似于this example的事情。我看过那里使用的代码如下:

var path = svg.selectAll("path")
    .attr("d", line);

svg.on("mousemove", function() {
  fisheye.center(d3.mouse(this));
  path.attr("d", function(d) { return line(d.map(fisheye)); });
});

但是,我不像以前那样使用线,但是我确实有像它们一样的路径。老实说,我不太确定为什么在这样的代码中使用d3.line。但是我现在是这样的:

  d3.xml('log.svg')
    .then(data => {

      d3.select('body').node().append(data.documentElement)

      var fisheye = d3.fisheye.circular()
        .radius(200)
        .distortion(2);

      var svg = d3.select("body").select("svg g")
      var path = svg.selectAll("path")
        .attr("d");

      svg.on("mousemove", function() {
        fisheye.focus(d3.mouse(this));
        path.attr("d", function(d) {
          return (d.map(fisheye)) // Not sure about this part yet.
        });

      });

    });

控制台给我以下错误:


未捕获的TypeError:path.attr不是函数


这发生在此行上:

path.attr("d", function(d) {
          return (d.map(fisheye)) // Not sure about this part yet.
        });

有人知道为什么会出现这种错误吗?它与工作版本没有太大不同吗?

1 个答案:

答案 0 :(得分:0)

您必须更改:

var path = svg.selectAll("path")
    .attr("d");

var path = svg.selectAll("path");

(还请注意,您有时用分号来结束语句,有时则不用分号)


此错误的原因很重要,因为它是d3.js中经常使用的重要代码设计。

要设置对象的属性/属性/行为,您不能直接设置它们。而是调用设置它们的函数,这样内部逻辑可以避免副作用。

这些 setter函数通常还会做两件事:

  1. 它们也是 getter 函数,返回相应的
  2. 用作设置器功能,它们会将您要为其设置值的对象返回到属性。

第二个项目符号允许您进行优雅的方法链接:

因此,如果要在一个对象上设置三个属性,则无需编写

let obj = *object*;
obj.method1(‘a’);
obj.method2(‘b’);
obj.method3(‘c’);

let obj = *object*;
obj = obj.method1(‘a’);
obj = obj.method2(‘b’);
obj = obj.method3(‘c’);

您可以改为:

let obj = *object*.method1(‘a’).method2(‘b’).method3(‘c’);

选择上,因为设置了很多属性,所以您经常不应用此方法链接!

正如我提到的,为方便起见,可以将相同的方法用作 getter 函数:

// calling method without argument returns its value
obj.method1(); // returns ‚a‘ !! not the obj!!

这意味着在应用getter函数之后,您将无法再进行方法链接,因为“ a”没有 method2 等。

对于 selections ,除了 selection.attr() selection.style()决定是根据第二个参数设置 / 获取

回到您的示例:

var path = svg.selectAll("path")
      .attr("d");

是getter函数,返回已(或尚未分配)给元素的d属性的字符串。

相反:

 var path = svg.selectAll("path");

返回所有路径选择,因此,  设置功能:

    var path = svg.selectAll("path")
      .attr("d", „*your path string*“);

请注意,您可以在鱼眼示例本身中看到的使用 getter,setter和方法链的代码设计实现:

fisheye.center = function(_) {
  if (!arguments.length) return center;
  center = _;
  return fisheye;
};

return rescale();

另请参阅Mike Bostocks excellent article有关可重复使用的代码,他在其中解释了此代码设计。