@andyreagan/hedotools 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +4 -0
- package/bundle.sh +11 -0
- package/code-versions.md +164 -0
- package/css/hedotools.shift.css +36 -0
- package/fonts/cmr10.ttf +0 -0
- package/fonts/cmr10.woff +0 -0
- package/js/cloud.min.js +1 -0
- package/js/d3.layout.cloud.js +505 -0
- package/js/hedotools.barchart.js +348 -0
- package/js/hedotools.init.js +59 -0
- package/js/hedotools.init.v4.js +69 -0
- package/js/hedotools.lens.js +353 -0
- package/js/hedotools.map.js +576 -0
- package/js/hedotools.sankey.js +550 -0
- package/js/hedotools.shifter.js +4042 -0
- package/js/hedotools.shifter.v4.js +3995 -0
- package/js/hedotools.urllib.js +186 -0
- package/js/shift-crowbar.js +106 -0
- package/package.json +28 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/*
|
|
2
|
+
hedotools.urllib
|
|
3
|
+
=========
|
|
4
|
+
|
|
5
|
+
a simple hedotools plugin to manage pushing and pulling the visualization state to the brower url
|
|
6
|
+
|
|
7
|
+
tests
|
|
8
|
+
-----
|
|
9
|
+
no test suite, I've tested in in Chrome v35 for reasonable use cases
|
|
10
|
+
|
|
11
|
+
example
|
|
12
|
+
-------
|
|
13
|
+
also no simple example, but you can see it in use here:
|
|
14
|
+
http://www.uvm.edu/storylab/share/papers/dodds2014a/books.html
|
|
15
|
+
|
|
16
|
+
documentation
|
|
17
|
+
-------------
|
|
18
|
+
slightly more documentation in the README
|
|
19
|
+
|
|
20
|
+
new:
|
|
21
|
+
|
|
22
|
+
decoder returns { current, cached } values
|
|
23
|
+
the current will be blank if there is nothing in the url
|
|
24
|
+
but the cached remains
|
|
25
|
+
I like this feature
|
|
26
|
+
|
|
27
|
+
*/
|
|
28
|
+
hedotools.urllib = {
|
|
29
|
+
encoder: function() {
|
|
30
|
+
var varname = "tmp";
|
|
31
|
+
var varval = [];
|
|
32
|
+
var show = true;
|
|
33
|
+
//var that = this;
|
|
34
|
+
|
|
35
|
+
function urllib(d) {
|
|
36
|
+
// nothing yet
|
|
37
|
+
//console.log(this);
|
|
38
|
+
//console.log(that);
|
|
39
|
+
return {current: varval,};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function parseurl() {
|
|
43
|
+
GET = {};
|
|
44
|
+
query = window.location.search.substring(1).split("&");
|
|
45
|
+
// break down the url
|
|
46
|
+
for (var i = 0, max = query.length; i < max; i++)
|
|
47
|
+
{
|
|
48
|
+
if (query[i] === "") // check for trailing & with no param
|
|
49
|
+
continue;
|
|
50
|
+
var param = query[i].split("=");
|
|
51
|
+
GET[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || "");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
baseUrl = window.location.origin+window.location.pathname;
|
|
55
|
+
var tmpStr = ""
|
|
56
|
+
if (typeof varval == 'string' || varval instanceof String)
|
|
57
|
+
{ tmpStr+=varval; }
|
|
58
|
+
else
|
|
59
|
+
{
|
|
60
|
+
tmpStr += "["+varval[0]
|
|
61
|
+
for (var i=1; i<varval.length; i++) { tmpStr += ","+varval[i]; }
|
|
62
|
+
tmpStr+="]"
|
|
63
|
+
}
|
|
64
|
+
GET[varname] = tmpStr;
|
|
65
|
+
|
|
66
|
+
var urlString = ""
|
|
67
|
+
for (var key in GET) {
|
|
68
|
+
if (GET.hasOwnProperty(key)) {
|
|
69
|
+
if (varname === key) {
|
|
70
|
+
// console.log("found that variable");
|
|
71
|
+
// console.log(show);
|
|
72
|
+
if (show) {
|
|
73
|
+
urlString += key+"="+GET[key]+"&";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else { urlString += key+"="+GET[key]+"&"; }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
urlString = urlString.substring(0,urlString.length-1);
|
|
81
|
+
|
|
82
|
+
// only add to url if there is stuff
|
|
83
|
+
if (urlString.length > 0) {
|
|
84
|
+
newDataUrl = baseUrl+"?"+urlString
|
|
85
|
+
}
|
|
86
|
+
else { newDataUrl = baseUrl; }
|
|
87
|
+
|
|
88
|
+
window.history.replaceState("object or string", "title",newDataUrl);
|
|
89
|
+
|
|
90
|
+
return urllib;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
urllib.varname = function(_) {
|
|
94
|
+
if (!arguments.length) return varname;
|
|
95
|
+
varname = _;
|
|
96
|
+
return urllib;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
urllib.destroy = function() {
|
|
100
|
+
show = false;
|
|
101
|
+
parseurl();
|
|
102
|
+
show = true;
|
|
103
|
+
// return urllib;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
urllib.varval = function(_) {
|
|
107
|
+
if (!arguments.length) return varval;
|
|
108
|
+
varval = _;
|
|
109
|
+
return parseurl();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return urllib;
|
|
113
|
+
},
|
|
114
|
+
decoder: function() {
|
|
115
|
+
var varname = "tmp";
|
|
116
|
+
var varresult = [];
|
|
117
|
+
var defvalue = [];
|
|
118
|
+
|
|
119
|
+
function urllib(d) {
|
|
120
|
+
parseurl();
|
|
121
|
+
return {current: varresult,
|
|
122
|
+
cached: defvalue};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function parseurl() {
|
|
126
|
+
GET = {};
|
|
127
|
+
query = window.location.search.substring(1).split("&");
|
|
128
|
+
for (var i = 0, max = query.length; i < max; i++) {
|
|
129
|
+
if (query[i] === "") // check for trailing & with no param
|
|
130
|
+
continue;
|
|
131
|
+
var param = query[i].split("=");
|
|
132
|
+
GET[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || "");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (varname in GET) {
|
|
136
|
+
if (GET[varname].length > 0 && GET[varname][0] === "[") {
|
|
137
|
+
if (GET[varname][GET[varname].length-1] === "]") {
|
|
138
|
+
var tmpArray = GET[varname].substring(1, GET[varname].length - 1).split(',');
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
var tmpArray = GET[varname].substring(1, GET[varname].length).split(',');
|
|
142
|
+
}
|
|
143
|
+
varresult = tmpArray;
|
|
144
|
+
defvalue = tmpArray;
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
varresult = GET[varname];
|
|
148
|
+
defvalue = GET[varname];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// if there is nothing in the url...we'll let the value
|
|
153
|
+
// live. this next line would kill the value
|
|
154
|
+
varresult = ""
|
|
155
|
+
}
|
|
156
|
+
return urllib;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
urllib.varname = function(_) {
|
|
160
|
+
if (!arguments.length) return varname;
|
|
161
|
+
varname = _;
|
|
162
|
+
return parseurl();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
urllib.varresult = function(_) {
|
|
166
|
+
if (!arguments.length) return varresult;
|
|
167
|
+
varresult = _;
|
|
168
|
+
defvalue = _;
|
|
169
|
+
return urllib;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return urllib;
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
var page = require('webpage').create();
|
|
2
|
+
var system = require('system');
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var address;
|
|
5
|
+
var selector;
|
|
6
|
+
var output;
|
|
7
|
+
|
|
8
|
+
if (system.args.length < 4) {
|
|
9
|
+
console.log('Usage: phantom-crowbar.js <some URL> <selector> <outputfile>');
|
|
10
|
+
phantom.exit();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
address = system.args[1];
|
|
14
|
+
selector = system.args[2];
|
|
15
|
+
output = system.args[3];
|
|
16
|
+
|
|
17
|
+
// logging
|
|
18
|
+
page.onConsoleMessage = function(msg) {
|
|
19
|
+
console.log('Console: '+msg);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// big screen
|
|
23
|
+
page.viewportSize = {
|
|
24
|
+
width: 1400,
|
|
25
|
+
height: 800
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// open dat page
|
|
29
|
+
page.open(address, function(status) {
|
|
30
|
+
if (status !== 'success') {
|
|
31
|
+
console.log('FAIL to load the address');
|
|
32
|
+
phantom.exit();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
var out = page.evaluate(function(s) {
|
|
36
|
+
// get rid of the credit and button entirely
|
|
37
|
+
d3.selectAll('g.resetbutton').remove();
|
|
38
|
+
d3.selectAll('.credit').remove();
|
|
39
|
+
|
|
40
|
+
// nice way
|
|
41
|
+
// hedotools.shifter.resetbuttontoggle(false);
|
|
42
|
+
|
|
43
|
+
// actually get the svg out, using a lot of the crowbar code
|
|
44
|
+
var source = '';
|
|
45
|
+
var doctype = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
|
|
46
|
+
var prefix = {
|
|
47
|
+
xmlns: "http://www.w3.org/2000/xmlns/",
|
|
48
|
+
xlink: "http://www.w3.org/1999/xlink",
|
|
49
|
+
svg: "http://www.w3.org/2000/svg"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var styles = '';
|
|
53
|
+
var styleSheets = document.styleSheets;
|
|
54
|
+
|
|
55
|
+
for (var i=0; i < styleSheets.length; i++) {
|
|
56
|
+
processStyleSheet(styleSheets[i]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// much simplified code from the crowbar
|
|
60
|
+
// don't care about illustrator
|
|
61
|
+
// and i don't use import rules
|
|
62
|
+
function processStyleSheet(ss) {
|
|
63
|
+
if (ss.cssRules) {
|
|
64
|
+
for (var i = 0; i < ss.cssRules.length; i++) {
|
|
65
|
+
var rule = ss.cssRules[i];
|
|
66
|
+
styles += "\n" + rule.cssText;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// mostly untouched from the crowbar
|
|
72
|
+
var svg = document.getElementById(s);
|
|
73
|
+
svg.setAttribute("version", "1.1");
|
|
74
|
+
|
|
75
|
+
var defsEl = document.createElement("defs");
|
|
76
|
+
svg.insertBefore(defsEl, svg.firstChild);
|
|
77
|
+
var styleEl = document.createElement("style")
|
|
78
|
+
defsEl.appendChild(styleEl);
|
|
79
|
+
styleEl.setAttribute("type", "text/css");
|
|
80
|
+
svg.removeAttribute("xmlns");
|
|
81
|
+
svg.removeAttribute("xlink");
|
|
82
|
+
// These are needed for the svg
|
|
83
|
+
if (!svg.hasAttributeNS(prefix.xmlns, "xmlns")) {
|
|
84
|
+
svg.setAttributeNS(prefix.xmlns, "xmlns", prefix.svg);
|
|
85
|
+
}
|
|
86
|
+
if (!svg.hasAttributeNS(prefix.xmlns, "xmlns:xlink")) {
|
|
87
|
+
svg.setAttributeNS(prefix.xmlns, "xmlns:xlink", prefix.xlink);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
var svgxml = (new XMLSerializer()).serializeToString(svg)
|
|
91
|
+
.replace('</style>', '<![CDATA[' + styles + ']]></style>');
|
|
92
|
+
source += doctype + svgxml;
|
|
93
|
+
|
|
94
|
+
return source;
|
|
95
|
+
|
|
96
|
+
}, selector);
|
|
97
|
+
|
|
98
|
+
// write it out to a file
|
|
99
|
+
fs.write(output,out,'w');
|
|
100
|
+
console.log('Evaluated our code');
|
|
101
|
+
phantom.exit();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@andyreagan/hedotools",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "A collection of D3.js tools in use at hedonometer.org: word shifts, choropleth maps, sankey diagrams, a frequency lens, and bar charts. Version tracks the supported D3 major version (3.x = D3 v3).",
|
|
5
|
+
"author": "Andy Reagan",
|
|
6
|
+
"license": "BSD-2-Clause",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/andyreagan/hedotools.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/andyreagan/hedotools#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/andyreagan/hedotools/issues"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"js",
|
|
17
|
+
"css",
|
|
18
|
+
"fonts",
|
|
19
|
+
"bundle.sh",
|
|
20
|
+
"code-versions.md"
|
|
21
|
+
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"d3": "^4.13.0",
|
|
24
|
+
"d3-selection": "^1.3.0",
|
|
25
|
+
"d3-selection-multi": "^1.0.1",
|
|
26
|
+
"jquery": "^3.5.1"
|
|
27
|
+
}
|
|
28
|
+
}
|