有没有办法避免d3.js中的代码重复?

J. *_*ley 2 javascript svg d3.js

我目前正在学习d3,并且正在创建一个SVG,其中包含四个以水平线组织的矩形。它们都具有相同的大小,高度和颜色。制作每个rect对象时有很多冗余,我想知道是否有一种优化它的方法。

我想知道是否有一种方法可以制作一个rect对象并设置我需要的几乎所有属性(高度,宽度,y位置,填充颜色),然后进入每个矩形创建四个副本并只设置x-我想要的位置。我实际上并没有使用JS编写太多代码,并且习惯于Java,因此某些对象创建语法和过程对我来说是陌生的。

var smallBoxMargin = {top: 20, bottom: 20, left: 20, right: 20};
    var boxH = 150;
    var smallBoxDim = {width: (w/4)-smallBoxMargin.left-smallBoxMargin.right, height: boxH-smallBoxMargin.top-smallBoxMargin.bottom}
    var boxSvg = d3.select("#boxDiv")
      .append("svg")
      .attr("height",boxH)
      .attr("width",w);
    var boxMidpoint = w/2;
    boxSvg.append("rect") //inner left box
      .attr("class","smallBox")
      .attr("width",smallBoxDim.width)
      .attr("height",smallBoxDim.height)
      .attr("fill",eteOrange)
      .attr("x", boxMidpoint - smallBoxDim.width - smallBoxMargin.right)
      .attr("y", smallBoxMargin.top) 
    boxSvg.append("rect") //inner right box
      .attr("class","smallBox")
      .attr("width",smallBoxDim.width)
      .attr("height",smallBoxDim.height)
      .attr("fill",eteOrange)
      .attr("x", boxMidpoint+smallBoxMargin.left)
      .attr("y", smallBoxMargin.top)
    boxSvg.append("rect") //outer left box
      .attr("class","smallBox")
      .attr("width",smallBoxDim.width)
      .attr("height",smallBoxDim.height)
      .attr("fill",eteOrange)
      .attr("x", boxMidpoint-2*smallBoxDim.width - 2*smallBoxMargin.right-smallBoxMargin.left)
      .attr("y", smallBoxMargin.top)
    boxSvg.append("rect") //outer right box
      .attr("class","smallBox")
      .attr("width",smallBoxDim.width)
      .attr("height",smallBoxDim.height)
      .attr("fill",eteOrange)
      .attr("x", boxMidpoint+smallBoxDim.width+2*smallBoxMargin.left+smallBoxMargin.right)
      .attr("y", smallBoxMargin.top)
Run Code Online (Sandbox Code Playgroud)

上面的代码有效,它在class,width,height,fill和y属性中只是非常多余的。每个boxSvg.append("rect")都是新矩形元素的开始。 smallBoxDim具有较小盒子的尺寸,具有较小盒子smallBoxMargin的边距。

Ger*_*ado 5

您需要输入选择

D3代表d ata- d里文d ocuments(即,国内长途或D3)。如果您没有使用D3的数据绑定功能,那么您将失去使用D3 的全部要点!在其他的答案,尽管用心良苦,也完全忽略了这一点。

长话短说,在矩形中,仅x位置会变化。因此,在您的情况下,这就是您需要的数据(可以大大简化,但是我离题了),它是一个包含所有这些位置的数组:

var data = [boxMidpoint - smallBoxDim.width - smallBoxMargin.right, boxMidpoint + smallBoxMargin.left, 
    boxMidpoint - 2 * smallBoxDim.width - 2 * smallBoxMargin.right - smallBoxMargin.left, 
    boxMidpoint + smallBoxDim.width + 2 * smallBoxMargin.left + smallBoxMargin.right
];
Run Code Online (Sandbox Code Playgroud)

有了该数据数组,这就是回车选择:

var rects = boxSvg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("class", "smallBox")
  .attr("width", smallBoxDim.width)
  .attr("height", smallBoxDim.height)
  .attr("fill", "orange")
  .attr("x", function(d) {
    return d
  })
  .attr("y", smallBoxMargin.top);
Run Code Online (Sandbox Code Playgroud)

这就是您不需要一次又一次地重复代码的全部...

这是演示:

var data = [boxMidpoint - smallBoxDim.width - smallBoxMargin.right, boxMidpoint + smallBoxMargin.left, 
    boxMidpoint - 2 * smallBoxDim.width - 2 * smallBoxMargin.right - smallBoxMargin.left, 
    boxMidpoint + smallBoxDim.width + 2 * smallBoxMargin.left + smallBoxMargin.right
];
Run Code Online (Sandbox Code Playgroud)
var rects = boxSvg.selectAll(null)
  .data(data)
  .enter()
  .append("rect")
  .attr("class", "smallBox")
  .attr("width", smallBoxDim.width)
  .attr("height", smallBoxDim.height)
  .attr("fill", "orange")
  .attr("x", function(d) {
    return d
  })
  .attr("y", smallBoxMargin.top);
Run Code Online (Sandbox Code Playgroud)