This page looks best with JavaScript enabled

ブログに Word Cloud を表示する[D3]

 ·   ·  ☕ 2 min read  ·  🐶 odanny · 👀... views

結論

以下のようなものが Javascript でいい感じに表示できる。



3行まとめ

  • Javascriptのコード例がすでにあるので、かんたんにワードクラウドを埋め込める
  • shortcodeで動的につくってくれるので、開くたびに文字の配置や形は変わる
  • 日本語を品詞ごとに区切る「わかち書き」は実装されていないので、標準では英語のみ対応

やり方

これは Hugo のテーマの一つである Zzo theme でのやり方です。

基本的には公式ドキュメント Zzo docs: D3 に沿って進めていけばいい。

まずはワードクラウドを表示したい.mdファイルを用意する。

$ hugo new hoge/huga.md

そして以下の記述を追加する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
--
title: "huga"

...tagとかいろいろ

libraries:
- d3
- d3_cloud
---
{{/* < d3 script="/d3/word-cloud.js" style="/d3/word-cloud.css" > */}}
<div id="word-cloud-div"></div>
\{\{\< /d3 \>\}\}

参照先は/d3/word-cloud.js となっているので、root/static/d3/配下に以下の2つのファイルを作成する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var d3 = window.d3;
var cloud = d3.layout.cloud;

d3.text("/d3/dream.txt").then((words) => {
  var stopwords = new Set(
    "i,me,my,myself,we,us,our,ours,ourselves,you,your,yours,yourself,yourselves,he,him,his,himself,she,her,hers,herself,it,its,itself,they,them,their,theirs,themselves,what,which,who,whom,whose,this,that,these,those,am,is,are,was,were,be,been,being,have,has,had,having,do,does,did,doing,will,would,should,can,could,ought,i'm,you're,he's,she's,it's,we're,they're,i've,you've,we've,they've,i'd,you'd,he'd,she'd,we'd,they'd,i'll,you'll,he'll,she'll,we'll,they'll,isn't,aren't,wasn't,weren't,hasn't,haven't,hadn't,doesn't,don't,didn't,won't,wouldn't,shan't,shouldn't,can't,cannot,couldn't,mustn't,let's,that's,who's,what's,here's,there's,when's,where's,why's,how's,a,an,the,and,but,if,or,because,as,until,while,of,at,by,for,with,about,against,between,into,through,during,before,after,above,below,to,from,up,upon,down,in,out,on,off,over,under,again,further,then,once,here,there,when,where,why,how,all,any,both,each,few,more,most,other,some,such,no,nor,not,only,own,same,so,than,too,very,say,says,said,shall".split(
      ","
    )
  );
  words = words
    .trim()
    .split(/[\s.]+/g)
    .map((w) => w.replace(/^[“‘"\-—()[\]{}]+/g, ""))
    .map((w) => w.replace(/[;:.!?()[\]{},"'’”\-—]+$/g, ""))
    .map((w) => w.replace(/['’]s$/g, ""))
    .map((w) => w.substring(0, 30))
    .map((w) => w.toLowerCase())
    .filter((w) => w && !stopwords.has(w));

  // console.log(d3.rollups(words,
  //   (group) => group.length,
  //   (w) => w
  // ).sort(([, a], [, b]) => d3.descending(a, b))
  // .slice(0, 250)
  // .map(([text, value]) => ({ text, value })));
  var fontFamily = "sans-serif";
  var fontScale = 15;
  var padding = 0;
  var height = 500;
  var width = 700;
  const rotate = () => 0; // () => (~~(Math.random() * 6) - 3) * 30

  var data = d3
    .rollups(
      words,
      (group) => group.length,
      (w) => w
    )
    .sort(([, a], [, b]) => d3.descending(a, b))
    .slice(0, 250)
    .map(([text, value]) => ({ text, value }));
  console.log(data);

  const svg = d3
    .select("#word-cloud-div")
    .append("svg")
    .attr("height", height)
    .attr("width", width)
    .attr("font-family", fontFamily)
    .attr("text-anchor", "middle");

  const w_cloud = cloud()
    .size([width, height])
    .words(data.map((d) => Object.create(d)))
    .padding(padding)
    .rotate(rotate)
    .font(fontFamily)
    .fontSize((d) => Math.sqrt(d.value) * fontScale)
    .on("word", ({ size, x, y, rotate, text }) => {
      svg
        .append("text")
        .attr("font-size", size)
        .attr("transform", `translate(${x},${y}) rotate(${rotate})`)
        .text(text);
    });

  w_cloud.start();
});
1
適当なテキストファイルをいれよう。

自分の場合は以前書いたネタ記事をDeepLで翻訳して入れてみた。

Qiita:人は寒すぎると何になる?~7400Tweetを分析して見えた答え~

参考

Zzo docs: D3

Share on

odanny
WRITTEN BY
odanny
レトロゲームが好きな大学院生