d3.select元素指定的width/height与实际绘图区域有什么关系?

What is the relationship between the width/height specified for a d3.select element and the actual drawing area?

我正在使用d3.cloud制作一些词云。我不明白设置 svg 图像的宽度和高度与“变换”动作之间的关系。我设置svg大小为1200 x 600,但实际词云只有590x 290

我的词云代码:

function prep_drawing(data) {

  // set the dimensions and margins of the graph
  var margin = {top: 10, right: 10, bottom: 10, left: 10},
      width = 1200 - margin.left - margin.right,
      height = 600 - margin.top - margin.bottom;
  
  // append the svg object to the body of the page
  var svg = d3.select("#wordly_wordcloud").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
    .append("g")
      .attr("transform",
            "translate(" + margin.left + "," + margin.top + ")");
  
  // Constructs a new cloud layout instance. It run an algorithm to find the position of words that suits your requirements
  // Wordcloud features that are different from one word to the other must be here
  var layout = d3.layout.cloud()
    .size([width, height])
    .words(data.map(function(d) { return {text: d.word, size:d.size, color:d.color, url:d.url}; }))
    .padding(5)        //space between words
    .rotate(function() { return 0; })
    .fontSize(function(d) { return parseFloat(d.size) * 250; })      // font size of words
    .on("end", draw);
  layout.start();
  
  function draw(words) {
      svg
        .append("g")
          .attr("transform", "translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")")
          .selectAll("text")
            .data(words)
          .enter().append("text")
            .style("font-size", function(d) { return d.size; })
            .style("fill", function(d) { return d.color; })
            .attr("text-anchor", "middle")
            .style("font-family", "Impact")
            .attr("transform", function(d) {
              return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
            })
            .append("a")
            .attr("xlink:href", function(d) { return d.url; })
            .attr("style", function(d) { return "fill:"+d.color+";"; })
            .text(function(d) { return d.text; });
    }
}

这是 chrome 开发者工具元素部分的输出:

<div id="wordly_wordcloud">
   <svg width="1200" height="600">
      <g transform="translate(10,10)">
        <g transform="translate(590,290)">
           <text text-anchor="middle" transform="translate(-201,-78)rotate(0)" style="font-size: 150px; fill: rgb(144, 12, 0); font-family: Impact;"><a xlink:href="wordcloud.html?name=descriptions&amp;word=story" style="fill:rgb(144, 12, 0);">story</a></text>
...other <text> elements remove for clarity
</g></g></svg></div>

能不能把“g”变换区的大小调大点,好像是词云的绘图区

我一直在 运行 解决一些“高频”词未被绘制的问题,因为它们不适合 590 x 290“g”框。我的词频被归一化到 0-1 的范围内,我将频率乘以 150-350 之间的一个因子以获得清晰的词。我不清楚如何平衡指定的 width/height 和词频乘数之间的关系,以确保所有词都显示出来并且清晰可见。

有没有更好的方法根据词频指定字体大小?

谢谢!

马克

这是a known issue of d3-cloud。一种解决方案是递归地重试,直到所有单词都适合:

function drawCloud () {
  d3.layout.cloud()
  .on("end", function(output) {
      if (word.length !== output.length) { 
           drawCloud(range_max - 5);
           return undefined;  
      }
      else { draw(output); } // your draw function here
   })
  .start();
}