158 lines
4.6 KiB
JavaScript
158 lines
4.6 KiB
JavaScript
// easy d3-based word cloud plugin https://github.com/wvengen/d3-wordcloud
|
|
// requires https://github.com/jasondavies/d3-cloud
|
|
// based on https://github.com/shprink/d3js-wordcloud
|
|
(function() {
|
|
function wordcloud() {
|
|
var selector = '#wordcloud',
|
|
element = d3.select(selector),
|
|
transitionDuration = 200,
|
|
scale = 'sqrt',
|
|
fill = d3.scale.category20b(),
|
|
layout = d3.layout.cloud(),
|
|
fontSize = null,
|
|
svg = null,
|
|
vis = null,
|
|
onwordclick = undefined;
|
|
|
|
wordcloud.element = function(x) {
|
|
if (!arguments.length) return element;
|
|
element = x == null ? '#wordcloud' : x;
|
|
return wordcloud
|
|
};
|
|
|
|
wordcloud.selector = function(x) {
|
|
if (!arguments.length) return selector;
|
|
element = d3.select(x == null ? selector : x);
|
|
return wordcloud;
|
|
};
|
|
|
|
wordcloud.transitionDuration = function(x) {
|
|
if (!arguments.length) return transitionDuration;
|
|
transitionDuration = typeof x == 'function' ? x() : x;
|
|
return wordcloud;
|
|
};
|
|
|
|
wordcloud.scale = function(x) {
|
|
if (!arguments.length) return scale;
|
|
scale = x == null ? 'sqrt' : x;
|
|
return wordcloud;
|
|
};
|
|
|
|
wordcloud.fill = function(x) {
|
|
if (!arguments.length) return fill;
|
|
fill = x == null ? d3.scale.category20b() : x;
|
|
return wordcloud;
|
|
};
|
|
|
|
wordcloud.onwordclick = function (func) {
|
|
onwordclick = func;
|
|
return wordcloud;
|
|
}
|
|
|
|
wordcloud.start = function() {
|
|
init();
|
|
layout.start(arguments);
|
|
return wordcloud;
|
|
};
|
|
|
|
function init() {
|
|
layout
|
|
.fontSize(function(d) {
|
|
return fontSize(+d.size);
|
|
})
|
|
.text(function(d) {
|
|
return d.text;
|
|
})
|
|
.on("end", draw);
|
|
|
|
svg = element.append("svg");
|
|
vis = svg.append("g").attr("transform", "translate(" + [layout.size()[0] >> 1, layout.size()[1] >> 1] + ")");
|
|
|
|
update();
|
|
svg.on('resize', function() { update() });
|
|
}
|
|
|
|
function draw(data, bounds) {
|
|
var w = layout.size()[0],
|
|
h = layout.size()[1];
|
|
|
|
svg.attr("width", w).attr("height", h);
|
|
|
|
scaling = 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(transitionDuration)
|
|
.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(transitionDuration)
|
|
.style("opacity", 1);
|
|
text.style("font-family", function(d) {
|
|
return d.font || layout.font() || svg.style("font-family");
|
|
})
|
|
.style("fill", function(d) {
|
|
return fill(d.text.toLowerCase());
|
|
})
|
|
.text(function(d) {
|
|
return d.text;
|
|
})
|
|
// clickable words
|
|
.style("cursor", function(d, i) {
|
|
if (onwordclick !== undefined) return 'pointer';
|
|
})
|
|
.on("mouseover", function(d, i) {
|
|
if (onwordclick !== undefined) {
|
|
d3.select(this).transition().style('font-size', d.size + 3 + 'px');
|
|
}
|
|
})
|
|
.on("mouseout", function(d, i) {
|
|
if (onwordclick !== undefined) {
|
|
d3.select(this).transition().style('font-size', d.size + 'px');
|
|
}
|
|
})
|
|
.on("click", function(d, i) {
|
|
if (onwordclick !== undefined) {
|
|
onwordclick(d,i);
|
|
}
|
|
});
|
|
|
|
vis.transition()
|
|
.attr("transform", "translate(" + [w >> 1, h >> 1] + ")scale(" + scaling + ")");
|
|
};
|
|
|
|
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]);
|
|
}
|
|
}
|
|
|
|
return d3.rebind(wordcloud, layout, 'on', 'words', 'size', 'font', 'fontStyle', 'fontWeight', 'spiral', 'padding');
|
|
}
|
|
|
|
if (typeof module === "object" && module.exports) module.exports = wordcloud;
|
|
else d3.wordcloud = wordcloud;
|
|
})();
|