Slip the surly bonds of earth, to touch the face of God

使用d3创建中心主词的词云

最近真的是压力山大,先是搞一个微信公众号的服务器,从没系统学过前端后端技术的我被迫突击了php服务器,现在又因为数据可视化的课程作业用到d3,又被迫学习了js ?,感觉经过这段历练,我向全栈工程师又迈进了一步?

基于js的数据可视化工具包D3

言归正传,让我们来了解一下什么是D3。D3 全称是Data-Driven-Document,是一个基于js的数据可视化工具,可以到D3官网了解一下它能做什么,上面的demo也都非常cool。因为是基于web浏览器的,多平台兼容性也非常nice。

《使用d3创建中心主词的词云》

使用也是非常的方便,只需一行引用:

1
<script src="https://d3js.org/d3.v4.min.js"></script>

当然,最新版本是v4,网上很多资源都是基于v3的,我们可以使用v3的脚本:

1
<script src="https://d3js.org/d3.v3.min.js"></script>

词云

词云大家都知道,可以用大小不等的词语来统计一篇文章或者一个主题中的主要概念。

《使用d3创建中心主词的词云》

D3中没有直接支持词云的功能,但是有现成的开源扩展可供参考:https://github.com/jasondavies/d3-cloud。使用也很简单,根据作者的demo,写一个调用词云模块的页面:

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
<script>
    var frequency_list;
    d3.json("./data.json", function (json) {
        frequency_list = json["word_list"];
        d3.layout.cloud().size([1280, 800])
            .words(frequency_list)
            .rotate(0)
            .fontSize(function (d) {
                return d.size;
            })
            .on("end", draw)
            .start();
    });<span style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" data-mce-type="bookmark" class="mce_SELRES_start"></span>
    function draw(words) {
        d3.select("body").append("svg")
            .attr("width", 1280)
            .attr("height", 800)
            .append("g")
            .attr("transform", "translate(640,400)")
            .selectAll("text")
            .data(words)
            .enter().append("text")
            .style("font-size", function (d) {
                return d.size + "px";
            })
            .style("fill", function () {
                return "#111";
            })
            .attr("transform", function (d) {
                return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
            })
            .text(function (d) {
                return d.text;
            });
    }
</script>

读取的json数据的格式类似: {“word_list”: [{“text”: “w1”, “size” : 20}, {“text”: “w2”, “size” : 20}…]这样。其中size表示单词在词云中的大小,通常跟单词出现频率正相关。

生成的词云类似这样:

《使用d3创建中心主词的词云》

可是我想把最重要的词放在图像正中间怎么办,在项目的GitHub库里可以找到这样一个commit:Add configure options for initializing the word position,可以自定义单词位置。下载下来发现不能用?,原来是js里step函数出了错:

1
2
3
d = data[i];
initPos(d, size);
cloudSprite(d, data, i);

initPos不是一个函数,那我们暴力解决,换成

1
2
3
d = data[i];
centerPointPos(d, size);
cloudSprite(d, data, i);

这样就可以了。看一看生成结果

《使用d3创建中心主词的词云》

额,看看单词们风骚的走位,应该是默认中心作为单词开始的位置了,找到页面文件的这里:

1
2
3
.attr("transform", function (d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})

把平移函数的平移值[d.x, d.y]改成[d.x – 1.5*d.size, d.y]就好啦,当然这不是绝对的做法,毕竟1.5倍单词大小是估计出来的,浓浓的工科风味——我才不管它精不精确,只要看着不错就行?

《使用d3创建中心主词的词云》

点赞

发表评论

电子邮件地址不会被公开。