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

时间:2013-01-24 12:58:12

标签: javascript svg d3.js

我正在开发一个d3.js项目,我正在显示一些高度相同的矩形。矩形连接到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});

然后能够用这样的方式改进矩形的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;});

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

数据没有任何问题(我已经检查过),我已经确认动画确实可以正常工作。

1 个答案:

答案 0 :(得分:8)

如果您将<use>元素指向<rect>根据SVG specification

忽略<use>的宽度/高度

我建议您将<rect>放在<symbol>中,然后使用引用该符号。这样,使用的宽度/高度将适用于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;});