mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-09-29 15:30:47 +00:00
Add first pass of D3.js plugin, and a new demo wiki for it
This commit is contained in:
parent
be788f64d4
commit
5445a8b782
10
bld.sh
10
bld.sh
@ -68,6 +68,14 @@ node ./tiddlywiki.js \
|
|||||||
--savetiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/tahoelafs.html text/plain \
|
--savetiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/tahoelafs.html text/plain \
|
||||||
|| exit 1
|
|| exit 1
|
||||||
|
|
||||||
# Fifth, run the test edition to run the node.js tests and to generate test.html for tests in the browser
|
# Fifth, d3demo.html: wiki to demo d3 plugin
|
||||||
|
|
||||||
|
node ./tiddlywiki.js \
|
||||||
|
./editions/d3demo \
|
||||||
|
--verbose \
|
||||||
|
--savetiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/d3demo.html text/plain \
|
||||||
|
|| exit 1
|
||||||
|
|
||||||
|
# Sixth, run the test edition to run the node.js tests and to generate test.html for tests in the browser
|
||||||
|
|
||||||
./test.sh
|
./test.sh
|
||||||
|
3
editions/d3demo/tiddlers/DefaultTiddlers.tid
Normal file
3
editions/d3demo/tiddlers/DefaultTiddlers.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/DefaultTiddlers
|
||||||
|
|
||||||
|
[[HelloThere]]
|
10
editions/d3demo/tiddlers/GraphData.tid
Normal file
10
editions/d3demo/tiddlers/GraphData.tid
Normal file
File diff suppressed because one or more lines are too long
8
editions/d3demo/tiddlers/HelloThere.tid
Normal file
8
editions/d3demo/tiddlers/HelloThere.tid
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
title: HelloThere
|
||||||
|
|
||||||
|
This is a demo of TiddlyWiki5 incorporating a plugin for the [[D3.js]] visualization library.
|
||||||
|
|
||||||
|
<$d3bar grouped={{$:/grouped}} data="GraphData"/>
|
||||||
|
<$button set="$:/grouped" setTo="yes">grouped</$button> <$button set="$:/grouped" setTo="no">stacked</$button>
|
||||||
|
|
||||||
|
//[[Raw data|GraphData]]//
|
3
editions/d3demo/tiddlers/SiteSubtitle.tid
Normal file
3
editions/d3demo/tiddlers/SiteSubtitle.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: SiteSubtitle
|
||||||
|
|
||||||
|
a demo of the D3.js plugin for TiddlyWiki5
|
3
editions/d3demo/tiddlers/SiteTitle.tid
Normal file
3
editions/d3demo/tiddlers/SiteTitle.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: SiteTitle
|
||||||
|
|
||||||
|
d3demo
|
3
editions/d3demo/tiddlers/grouped.tid
Normal file
3
editions/d3demo/tiddlers/grouped.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/grouped
|
||||||
|
|
||||||
|
yes
|
16
editions/d3demo/tiddlywiki.info
Normal file
16
editions/d3demo/tiddlywiki.info
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"tiddlywiki/d3"
|
||||||
|
],
|
||||||
|
"themes": [
|
||||||
|
"tiddlywiki/snowwhite"
|
||||||
|
],
|
||||||
|
"doNotSave": [
|
||||||
|
"$:/StoryList",
|
||||||
|
"$:/HistoryList",
|
||||||
|
"$:/status/IsLoggedIn",
|
||||||
|
"$:/status/UserName"
|
||||||
|
],
|
||||||
|
"includeWikis": [
|
||||||
|
]
|
||||||
|
}
|
189
plugins/tiddlywiki/d3/barwidget.js
vendored
Normal file
189
plugins/tiddlywiki/d3/barwidget.js
vendored
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/plugins/tiddlywiki/d3/barwidget.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
A widget for displaying stacked or grouped bar charts. Derived from http://bl.ocks.org/mbostock/3943967
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var d3 = require("$:/plugins/tiddlywiki/d3/d3.js").d3;
|
||||||
|
|
||||||
|
var BarWidget = function(renderer) {
|
||||||
|
// Save state
|
||||||
|
this.renderer = renderer;
|
||||||
|
// Generate child nodes
|
||||||
|
this.generate();
|
||||||
|
};
|
||||||
|
|
||||||
|
BarWidget.prototype.generate = function() {
|
||||||
|
// Get the parameters
|
||||||
|
this.data = this.renderer.getAttribute("data");
|
||||||
|
this.grouped = this.renderer.getAttribute("grouped","no");
|
||||||
|
// Set the return element
|
||||||
|
this.tag = "div";
|
||||||
|
this.attributes = {
|
||||||
|
"class": "tw-barwidget"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
BarWidget.prototype.postRenderInDom = function() {
|
||||||
|
this.updateChart = this.createChart();
|
||||||
|
};
|
||||||
|
|
||||||
|
BarWidget.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.grouped) {
|
||||||
|
// Update the chart if the grouping setting has changed
|
||||||
|
this.grouped = this.renderer.getAttribute("grouped","no");
|
||||||
|
if(this.updateChart) {
|
||||||
|
this.updateChart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BarWidget.prototype.createChart = function() {
|
||||||
|
|
||||||
|
var n,m,stack,layers;
|
||||||
|
|
||||||
|
// Get the data we're plotting
|
||||||
|
var data = this.renderer.renderTree.wiki.getTiddlerData(this.data);
|
||||||
|
if(data) {
|
||||||
|
n = data.layers;
|
||||||
|
m = data.samples;
|
||||||
|
layers = data.data;
|
||||||
|
} else {
|
||||||
|
n = 4; // number of layers
|
||||||
|
m = 58; // number of samples per layer
|
||||||
|
stack = d3.layout.stack();
|
||||||
|
layers = stack(d3.range(n).map(function() { return bumpLayer(m, .1); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
var yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }),
|
||||||
|
yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });
|
||||||
|
|
||||||
|
var margin = {top: 40, right: 10, bottom: 20, left: 10},
|
||||||
|
width = 960 - margin.left - margin.right,
|
||||||
|
height = 500 - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
var x = d3.scale.ordinal()
|
||||||
|
.domain(d3.range(m))
|
||||||
|
.rangeRoundBands([0, width], .08);
|
||||||
|
|
||||||
|
var y = d3.scale.linear()
|
||||||
|
.domain([0, yStackMax])
|
||||||
|
.range([height, 0]);
|
||||||
|
|
||||||
|
var color = d3.scale.linear()
|
||||||
|
.domain([0, n - 1])
|
||||||
|
.range(["#aad", "#556"]);
|
||||||
|
|
||||||
|
var xAxis = d3.svg.axis()
|
||||||
|
.scale(x)
|
||||||
|
.tickSize(0)
|
||||||
|
.tickPadding(6)
|
||||||
|
.orient("bottom");
|
||||||
|
|
||||||
|
var svg = d3.select(this.renderer.domNode).append("svg")
|
||||||
|
.attr("viewBox", "0 0 960 500")
|
||||||
|
.attr("preserveAspectRatio", "xMinYMin meet")
|
||||||
|
.attr("width", width + margin.left + margin.right)
|
||||||
|
.attr("height", height + margin.top + margin.bottom)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
||||||
|
|
||||||
|
var layer = svg.selectAll(".layer")
|
||||||
|
.data(layers)
|
||||||
|
.enter().append("g")
|
||||||
|
.attr("class", "layer")
|
||||||
|
.style("fill", function(d, i) { return color(i); });
|
||||||
|
|
||||||
|
var rect = layer.selectAll("rect")
|
||||||
|
.data(function(d) { return d; })
|
||||||
|
.enter().append("rect")
|
||||||
|
.attr("x", function(d) { return x(d.x); })
|
||||||
|
.attr("y", height)
|
||||||
|
.attr("width", x.rangeBand())
|
||||||
|
.attr("height", 0);
|
||||||
|
|
||||||
|
rect.transition()
|
||||||
|
.delay(function(d, i) { return i * 10; })
|
||||||
|
.attr("y", function(d) { return y(d.y0 + d.y); })
|
||||||
|
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); });
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "x axis")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
.call(xAxis);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
return function updateChart() {
|
||||||
|
if (self.grouped !== "no") {
|
||||||
|
transitionGrouped();
|
||||||
|
} else {
|
||||||
|
transitionStacked();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function transitionGrouped() {
|
||||||
|
y.domain([0, yGroupMax]);
|
||||||
|
|
||||||
|
rect.transition()
|
||||||
|
.duration(500)
|
||||||
|
.delay(function(d, i) { return i * 10; })
|
||||||
|
.attr("x", function(d, i, j) { return x(d.x) + x.rangeBand() / n * j; })
|
||||||
|
.attr("width", x.rangeBand() / n)
|
||||||
|
.transition()
|
||||||
|
.attr("y", function(d) { return y(d.y); })
|
||||||
|
.attr("height", function(d) { return height - y(d.y); });
|
||||||
|
}
|
||||||
|
|
||||||
|
function transitionStacked() {
|
||||||
|
y.domain([0, yStackMax]);
|
||||||
|
|
||||||
|
rect.transition()
|
||||||
|
.duration(500)
|
||||||
|
.delay(function(d, i) { return i * 10; })
|
||||||
|
.attr("y", function(d) { return y(d.y0 + d.y); })
|
||||||
|
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
|
||||||
|
.transition()
|
||||||
|
.attr("x", function(d) { return x(d.x); })
|
||||||
|
.attr("width", x.rangeBand());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inspired by Lee Byron's test data generator.
|
||||||
|
function bumpLayer(n, o) {
|
||||||
|
|
||||||
|
function bump(a) {
|
||||||
|
var x = 1 / (.1 + Math.random()),
|
||||||
|
y = 2 * Math.random() - .5,
|
||||||
|
z = 10 / (.1 + Math.random());
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
var w = (i / n - y) * z;
|
||||||
|
a[i] += x * Math.exp(-w * w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var a = [], i;
|
||||||
|
for (i = 0; i < n; ++i) a[i] = o + o * Math.random();
|
||||||
|
for (i = 0; i < 5; ++i) bump(a);
|
||||||
|
return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.d3bar = BarWidget;
|
||||||
|
|
||||||
|
})();
|
18
plugins/tiddlywiki/d3/base.tid
Normal file
18
plugins/tiddlywiki/d3/base.tid
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
title: $:/plugins/tiddlywiki/d3/base.tid
|
||||||
|
tags: [[$:/tags/stylesheet]]
|
||||||
|
|
||||||
|
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline
|
||||||
|
|
||||||
|
.tw-barwidget {
|
||||||
|
}
|
||||||
|
|
||||||
|
.tw-barwidget text {
|
||||||
|
font: 8px sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tw-barwidget .axis path,
|
||||||
|
.tw-barwidget .axis line {
|
||||||
|
fill: none;
|
||||||
|
stroke: #000;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
5
plugins/tiddlywiki/d3/files/d3.min.js
vendored
Normal file
5
plugins/tiddlywiki/d3/files/d3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
14
plugins/tiddlywiki/d3/files/tiddlywiki.files
Normal file
14
plugins/tiddlywiki/d3/files/tiddlywiki.files
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"tiddlers": [
|
||||||
|
{
|
||||||
|
"file": "d3.min.js",
|
||||||
|
"fields": {
|
||||||
|
"type": "application/javascript",
|
||||||
|
"title": "$:/plugins/tiddlywiki/d3/d3.js",
|
||||||
|
"module-type": "library"
|
||||||
|
},
|
||||||
|
"prefix": "var d3;if($tw.browser){\n",
|
||||||
|
"suffix": "}\nexports.d3 = d3;\n"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
plugins/tiddlywiki/d3/plugin.info
Normal file
7
plugins/tiddlywiki/d3/plugin.info
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"title": "$:/plugins/tiddlywiki/d3",
|
||||||
|
"description": "d3.js plugin for TiddlyWiki5",
|
||||||
|
"author": "JeremyRuston",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"core-version": ">=5.0.0"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user