如何使用svg:defs在d3.js中创建具有相同高度的rect?

din*_*ino 2 javascript svg d3.js

我正在开发一个d3.js项目,我正在显示一些高度相同的矩形.矩形连接到a input[type=number],调整每组矩形的高度.为了使动画更容易(所以我只需要操作svg:defs数字输入的onchange),我希望能够用这样的svg:def标记指定一组矩形的高度:

var svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500);
svg.append("defs").selectAll(".rectdef")
  .data(data).enter()
  .append("rect")
  .attr("class", "rectdef")
  .attr("id", function (d, i){return "rect" + d.name;})
  .attr("x", 0)      // overridden below
  .attr("width", 0)  // overridden below
  .attr("y", 0)      // overridden below
  .attr("height", function (d, i){return d.height});
Run Code Online (Sandbox Code Playgroud)

然后能够用这样的方式改进矩形的放置x,y和宽度:

svg.selectAll(".bar")
  .data(data).enter()
  .append("use")
  .attr("class", "bar")
  .attr("xlink:href",function (d){return "#rect"+d.type;})
  .attr("x", function(d) { return d.x })
  .attr("width", function (d) {return d.w;})  // this does NOT adjust width!
  .attr("y", function (d) {return 0;});
Run Code Online (Sandbox Code Playgroud)

此代码段正确更改了x和y坐标,但它没有正确更改宽度!任何想法在这里有什么问题?这是浏览器问题(我使用的是Chrome 24.0.1312.52)吗?在svg:use标签上宽度不能像这样编辑吗?

数据没有任何问题(我已经检查过),我已经能够确认动画是否正常工作.

Rob*_*son 8

如果根据SVG规范<use>元素指向<rect>宽度/高度,<use>则忽略该元素

我建议你把它<rect>放在一个<symbol>,然后有使用参考符号.这样,使用的宽度/高度将适用于rect.您可能希望在符号内使rect的宽度/高度为100%.

换句话说,这样的事情应该有效:

svg.append("defs").selectAll(".rectdef")
  .data(data).enter()
  .append("symbol")
  .attr("class", "rectdef")
  .attr("id", function (d, i){return "rect" + d.name;})
  .append("rect")
  .attr("x", 0)           // overridden below
  .attr("width", "100%")  // overridden below
  .attr("y", 0)           // overridden below
  .attr("height", function (d, i){return d.height});

svg.selectAll(".bar")
  .data(data).enter()
  .append("use")
  .attr("class", "bar")
  .attr("xlink:href",function (d){return "#rect"+d.type;})
  .attr("x", function(d) { return d.x })
  .attr("width", function (d) {return d.w;})  // this correctly adjusts width!
  .attr("y", function (d) {return 0;});
Run Code Online (Sandbox Code Playgroud)