TiddlyWiki5/plugins/tiddlywiki/d3/cloudwidget.js

120 wiersze
3.1 KiB
JavaScript

/*\
title: $:/plugins/tiddlywiki/d3/cloudwidget.js
type: application/javascript
module-type: widget
A widget for displaying word clouds. Derived from https://github.com/jasondavies/d3-cloud
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var d3 = require("$:/plugins/tiddlywiki/d3/d3.js").d3;
if($tw.browser) {
// Frightful hack to give the cloud plugin the global d3 variable it needs
window.d3 = d3;
d3.layout.cloud = require("$:/plugins/tiddlywiki/d3/d3.layout.cloud.js").cloud;
}
var CloudWidget = function(renderer) {
// Save state
this.renderer = renderer;
// Generate child nodes
this.generate();
};
CloudWidget.prototype.generate = function() {
// Get the parameters
this.data = this.renderer.getAttribute("data");
this.spiral = this.renderer.getAttribute("spiral","archimedean");
// Set the return element
this.tag = "div";
this.attributes = {
"class": "tw-cloudwidget"
};
};
CloudWidget.prototype.postRenderInDom = function() {
this.updateChart = this.createChart();
};
CloudWidget.prototype.refreshInDom = function(changedAttributes,changedTiddlers) {
// Reexecute the widget if the data reference attributes have changed
if(changedAttributes.data || changedTiddlers[this.data]) {
// Regenerate and rerender the widget and replace the existing DOM node
this.generate();
var oldDomNode = this.renderer.domNode,
newDomNode = this.renderer.renderInDom();
oldDomNode.parentNode.replaceChild(newDomNode,oldDomNode);
} else if(changedAttributes.spiral) {
// Update the chart if the spiral setting has changed
this.spiral = this.renderer.getAttribute("spiral","archimedean");
if(this.updateChart) {
this.updateChart();
}
}
};
CloudWidget.prototype.createChart = function() {
var self = this;
var domNode = this.renderer.domNode;
var fill = d3.scale.category20();
var data = this.renderer.renderTree.wiki.getTiddlerData(this.data);
if(!data) {
// Use dummy data if none provided
data = "This word cloud does not have any data in it".split(" ").map(function(d) {
return {text: d, size: 10 + Math.random() * 90};
})
}
var svg = d3.select(domNode).append("svg")
.attr("width", 600)
.attr("height", 400)
.append("g")
.attr("transform", "translate(300,200)");
var layout = d3.layout.cloud().size([600, 400])
.words(data)
.padding(5)
.rotate(function() { return ~~(Math.random() * 5) * 30 - 60; })
.font("Impact")
.fontSize(function(d) { return d.size*2; })
.on("end", draw)
.start();
function draw(words) {
svg.selectAll("text")
.data(words)
.enter().append("text")
.style("font-size", function(d) { return d.size + "px"; })
.style("font-family", "Impact")
.style("fill", function(d, i) { return fill(i); })
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) { return d.text; });
}
function updateChart() {
layout.spiral(self.spiral);
}
return updateChart;
};
exports.d3cloud = CloudWidget;
})();