减少调用D3的“attr”等所需的匿名函数的数量

时间:2016-02-08 06:35:08

标签: d3.js

所以我有一些基本的代码可以正常使用[顺便说一下我还没有使用任何音阶]:

        svg.selectAll("rect")
           .data(dataset)
           .enter()
           .append("rect")
           .attr("x", function(d, i) {
                return i * (w / dataset.length);
           })
           .attr("y", function(d) {
                return h - (d.close * 4);
           })
           .attr("width", w / dataset.length - barPadding)
           .attr("height", function(d) {
                return d.close * 4;
           })
           .attr("fill", function(d) {
                return "rgb(0, 0, " + (d.close * 10) + ")";
           })
           .append("title").text(function(d) {
                if (d.date == null) {
                    return "Close: " + d.close;
                } else {
                    return "Date: " + dateFmt(d.date)
                         + "\nClose: " + d.close;
                }
           });

现在我告诉我可以通过让第一个参数成为值对的名称对象来减少对attr的调用:

        svg.selectAll("rect")
           .data(dataset)
           .enter()
           .append("rect")
           .attr({
           "x": function(d, i) {
                return i * (w / dataset.length);
           },
           "y": function(d) {
                return h - (d.close * 4);
           },
           "width": w / dataset.length - barPadding,
           "height": function(d) {
                return d.close * 4;
           },
           "fill": function(d) {
                return "rgb(0, 0, " + (d.close * 10) + ")";
           }})
           .append("title").text(function(d) {
                if (d.date == null) {
                    return "Close: " + d.close;
                } else {
                    return "Date: " + dateFmt(d.date)
                         + "\nClose: " + d.close;
                }
           });
然而,在我看来,如果第一个参数可以是一个返回名称值对的特定对象的函数(第二个可以是函数),它就会更加简洁。像这样:

        svg.selectAll("rect")
           .data(dataset)
           .enter()
           .append("rect")
           .attr(function(d,i) {
             return {
                "x": i * (w / dataset.length),
                "y": h - (d.close * 4),
                "width": w / dataset.length - barPadding,
                "height": d.close * 4,
                "fill": "rgb(0, 0, " + (d.close * 10) + ")"
           })
           .append("title").text(function(d) {
                return ((d.date != null)
                        ? "Date: " + dateFmt(d.date) + "\n"
                        : "")
                    + "Close: " + d.close;
           });

后者不起作用,但也许我错过了更好的形成方法,因此需要指定更少的匿名函数定义。如果是这样的话,如果我愿意,可以对重复的di进行更具描述性的描述。是否有一些我可以忽略的替代模式?

2 个答案:

答案 0 :(得分:1)

尝试这种方式:

svg.selectAll("rect")
   .data(dataset)
   .enter()
   .append("rect")
   .each(function (d,i) {
       d3.select(this)
         .attr({
             "x": i * (w / dataset.length),
             "y": h - (d.close * 4),
             "width": w / dataset.length - barPadding,
             "height": d.close * 4,
             "fill": "rgb(0, 0, " + (d.close * 10) + ")"
         });
   });

答案 1 :(得分:0)

这是我偶尔会遗漏的功能之一。

有关于专业人士和专业人士的讨论。对issue #277issue #2254以及comments .classed()的同意,双方都有很好的论据。最好的一个反对包括在.attr()中,由Mike Bostock在他的一个D3 v4中提出:

  

这保留了D3的理念,即只鼓励将值(而不是名称)指定为函数。

尽管如此,等待可能很快就会结束!正如我刚刚注意到的那样,我们可能会在即将到来的repo中看到此功能。现在的共识似乎是不会进一步超载方法.attr().property().style(),以避免混淆这些方法'签名。目前answer中的更改已在新方法.attrs().properties().styles()中实施。请注意这些方法的复数名称。

目前,Gilsha发布的comment显然是正确的,并且尽可能接近D3 v3。 Mike Bostock也在others中提到了上述问题,但是对于某些code sample,包括我自己在内,感觉有点hacky。