Я пытаюсь создать связанный набор облаков слов, так что щелчок по слову в первом облаке обновлял бы второе облако слов новыми значениями.
Я использовал следующие две записные книжки:
- http://bl.ocks.org/joews/9697914 - содержит код для обновления / перерисовки облака слов
- https://observablehq.com/@contervis / clickable-word-cloud - содержит код для добавления событий onClick к словам
Проблема: вместо перерисовки второго облака слов, в настоящее время код добавляет новые облака слов в div при последовательных кликах.
JSFiddle: https://jsfiddle.net/yfkrL1a0/14/
var master_words = data.map(function(d) {
return {
text: d.name,
size: d.size,
children: d.children,
success: d.size
};
});
function handleClick(d, i) {
var e = d3.select(this);
console.log(d.text);
var myWordCloud2 = wordCloud('#my_dataviz2');
myWordCloud2.update(master_words);
}
function wordCloud(selector) {
var margin = {
top: 10,
right: 10,
bottom: 10,
left: 10
},
width = 450 - margin.left - margin.right,
height = 450 - margin.top - margin.bottom;
// append the svg object to the selector
var svg = d3.select(selector).append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform", "translate(250,250)");
var font_scale = d3.scaleLinear()
.domain([0, d3.max(data, function(d) {
return d.size;
})])
.range([10, 44]);
var color_scale = d3.scaleLinear().domain([0, 100])
.range(["#FF6138", "#00A388"]);
function draw(words) {
var cloud = svg.selectAll("g text")
.data(words);
cloud.enter()
.append("text")
.style("font-size", function(d) {
return d.size;
})
.style("fill", function(d) {
if (d.children.length == 0) {
return "none";
} else {
return color_scale(d.success);
}
})
.style("stroke", function(d) {
return color_scale(d.success);
})
.attr("text-anchor", "middle")
.style("font-family", "Impact")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) {
return d.text;
})
.classed("click-only-text", true)
.classed("word-default", true)
.on("click", handleClick);
cloud.exit()
.transition()
.duration(200)
.style('fill-opacity', 1e-6)
.attr('font-size', 1)
.remove();
}
return {
update: function(words) {
var layout = d3.layout.cloud()
.size([width, height])
.words(data.map(function(d) {
return {
text: d.name,
size: d.size,
children: d.children,
success: d.size
};
}))
.padding(5) //space between words
.rotate(function() {
return 0;
})
.fontSize(function(d) {
return font_scale(d.size);
}) // font size of words
.on("end", draw);
layout.start();
}
}
}
var myWordCloud = wordCloud('#my_dataviz');
myWordCloud.update(master_words);
Примечание: в настоящее время в коде я отправляю тот же набор данных во второе облако слов для простоты.