【问题标题】:D3 word cloud layout circle and rectangularD3 词云布局圆形和矩形
【发布时间】:2019-02-11 03:43:48
【问题描述】:

我是 D3 新手,正在尝试使用 JasonDavies d3-cloud.

但有时所有单词都以圆形布局显示,但有时以矩形显示。

我怎样才能让它们始终位于圆形布局中?

【问题讨论】:

    标签: javascript d3.js d3-cloud


    【解决方案1】:

    d3-cloud 的布局算法将单词放置在从您提供的矩形 (d3.layout.cloud().size([width, height])) 的中心开始的椭圆内。

    如果您的容器 (size([width, height])) 与您的单词数量和您为这些单词指定的大小相比足够大,那么您将得到一个漂亮的圆圈(如果您的容器不是的话,您会得到一个椭圆一个正方形):

    Math.seedrandom('hello words');
    
    var data = [{ text: "Hello", count: 38 }, { text: "World", count: 27 }, { text: "Whatever", count: 21 }, { text: "Massive", count: 21 }, { text: "Thing", count: 16 }, { text: "Something", count: 14 }, { text: "What", count: 12 }, { text: "Else", count: 9 }, { text: "Blabla", count: 6 }, { text: "Small", count: 6 }, { text: "VeryLong", count: 6 }, { text: "Word", count: 3 }, { text: "abcdef", count: 4 }, { text: "Elsewhere", count: 9 }, { text: "Anything", count: 3 }, { text: "Placeholder", count: 14 }, { text: "WhateverSmall", count: 3 }, { text: "Work", count: 12 }, { text: "Wording", count: 7 }, { text: "Verb", count: 4 }];
    
      var svg = d3.select("svg").append("g");
    
      let fill = d3.scaleOrdinal(d3.schemeCategory20);
      let size = d3.scaleLinear().range([0, 20]).domain([0, d3.max(data, d => d.count)]);
    
      let word_cloud_data = data
        .map( function(d) {
          return { text: d.text, size: 9 + size(d.count) * 3.5 };
        });
    
      let layout = d3.layout.cloud()
        .size([600, 600])
        .words(word_cloud_data)
        .padding(2.5)
        .rotate(d => ~~(Math.random() * 2) * -90)
        .fontSize(d => d.size)
        .on("end", draw);
    
      layout.start();
    
      function draw(words) {
    
        svg.append("g")
          .attr("transform", "translate(250,250)")
          .selectAll("text")
          .data(words)
          .enter().append("text")
          .style("fill", (d, i) => { d.color = fill(i); return d.color; })
          .style("text-anchor", "middle")
          .attr("transform", d => "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")")
          .text(d => d.text)
          .style("font-size", d => d.size + "px");
      }
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://cdn.rawgit.com/jasondavies/d3-cloud/master/build/d3.layout.cloud.js"></script>
    <script src="https://d3js.org/d3-scale.v1.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.4/seedrandom.min.js">
    </script>
    <svg width="700" height="700"></svg>

    如果您的容器不能将您的文字作为椭圆/圆来容纳,d3-cloud 的布局算法将开始在您选择包含云的容器的角落寻找空间。它会开始看起来像一个矩形/正方形。 (到目前为止,连剩余的字都没有足够的空间添加):

    Math.seedrandom('hello words');
    
    var data = [{ text: "Hello", count: 38 }, { text: "World", count: 27 }, { text: "Whatever", count: 21 }, { text: "Massive", count: 21 }, { text: "Thing", count: 16 }, { text: "Something", count: 14 }, { text: "What", count: 12 }, { text: "Else", count: 9 }, { text: "Blabla", count: 6 }, { text: "Small", count: 6 }, { text: "VeryLong", count: 6 }, { text: "Word", count: 3 }];
    
      var svg = d3.select("svg").append("g");
    
      let fill = d3.scaleOrdinal(d3.schemeCategory20);
      let size = d3.scaleLinear().range([0, 20]).domain([0, d3.max(data, d => d.count)]);
    
      let word_cloud_data = data
        .map( function(d) {
          return { text: d.text, size: 9 + size(d.count) * 3.5 };
        });
    
      let layout = d3.layout.cloud()
        .size([275, 275])
        .words(word_cloud_data)
        .padding(2.5)
        .rotate(d => ~~(Math.random() * 2) * -90)
        .fontSize(d => d.size)
        .on("end", draw);
    
      layout.start();
    
      function draw(words) {
    
        svg.append("g")
          .attr("transform", "translate(150,150)")
          .selectAll("text")
          .data(words)
          .enter().append("text")
          .style("fill", (d, i) => { d.color = fill(i); return d.color; })
          .style("text-anchor", "middle")
          .attr("transform", d => "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")")
          .text(d => d.text)
          .style("font-size", d => d.size + "px");
      }
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://cdn.rawgit.com/jasondavies/d3-cloud/master/build/d3.layout.cloud.js"></script>
    <script src="https://d3js.org/d3-scale.v1.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.4/seedrandom.min.js">
    </script>
    <svg width="700" height="700"></svg>

    解决方案包括缩小字的大小以便为d3-layout 提供足够的空间,或者增加云容器的宽度和高度。

    例如通过缩小单词的大小:

    // domain reduced from [0, 20] to [0, 13]:
    var sizeScale = d3.scaleLinear().range([0, 13]).domain([0, d3.max(data, d => d.count)]);
    

    Math.seedrandom('hello word');
    
    var data = [{ text: "Hello", count: 38 }, { text: "World", count: 27 }, { text: "Whatever", count: 21 }, { text: "Massive", count: 21 }, { text: "Thing", count: 16 }, { text: "Something", count: 14 }, { text: "What", count: 12 }, { text: "Else", count: 9 }, { text: "Blabla", count: 6 }, { text: "Small", count: 6 }, { text: "VeryLong", count: 6 }, { text: "Word", count: 3 }];
    
      var svg = d3.select("svg").append("g");
    
      let fill = d3.scaleOrdinal(d3.schemeCategory20);
      let size = d3.scaleLinear().range([0, 13]).domain([0, d3.max(data, d => d.count)]);
    
      let word_cloud_data = data
        .map( function(d) {
          return { text: d.text, size: 9 + size(d.count) * 3.5 };
        });
    
      let layout = d3.layout.cloud()
        .size([275, 275])
        .words(word_cloud_data)
        .padding(2.5)
        .rotate(d => ~~(Math.random() * 2) * -90)
        .fontSize(d => d.size)
        .on("end", draw);
    
      layout.start();
    
      function draw(words) {
    
        svg.append("g")
          .attr("transform", "translate(150,150)")
          .selectAll("text")
          .data(words)
          .enter().append("text")
          .style("fill", (d, i) => { d.color = fill(i); return d.color; })
          .style("text-anchor", "middle")
          .attr("transform", d => "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")")
          .text(d => d.text)
          .style("font-size", d => d.size + "px");
      }
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://cdn.rawgit.com/jasondavies/d3-cloud/master/build/d3.layout.cloud.js"></script>
    <script src="https://d3js.org/d3-scale.v1.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.4/seedrandom.min.js">
    </script>
    <svg width="700" height="700"></svg>

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 1970-01-01
      • 1970-01-01
      • 2014-02-09
      • 2013-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多