d3.js - 使用 d3.wordcloud 重绘词云
问题描述
我正在使用 d3.wordcloud (https://github.com/wvengen/d3-wordcloud),我正在尝试擦除我当前的词云并在按钮单击时绘制一个新的。它在第一次绘制词云时效果很好,但在每次连续绘制时,字体大小变得越来越乱。
这是它在第一次运行和连续运行几次后的样子:
经过观察,我可以看到每次运行后字体大小的范围都会减小,最终将每个单词的大小设置为 10 或 100。我相信问题出在d3.wordcloud.js中的函数更新中,但我我不知道如何继续解决这个问题。
function update() {
var words = layout.words();
fontSize = d3.scale[scale]().range([10, 100]);
if (words.length) {
fontSize.domain([+words[words.length - 1].size || 1, +words[0].size]);
}
}
我正在运行的代码基于存储库中提供的示例,带有一个用于测试目的的较小的 word 对象和一个用于重绘代码的按钮。
这是一个现场演示:
var test_words = [
{text: 'have', size: 102},
{text: 'Oliver', size: 47},
{text: 'say', size: 46},
{text: 'said', size: 36},
{text: 'bumble', size: 29, href: 'https://en.wikipedia.org/wiki/Beadle'},
{text: 'will', size: 29},
{text: 'Mrs', size: 56, href: 'https://en.wikipedia.org/wiki/Mrs.'},
{text: 'Mann', size: 27, href: 'http://educationcing.blogspot.nl/2012/06/oliver-twist-mrs-manns-character.html'},
{text: 'Mr', size: 27},
{text: 'very', size: 26},
{text: 'child', size: 20},
{text: 'all', size: 19},
{text: 'boy', size: 19},
{text: 'gentleman', size: 19, href: 'http://www.thefreelibrary.com/The+gentleman+in+the+white+waistcoat%3a+Dickens+and+metonymy.-a0154239625'},
{text: 'great', size: 19},
{text: 'take', size: 19},
{text: 'but', size: 18},
{text: 'beadle', size: 16},
{text: 'twist', size: 16},
{text: 'board', size: 15},
{text: 'more', size: 15},
{text: 'one', size: 15}
];
d3.wordcloud()
.size([600, 275])
.transitionDuration(1000)
.fill(d3.scale.ordinal().range(["#884400", "#448800", "#888800", "#444400"]))
.words(test_words)
.onwordclick(function(d, i) {
if (d.href) { window.location = d.href; }
})
.start();
d3.select('#dataset-picker').selectAll('.dataset-button')
.on("click", function() {
//clear the wordcloud div
document.getElementById("wordcloud").innerHTML = "";
var a2 = d3.wordcloud()
.size([600, 275])
.transitionDuration(1000)
.fill(d3.scale.ordinal().range(["#884400", "#448800", "#888800", "#444400"]))
.words(test_words)
.onwordclick(function(d, i) {
if (d.href) { window.location = d.href; }
})
.start();
});
<html>
<head>
<meta charset="UTF-8">
<title>Word Cloud</title>
<script src="https://cdn.rawgit.com/wvengen/d3-wordcloud/master/lib/d3/d3.js"></script>
<script src="https://cdn.rawgit.com/wvengen/d3-wordcloud/master/lib/d3/d3.layout.cloud.js"></script>
<script src="https://cdn.rawgit.com/wvengen/d3-wordcloud/master/d3.wordcloud.js"></script>
<!-- <script src="test_words.js"></script> -->
</head>
<body style="text-align: center">
<h1>Word Cloud</h1>
<div id='wordcloud'></div>
<div id="dataset-picker">
<input id ="test" value="test" class="dataset-button" type="button">
</div>
</body>
</html>
谢谢你。
解决方案
这有点棘手。该d3-wordcloud
插件(更确切地说是底层d3.layout.cloud
插件)将修改您输入的单词数据集以适应单词的大小。
渐渐地,某些单词会越来越大,而其他单词会越来越小。
为避免这种情况,您可以在每次使用deep copy
原始数据集创建新云时提供插件。这样原始数据集始终保持不变:
这是一种使用 javascript 深度复制 json 的方法:
function deepCopy(oldValue) {
var newValue
strValue = JSON.stringify(oldValue)
return newValue = JSON.parse(strValue)
}
您以这种方式将其传递给 wordcloud 插件:
.words(deepCopy(test_words))
这是一个演示:
var test_words = [
{text: 'have', size: 102},
{text: 'Oliver', size: 47},
{text: 'say', size: 46},
{text: 'said', size: 36},
{text: 'bumble', size: 29, href: 'https://en.wikipedia.org/wiki/Beadle'},
{text: 'will', size: 29},
{text: 'Mrs', size: 56, href: 'https://en.wikipedia.org/wiki/Mrs.'},
{text: 'Mann', size: 27, href: 'http://educationcing.blogspot.nl/2012/06/oliver-twist-mrs-manns-character.html'},
{text: 'Mr', size: 27},
{text: 'very', size: 26},
{text: 'child', size: 20},
{text: 'all', size: 19},
{text: 'boy', size: 19},
{text: 'gentleman', size: 19, href: 'http://www.thefreelibrary.com/The+gentleman+in+the+white+waistcoat%3a+Dickens+and+metonymy.-a0154239625'},
{text: 'great', size: 19},
{text: 'take', size: 19},
{text: 'but', size: 18},
{text: 'beadle', size: 16},
{text: 'twist', size: 16},
{text: 'board', size: 15},
{text: 'more', size: 15},
{text: 'one', size: 15}
];
function deepCopy(oldValue) {
var newValue
strValue = JSON.stringify(oldValue)
return newValue = JSON.parse(strValue)
}
var cloud = d3.wordcloud()
.size([500, 275])
.transitionDuration(1000)
.fill(d3.scale.ordinal().range(["#884400", "#448800", "#888800", "#444400"]))
.words(deepCopy(test_words))
.onwordclick(function(d, i) {
if (d.href) { window.location = d.href; }
})
.start();
d3.select('#dataset-picker').selectAll('.dataset-button')
.on("click", function() {
//clear the wordcloud div
// cloud.remove();
document.getElementById("wordcloud").innerHTML = "";
var cloud = d3.wordcloud()
.size([500, 275])
.transitionDuration(1000)
.fill(d3.scale.ordinal().range(["#884400", "#448800", "#888800", "#444400"]))
.words(deepCopy(test_words))
.onwordclick(function(d, i) {
if (d.href) { window.location = d.href; }
})
.start();
});
<html>
<head>
<meta charset="UTF-8">
<title>Word Cloud</title>
<script src="https://cdn.rawgit.com/wvengen/d3-wordcloud/master/lib/d3/d3.js"></script>
<script src="https://cdn.rawgit.com/wvengen/d3-wordcloud/master/lib/d3/d3.layout.cloud.js"></script>
<script src="https://cdn.rawgit.com/wvengen/d3-wordcloud/master/d3.wordcloud.js"></script>
</head>
<body style="text-align: center">
<h1>Word Cloud</h1>
<div id='wordcloud'></div>
<div id="dataset-picker">
<input id ="test" value="test" class="dataset-button" type="button">
</div>
</body>
</html>
推荐阅读
- microsoft-teams - 无法将消息中心帖子自动同步到 Microsoft Planner:请修复连接问题
- c# - 在哪里可以找到 SQLite.Interop.dll 文件和捆绑包?
- python - 从文件转换模型
- spring-boot - 为什么我不能访问映射器中的嵌入属性?
- bash - 以浏览器为中心运行脚本
- javascript - 使用 chart.js 仅显示某些标签
- java - 使用 Micrometer 发布 Spring Batch 指标
- excel - excel单元格格式错误 - 此单元格中的数字格式为文本或前面有撇号
- java - JAVA - 如何进行购买.products.acknowledge 请求
- sql - 如何从 postgresql sql 表中删除重复的行