具有 D3.js 的响应式词云



我正在尝试使用 d3.js 实现响应式词云。我还需要更新/更改数据的能力。

有很多例子基于Jason Davies非常好的解决方案。我正在尝试调整词云实现(在此处找到(以满足我的要求。

这是我的代码。

<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 没有明确的宽度和高度。

我在这里错过了什么?
感谢您的任何帮助。

你必须定义一些关于div维度的值,无论是内联样式还是css。 例如,整页div:

<div id="wordcloud" style="width:100%; height:100vh; display: block">
<div id="vis"></div>
</div>

将起作用,否则,如果缺少任何宽度或高度属性或等于 0,脚本将停止。

最新更新