D3词云布局圆形和矩形 [英] D3 word cloud layout circle and rectangular

查看:67
本文介绍了D3词云布局圆形和矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是D3新手,正在尝试使用以下内容构建词云页面 JasonDavies d3-cloud .

I'm a D3 newbie and trying to build word cloud page using JasonDavies d3-cloud.

但是有时所有单词都以圆形显示,但有时以矩形显示.

But sometimes all words are showing in circle layout, but sometimes in rectangular.

如何使它们始终位于圆形布局中?

How can I make them always locate in circle layout?

推荐答案

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

d3-cloud's layout algorithm places words within an ellipse starting from the center of the rectangle you've provided (d3.layout.cloud().size([width, height])).

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

If you have a container (size([width, height])) big enough compared to your number of words and the size you've given to these words, then you'll get a nice circle (or an ellipse if your container isn't a square):

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 的布局算法将开始在您选择用来容纳云的容器的角部寻找空间.它将开始看起来像矩形/正方形.(到目前为止,甚至没有足够的空间来添加剩余的单词):

If your container can't hold your words as an ellipse/circle, d3-cloud's layout algorithm will start finding space in the corners of the container you've chosen to contain your cloud. And it will start looking like a rectangle/square. (Up to the point there's not even enough space to add the remaining words):

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 提供足够的空间,或者增加云容器的宽度和高度.

The solutions consist in either scaling down the size of your words in order to give d3-layout enough space or increase the width and height of the cloud container.

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

For instance by scaling down the size of words:

// 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>

这篇关于D3词云布局圆形和矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆