【发布时间】:2019-12-16 17:46:39
【问题描述】:
我正在尝试使用 d3.js 实现 响应式 词云。我还需要更新/更改数据的能力。
有很多例子都是基于Jason Davies这个很好的解决方案。我正在尝试调整文字云实现(found here) 以满足我的要求。
这是我的代码。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/d3/d3.min.js"></script>
<script type="text/javascript" src="bower_components/d3-cloud/d3.layout.cloud.js"></script>
<script type="text/javascript" src="tags.js"></script>
<body>
<div id="wordcloud">
<div id="vis"></div>
</div>
<script>
var w = window.innerWidth, h = window.innerHeight;
var fontSize;
var layout = d3.layout.cloud()
.timeInterval(Infinity)
.size([w, h])
.fontSize(function(d) {
return fontSize(+d.value);
})
.text(function(d) {
return d.key;
})
.on("end", draw);
var svg = d3.select("#vis").append("svg")
.attr("width", w)
.attr("height", h);
var vis = svg.append("g").attr("transform", "translate(" + [w >> 1, h >> 1] + ")");
update();
if(window.attachEvent) {
window.attachEvent('onresize', update);
}
else if(window.addEventListener) {
window.addEventListener('resize', update);
}
function draw(data, bounds) {
var w = window.innerWidth,
h = window.innerHeight;
// ***
svg.remove();
svg = d3.select("#vis").append("svg")
.attr("width", w)
.attr("height", h);
vis = svg.append("g").attr("transform", "translate(" + [w >> 1, h >> 1] + ")");
// ***
svg.attr("width", w).attr("height", h);
scale = bounds ? Math.min(
w / Math.abs(bounds[1].x - w / 2),
w / Math.abs(bounds[0].x - w / 2),
h / Math.abs(bounds[1].y - h / 2),
h / Math.abs(bounds[0].y - h / 2)) / 2 : 1;
var text = vis.selectAll("text")
.data(data, function(d) {
return d.text.toLowerCase();
});
text.transition()
.duration(1000)
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.style("font-size", function(d) {
return d.size + "px";
});
text.enter().append("text")
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.style("font-size", function(d) {
return d.size + "px";
})
.style("opacity", 1e-6)
.transition()
.duration(1000)
.style("opacity", 1);
text.style("font-family", function(d) {
return d.font;
})
.style("fill", function(d) {
return fill(d.text.toLowerCase());
})
.text(function(d) {
return d.text;
});
vis.transition().attr("transform", "translate(" + [w >> 1, h >> 1] + ")scale(" + scale + ")");
}
function update() {
layout.font('impact').spiral('archimedean');
fontSize = d3.scale['sqrt']().range([10, 100]);
if (tags.length){
fontSize.domain([+tags[tags.length - 1].value || 1, +tags[0].value]);
}
layout.stop().words(tags).start();
}
function changeWords(newTags) {
tags = newTags;
update();
}
</script>
此解决方案适用于整个窗口。但我希望将词云显示在 div 中。
当我尝试用 var w = $('#wordcloud').innerWidth(), h = $('#wordcloud').innerHeight(); 或类似的东西替换 var w = window.innerWidth, h = window.innerHeight; 时,它不起作用。
在我的实际应用程序中,我想使用这个解决方案,我在其他容器中有一个深度嵌套的 div。 div 没有明确的宽度和高度。
我在这里缺少什么?
感谢您的帮助。
【问题讨论】:
-
我记得使用 Jason Davies 的 wordcloud 时,很难让它具有响应性。然而,我能够把它放在一个容器里。检查我的代码,看看它是否可以帮助你:wordcloud.adelriosantiago.com
-
@adelriosantiago 感谢您的回复。我看到你正在使用
d3.min.js和d3.wordcloud.js。但我找不到任何发生魔法的javascript。您能否在处理响应性的地方发布相关代码部分? -
在我的示例中,您可以在此处更改 wordcloud 的宽度和高度:github.com/adelriosantiago/wikipedia-symptoms/blob/master/…。尝试使用这些值,其中包含的 wordcloud 应该相应地调整大小,因此您只需要在
<div>或包装器调整大小时调用该函数。
标签: javascript d3.js word-cloud