我正在研究 D3 标签云的交互式实现,它依赖于每个术语都有自己的类别或类。通过像这样修改 d3.layout.cloud.js,我设法将类别属性包含到术语中:
cloud.start = function() {
var board = zeroArray((size[0] >> 5) * size[1]),
bounds = null,
n = words.length,
i = -1,
tags = [],
data = words.map(function(d, i) {
return {
// Added by me
epidem_category: d['epidem_category'],
other_details: d['other_details'],
id: d['id'],
///////
text: text.call(this, d, i),
size: ~~fontSize.call(this, d, i),
font: font.call(this, d, i),
rotate: rotate.call(this, d, i),
padding: cloudPadding.call(this, d, i)
};
}).sort(function(a, b) { return b.size - a.size; });
我现在可以访问d.epidem_category
以及d.id
在绘制云时为某些类别提供不同的填充颜色或旋转值:
canvas
.selectAll("text")
.data(words)
.enter()
.append("text")
.style("font-size", function(d) { return d.size + "px"; })
.style("font-family", 'Gentium Book Basic')
.style("fill", function(d, i) { return entity_cloud.set_color(d.epidem_category);})
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + entity_cloud.set_rotation(d.epidem_category) ")";
})
.attr("class", function(d) { return d.epidem_category })
.attr("id", function(d, i) { return d.id })
.text(function(d) { return d.text; })
我的问题是我现在还想控制单词的位置——我希望同一类别的所有术语在云中捆绑在一起出现。我想也许我可以通过按类别重新排序输入数组来控制这一点,假设Jason Davies 的标签云演示页面上描述的算法:
尝试将单词放在某个起点:通常靠近中间,或位于中央水平线上的某处。
.. 因此,按照这种逻辑,如果前 10 个单词属于同一类别,它们应该在中间的某个地方捆绑在一起,其他类别将以循环模式跟随。然而,对此进行测试并没有产生预期的结果。事实上,我几乎看不到布局的任何变化。
有没有人对如何实现基于某些属性将术语捆绑在一起的布局有任何想法?