@andyreagan/hedotools 7.0.0 → 7.2.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/README.md +168 -1
- package/bundle.sh +40 -16
- package/dist/hedotools-bundle.js +5006 -0
- package/dist/hedotools.js +2125 -0
- package/js/hedotools.barchart.js +17 -1
- package/js/hedotools.computeHapps.js +18 -0
- package/js/hedotools.lens.js +1 -1
- package/js/hedotools.map.js +1 -1
- package/js/hedotools.nonsankey.js +580 -0
- package/js/hedotools.sankey.js +1 -1
- package/package.json +11 -2
package/js/hedotools.barchart.js
CHANGED
|
@@ -24,6 +24,16 @@ hedotools.barchartoncall = function() {
|
|
|
24
24
|
return opublic;
|
|
25
25
|
}();
|
|
26
26
|
|
|
27
|
+
// mousedown ("click-to-open") hook: an empty stub by default; the host page
|
|
28
|
+
// overrides hedotools.barchartonclick.test to open the linked shift/modal.
|
|
29
|
+
hedotools.barchartonclick = function() {
|
|
30
|
+
var test = function(event,d) {
|
|
31
|
+
}
|
|
32
|
+
var opublic = { test: test,
|
|
33
|
+
};
|
|
34
|
+
return opublic;
|
|
35
|
+
}();
|
|
36
|
+
|
|
27
37
|
// make the plot
|
|
28
38
|
hedotools.barchart = function() {
|
|
29
39
|
var figure;
|
|
@@ -271,6 +281,9 @@ hedotools.barchart = function() {
|
|
|
271
281
|
.on('mouseout', function(event,d){
|
|
272
282
|
var rectSelection = d3.select(this).style('opacity','1.0').style('stroke','rgb(100,100,100)').style('stroke-width','1.0');
|
|
273
283
|
// var rectSelection = d3.select(this).style({opacity:'0.7'});
|
|
284
|
+
})
|
|
285
|
+
.on('mousedown', function(event,d){
|
|
286
|
+
hedotools.barchartonclick.test(d,d[0]);
|
|
274
287
|
});
|
|
275
288
|
|
|
276
289
|
axes.selectAll("text.statetext")
|
|
@@ -284,6 +297,9 @@ hedotools.barchart = function() {
|
|
|
284
297
|
.text(function(d,i) { return (i+1)+". "+d[2]; })
|
|
285
298
|
.on('mouseover', function(event,d){
|
|
286
299
|
hedotools.barchartoncall.test(d,d[0]);
|
|
300
|
+
})
|
|
301
|
+
.on('mousedown', function(event,d){
|
|
302
|
+
hedotools.barchartonclick.test(d,d[0]);
|
|
287
303
|
});
|
|
288
304
|
|
|
289
305
|
// d3.select(window).on("resize.shiftplot",resizeshift);
|
|
@@ -334,7 +350,7 @@ hedotools.barchart = function() {
|
|
|
334
350
|
plot: plot, };
|
|
335
351
|
|
|
336
352
|
return opublic;
|
|
337
|
-
};
|
|
353
|
+
}();
|
|
338
354
|
|
|
339
355
|
|
|
340
356
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
hedotools.computeHapps = function() {
|
|
2
|
+
var go = function () {
|
|
3
|
+
for (var j=0; j<52; j++) {
|
|
4
|
+
// compute total frequency
|
|
5
|
+
var N = 0.0;
|
|
6
|
+
for (var i=0; i<allData[j].freq.length; i++) {
|
|
7
|
+
N += parseFloat(allData[j].freq[i]);
|
|
8
|
+
}
|
|
9
|
+
var happs = 0.0;
|
|
10
|
+
for (var i=0; i<allData[j].freq.length; i++) {
|
|
11
|
+
happs += parseFloat(allData[j].freq[i])*parseFloat(lens[i]);
|
|
12
|
+
}
|
|
13
|
+
allData[j].avhapps = happs/N;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
var opublic = { go: go, };
|
|
17
|
+
return opublic;
|
|
18
|
+
}();
|
package/js/hedotools.lens.js
CHANGED
package/js/hedotools.map.js
CHANGED
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
hedotools.sankeyoncall = function() {
|
|
2
|
+
var test = function(i,data) {
|
|
3
|
+
console.log("set in module");
|
|
4
|
+
|
|
5
|
+
console.log(allDataOld);
|
|
6
|
+
|
|
7
|
+
var shiftObj = hedotools.shifter.shift(allDataOld[data[i].index].freq,allData[data[i].index].freq,lens,words);
|
|
8
|
+
|
|
9
|
+
shiftObj.setfigure(d3.select('#shift01')).setText("Why "+data[i].name+" has become "+((allDataOld[data[i].index].avhapps < allData[data[i].index].avhapps) ? "happier" : "less happy")+":").plot();
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
var opublic = { test: test, };
|
|
14
|
+
return opublic;
|
|
15
|
+
}();
|
|
16
|
+
|
|
17
|
+
hedotools.sankey = function() {
|
|
18
|
+
|
|
19
|
+
var popuptimer;
|
|
20
|
+
|
|
21
|
+
var figure;
|
|
22
|
+
|
|
23
|
+
var setfigure = function(_) {
|
|
24
|
+
console.log("setting figure");
|
|
25
|
+
figure = _;
|
|
26
|
+
// grabwidth();
|
|
27
|
+
return hedotools.sankey;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var oldlist;
|
|
31
|
+
var newlist;
|
|
32
|
+
var stateNames;
|
|
33
|
+
|
|
34
|
+
var oldindices;
|
|
35
|
+
var newindices;
|
|
36
|
+
var data;
|
|
37
|
+
|
|
38
|
+
var setdata = function(a,b,c) {
|
|
39
|
+
oldlist = a;
|
|
40
|
+
newlist = b;
|
|
41
|
+
stateNames = c;
|
|
42
|
+
if ( stateNames[50] === "District of Columbia" ) {
|
|
43
|
+
stateNames[50] = "DC";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// do the sorting
|
|
47
|
+
oldindices = Array(oldlist.length);
|
|
48
|
+
for (var i = 0; i < oldlist.length; i++) { oldindices[i] = i; }
|
|
49
|
+
|
|
50
|
+
// sort by abs magnitude
|
|
51
|
+
// oldindices.sort(function(a,b) { return Math.abs(data[a]) < Math.abs(data[b]) ? 1 : Math.abs(data[a]) > Math.abs(data[b]) ? -1 : 0; });
|
|
52
|
+
|
|
53
|
+
// sort by magnitude, parity preserving
|
|
54
|
+
oldindices.sort(function(a,b) { return oldlist[a] < oldlist[b] ? 1 : oldlist[a] > oldlist[b] ? -1 : 0; });
|
|
55
|
+
|
|
56
|
+
// do the sorting on new data
|
|
57
|
+
newindices = Array(newlist.length);
|
|
58
|
+
for (var i = 0; i < newlist.length; i++) { newindices[i] = i; }
|
|
59
|
+
|
|
60
|
+
newindices.sort(function(a,b) { return newlist[a] < newlist[b] ? 1 : newlist[a] > newlist[b] ? -1 : 0; });
|
|
61
|
+
|
|
62
|
+
data = Array(oldlist.length);
|
|
63
|
+
for (var i=0; i<data.length; i++) {
|
|
64
|
+
data[i] = {
|
|
65
|
+
"name": stateNames[i],
|
|
66
|
+
"index": i,
|
|
67
|
+
"oldindex": oldindices.indexOf(i),
|
|
68
|
+
"newindex": newindices.indexOf(i),
|
|
69
|
+
"change": newlist[i]-oldlist[i],
|
|
70
|
+
"oldhapps": oldlist[i],
|
|
71
|
+
"newhapps": newlist[i],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// console.log(data);
|
|
76
|
+
// tmpglob = data;
|
|
77
|
+
|
|
78
|
+
return hedotools.sankey;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// initialize everything so other function in this module have access
|
|
82
|
+
var margin;
|
|
83
|
+
var axeslabelmargin;
|
|
84
|
+
var figwidth;
|
|
85
|
+
var aspectRatio;
|
|
86
|
+
var figheight;
|
|
87
|
+
var width;
|
|
88
|
+
var height;
|
|
89
|
+
var figcenter;
|
|
90
|
+
var leftOffsetStatic;
|
|
91
|
+
|
|
92
|
+
var canvas;
|
|
93
|
+
var x;
|
|
94
|
+
var y;
|
|
95
|
+
var axes;
|
|
96
|
+
|
|
97
|
+
var oldstateselection;
|
|
98
|
+
var newstateselction;
|
|
99
|
+
var path;
|
|
100
|
+
var sankeydata;
|
|
101
|
+
var pathwidth;
|
|
102
|
+
var pathselection;
|
|
103
|
+
|
|
104
|
+
var listlabels;
|
|
105
|
+
var extraSideWidth = [0,0];
|
|
106
|
+
|
|
107
|
+
var useTip = false;
|
|
108
|
+
var tip;
|
|
109
|
+
|
|
110
|
+
var minwidth = 450;
|
|
111
|
+
|
|
112
|
+
// make the plot
|
|
113
|
+
var plot = function() {
|
|
114
|
+
margin = {top: 0, right: 0, bottom: 0, left: 0};
|
|
115
|
+
axeslabelmargin = {top: 0, right: 0+extraSideWidth[0], bottom: 0, left: 0+extraSideWidth[1]};
|
|
116
|
+
figwidth = parseInt(figure.style('width')) - margin.left - margin.right;
|
|
117
|
+
if (figwidth<minwidth) {
|
|
118
|
+
console.log("width is too small...");
|
|
119
|
+
d3.selectAll(".reftimelabel,.comptimelabel,.reftimelabelbottom,.comptimelabelbottom").remove();
|
|
120
|
+
figure.append("text").text("Unfortunately, this visualization will look terrible on your device. If you're on a phone, try rotating and refreshing, or looking from a desktop. Thanks :)");
|
|
121
|
+
return hedotools.sankey;
|
|
122
|
+
}
|
|
123
|
+
aspectRatio = 1.8+3.4*(oldlist.length-51)/(304-51);
|
|
124
|
+
figheight = parseInt(figure.style('width'))*aspectRatio - margin.top - margin.bottom;
|
|
125
|
+
// console.log("figheight is "+figheight);
|
|
126
|
+
// figheight = 4576; // for the city sankey this seems good
|
|
127
|
+
width = figwidth-axeslabelmargin.left-axeslabelmargin.right;
|
|
128
|
+
height = figheight-axeslabelmargin.top-axeslabelmargin.bottom;
|
|
129
|
+
figcenter = width/2;
|
|
130
|
+
leftOffsetStatic = axeslabelmargin.left;
|
|
131
|
+
|
|
132
|
+
var hovergroup = figure.append("div").attr("class", "hoverinfogroup")
|
|
133
|
+
// .style("transform", "translate("+(x+hoverboxxoffset+axeslabelmargin.left)+","+(d3.min([d3.max([0,y-hoverboxheight/2-hoverboxyoffset]),height-hoverboxheight]))+")")
|
|
134
|
+
.style("position", "absolute")
|
|
135
|
+
.style("top", "100px")
|
|
136
|
+
.style("left", "100px")
|
|
137
|
+
.style("visibility", "hidden");
|
|
138
|
+
|
|
139
|
+
function hidehover() {
|
|
140
|
+
console.log("hiding hover");
|
|
141
|
+
hovergroup.style("visibility", "hidden");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// remove an old figure if it exists
|
|
145
|
+
figure.select(".canvas").remove();
|
|
146
|
+
|
|
147
|
+
canvas = figure.append("svg")
|
|
148
|
+
.attr("width",figwidth)
|
|
149
|
+
.attr("height",figheight)
|
|
150
|
+
.attr("class","canvas")
|
|
151
|
+
|
|
152
|
+
// x scale, maps all the data to
|
|
153
|
+
x = d3.scaleLinear()
|
|
154
|
+
.domain([0,1])
|
|
155
|
+
.range([5,width-10]);
|
|
156
|
+
|
|
157
|
+
// linear scale function
|
|
158
|
+
y = d3.scaleLinear()
|
|
159
|
+
.domain([newlist.length,1])
|
|
160
|
+
.range([height-20, 0]);
|
|
161
|
+
|
|
162
|
+
// create the axes themselves
|
|
163
|
+
axes = canvas.append("g")
|
|
164
|
+
.attr("transform", "translate(" + (axeslabelmargin.left) + "," +
|
|
165
|
+
(axeslabelmargin.top) + ")")
|
|
166
|
+
.attr("width", width)
|
|
167
|
+
.attr("height", height)
|
|
168
|
+
.attr("class", "main");
|
|
169
|
+
|
|
170
|
+
// if (useTip) {
|
|
171
|
+
// console.log("setting tip");
|
|
172
|
+
// tip = d3.tip().attr('class', 'd3-tip').html(function(d) { return d; });
|
|
173
|
+
// axes.call(tip);
|
|
174
|
+
// }
|
|
175
|
+
|
|
176
|
+
oldstateselection = axes.selectAll("text.statetext.old")
|
|
177
|
+
.data(data)
|
|
178
|
+
.enter()
|
|
179
|
+
.append("text")
|
|
180
|
+
.attr("class", function(d,i) { return d.name+" statetext"; })
|
|
181
|
+
.attr("x",20)
|
|
182
|
+
.style("text-anchor", "start")
|
|
183
|
+
.attr("y",function(d,i) { return y(d.oldindex+1)+11; } )
|
|
184
|
+
.text(function(d,i) { return (d.oldindex+1)+". "+d.name; })
|
|
185
|
+
.on("mouseover", function(event, d) {
|
|
186
|
+
var i = d.index;
|
|
187
|
+
var hoverboxheight = 90;
|
|
188
|
+
var hoverboxwidth = 200;
|
|
189
|
+
var hoverboxyoffset = 0;
|
|
190
|
+
var hoverboxxoffset = 0;
|
|
191
|
+
|
|
192
|
+
var x = d3.pointer(event, this)[0];
|
|
193
|
+
var y = d3.pointer(event, this)[1];
|
|
194
|
+
|
|
195
|
+
var hoverboxheightguess = 190;
|
|
196
|
+
if (refcity.length > 0) {
|
|
197
|
+
hoverboxheightguess = 270;
|
|
198
|
+
}
|
|
199
|
+
if ((y+hoverboxheightguess)>height) { y-=(y+hoverboxheightguess-height); }
|
|
200
|
+
|
|
201
|
+
hovergroup.style("position", "absolute")
|
|
202
|
+
.style("top", y+"px")
|
|
203
|
+
.style("left", x+"px")
|
|
204
|
+
.style("visibility", "visible");
|
|
205
|
+
|
|
206
|
+
hovergroup.selectAll("p,h3,button,br").remove();
|
|
207
|
+
|
|
208
|
+
hovergroup.append("h3")
|
|
209
|
+
.attr("class","cityname")
|
|
210
|
+
.text(d.name);
|
|
211
|
+
|
|
212
|
+
hovergroup.append("p")
|
|
213
|
+
.attr("class","refhapps")
|
|
214
|
+
.text(reftimeseldecoder().cached+" Happiness: "+parseFloat(d.oldhapps).toFixed(2));
|
|
215
|
+
|
|
216
|
+
hovergroup.append("p")
|
|
217
|
+
.attr("class","refrank")
|
|
218
|
+
.text(reftimeseldecoder().cached+" Rank: "+(d.oldindex+1));
|
|
219
|
+
|
|
220
|
+
hovergroup.append("p")
|
|
221
|
+
.attr("class","comphapps")
|
|
222
|
+
.text(comptimeseldecoder().cached+" Happiness: "+parseFloat(d.newhapps).toFixed(2));
|
|
223
|
+
|
|
224
|
+
hovergroup.append("p")
|
|
225
|
+
.attr("class","comprank")
|
|
226
|
+
.text(comptimeseldecoder().cached+" Rank: "+(d.newindex+1));
|
|
227
|
+
|
|
228
|
+
var popupshift = function(refyear,refname,compyear,compname) {
|
|
229
|
+
refshifttimeencoder.varval(refyear);
|
|
230
|
+
refshiftcityencoder.varval(refname);
|
|
231
|
+
compshifttimeencoder.varval(compyear);
|
|
232
|
+
compshiftcityencoder.varval(compname);
|
|
233
|
+
// write a function to call on the load
|
|
234
|
+
drawShift = function() {
|
|
235
|
+
hedotools.shifter._refF(refF);
|
|
236
|
+
hedotools.shifter._compF(compF);
|
|
237
|
+
hedotools.shifter.stop();
|
|
238
|
+
hedotools.shifter.shifter();
|
|
239
|
+
hedotools.shifter.setText("Why "+compname+" in "+compyear+" is "+( ( hedotools.shifter._compH() > hedotools.shifter._refH() ) ? "happier" : "less happy" )+" than "+refname+" in "+refyear+":").plot();
|
|
240
|
+
$('#myModal').modal('show');
|
|
241
|
+
}
|
|
242
|
+
// load both of the files
|
|
243
|
+
var csvLoadsRemaining = 2;
|
|
244
|
+
var reffile = "https://hedonometer.org/data/cities/word-vectors/"+refyear+"/"+refname+".csv";
|
|
245
|
+
if (parseInt(refyear) < 2014) reffile+=".new"
|
|
246
|
+
var compfile = "https://hedonometer.org/data/cities/word-vectors/"+compyear+"/"+compname+".csv";
|
|
247
|
+
if (parseInt(compyear) < 2014) compfile+=".new"
|
|
248
|
+
console.log(reffile);
|
|
249
|
+
console.log(compfile);
|
|
250
|
+
var refF;
|
|
251
|
+
var compF;
|
|
252
|
+
d3.text(reffile).then(function(text) {
|
|
253
|
+
refF = text.split(",");
|
|
254
|
+
console.log(refF);
|
|
255
|
+
if (!--csvLoadsRemaining) drawShift();
|
|
256
|
+
});
|
|
257
|
+
d3.text(compfile).then(function(text) {
|
|
258
|
+
compF = text.split(",");
|
|
259
|
+
console.log(compF);
|
|
260
|
+
if (!--csvLoadsRemaining) drawShift();
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
hovergroup.append("button")
|
|
265
|
+
.attr("class","btn btn-sm btn-primary")
|
|
266
|
+
.text("Shift city vs previous year")
|
|
267
|
+
.on("click", function() {
|
|
268
|
+
console.log(d);
|
|
269
|
+
console.log(i);
|
|
270
|
+
popupshift(reftimeseldecoder().cached,d.name,comptimeseldecoder().cached,d.name);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
hovergroup.append("br");
|
|
274
|
+
hovergroup.append("br");
|
|
275
|
+
|
|
276
|
+
hovergroup.append("button")
|
|
277
|
+
.attr("class","btn btn-sm btn-primary")
|
|
278
|
+
.text("Shift city in "+reftimeseldecoder().cached+" vs sum "+reftimeseldecoder().cached)
|
|
279
|
+
.on("click", function() {
|
|
280
|
+
console.log(d);
|
|
281
|
+
console.log(i);
|
|
282
|
+
popupshift(reftimeseldecoder().cached,"US",reftimeseldecoder().cached,d.name);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
hovergroup.append("br");
|
|
286
|
+
hovergroup.append("br");
|
|
287
|
+
|
|
288
|
+
hovergroup.append("button")
|
|
289
|
+
.attr("class","btn btn-sm btn-primary")
|
|
290
|
+
.text("Shift city in "+comptimeseldecoder().cached+" vs sum "+comptimeseldecoder().cached)
|
|
291
|
+
.on("click", function() {
|
|
292
|
+
console.log(d);
|
|
293
|
+
console.log(i);
|
|
294
|
+
popupshift(comptimeseldecoder().cached,"US",comptimeseldecoder().cached,d.name);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
hovergroup.append("br");
|
|
298
|
+
hovergroup.append("br");
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
hovergroup.append("button")
|
|
302
|
+
.attr("class","btn btn-xs btn-primary")
|
|
303
|
+
.text("Select as reference for city-city comparison")
|
|
304
|
+
.on("click", function() {
|
|
305
|
+
console.log(d);
|
|
306
|
+
console.log(i);
|
|
307
|
+
refcity = d.name;
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
if (refcity.length > 0) {
|
|
311
|
+
hovergroup.append("br");
|
|
312
|
+
hovergroup.append("br");
|
|
313
|
+
hovergroup.append("button")
|
|
314
|
+
.attr("class","btn btn-xs btn-primary")
|
|
315
|
+
.text("Compare against "+refcity+" in "+comptimeseldecoder().cached)
|
|
316
|
+
.on("click", function() {
|
|
317
|
+
console.log(d);
|
|
318
|
+
console.log(i);
|
|
319
|
+
popupshift(comptimeseldecoder().cached,refcity,comptimeseldecoder().cached,d.name);
|
|
320
|
+
});
|
|
321
|
+
hovergroup.append("br");
|
|
322
|
+
hovergroup.append("br");
|
|
323
|
+
hovergroup.append("button")
|
|
324
|
+
.attr("class","btn btn-xs btn-primary")
|
|
325
|
+
.text("Compare against "+refcity+" in "+reftimeseldecoder().cached)
|
|
326
|
+
.on("click", function() {
|
|
327
|
+
console.log(d);
|
|
328
|
+
console.log(i);
|
|
329
|
+
popupshift(reftimeseldecoder().cached,refcity,reftimeseldecoder().cached,d.name);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
clearTimeout(popuptimer);
|
|
334
|
+
|
|
335
|
+
popuptimer = setTimeout(hidehover,3000);
|
|
336
|
+
})
|
|
337
|
+
.on("mouseout", function(event, d) {
|
|
338
|
+
clearTimeout(popuptimer);
|
|
339
|
+
|
|
340
|
+
popuptimer = setTimeout(hidehover,3000);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
newstateselection = axes.selectAll("text.statetext.new")
|
|
344
|
+
.data(data)
|
|
345
|
+
.enter()
|
|
346
|
+
.append("text")
|
|
347
|
+
.attr("class", function(d,i) { return d.name+" statetext"; })
|
|
348
|
+
.attr("x",300)
|
|
349
|
+
.style("text-anchor", "start")
|
|
350
|
+
.attr("y",function(d,i) { return y(d.newindex+1)+11; } )
|
|
351
|
+
.text(function(d,i) { return (d.newindex+1)+". "+d.name; })
|
|
352
|
+
.on("mouseover", function(event, d) {
|
|
353
|
+
var i = d.index;
|
|
354
|
+
var hoverboxheight = 90;
|
|
355
|
+
var hoverboxwidth = 200;
|
|
356
|
+
var hoverboxyoffset = 0;
|
|
357
|
+
var hoverboxxoffset = 0;
|
|
358
|
+
|
|
359
|
+
var x = d3.pointer(event, this)[0];
|
|
360
|
+
var y = d3.pointer(event, this)[1];
|
|
361
|
+
|
|
362
|
+
var hoverboxheightguess = 190;
|
|
363
|
+
if (refcity.length > 0) {
|
|
364
|
+
hoverboxheightguess = 270;
|
|
365
|
+
}
|
|
366
|
+
if ((y+hoverboxheightguess)>height) { y-=(y+hoverboxheightguess-height); }
|
|
367
|
+
|
|
368
|
+
hovergroup.style("position", "absolute")
|
|
369
|
+
.style("top", y+"px")
|
|
370
|
+
.style("left", x+"px")
|
|
371
|
+
.style("visibility", "visible");
|
|
372
|
+
|
|
373
|
+
hovergroup.selectAll("p,h3,button,br").remove();
|
|
374
|
+
|
|
375
|
+
hovergroup.append("h3")
|
|
376
|
+
.attr("class","cityname")
|
|
377
|
+
.text(d.name);
|
|
378
|
+
|
|
379
|
+
hovergroup.append("p")
|
|
380
|
+
.attr("class","refhapps")
|
|
381
|
+
.text(reftimeseldecoder().cached+" Happiness: "+parseFloat(d.oldhapps).toFixed(2));
|
|
382
|
+
|
|
383
|
+
hovergroup.append("p")
|
|
384
|
+
.attr("class","refrank")
|
|
385
|
+
.text(reftimeseldecoder().cached+" Rank: "+(d.oldindex+1));
|
|
386
|
+
|
|
387
|
+
hovergroup.append("p")
|
|
388
|
+
.attr("class","comphapps")
|
|
389
|
+
.text(comptimeseldecoder().cached+" Happiness: "+parseFloat(d.newhapps).toFixed(2));
|
|
390
|
+
|
|
391
|
+
hovergroup.append("p")
|
|
392
|
+
.attr("class","comprank")
|
|
393
|
+
.text(comptimeseldecoder().cached+" Rank: "+(d.newindex+1));
|
|
394
|
+
|
|
395
|
+
var popupshift = function(refyear,refname,compyear,compname) {
|
|
396
|
+
refshifttimeencoder.varval(refyear);
|
|
397
|
+
refshiftcityencoder.varval(refname);
|
|
398
|
+
compshifttimeencoder.varval(compyear);
|
|
399
|
+
compshiftcityencoder.varval(compname);
|
|
400
|
+
// write a function to call on the load
|
|
401
|
+
drawShift = function() {
|
|
402
|
+
hedotools.shifter._refF(refF);
|
|
403
|
+
hedotools.shifter._compF(compF);
|
|
404
|
+
hedotools.shifter.stop();
|
|
405
|
+
hedotools.shifter.shifter();
|
|
406
|
+
hedotools.shifter.setText("Why "+compname+" in "+compyear+" is "+( ( hedotools.shifter._compH() > hedotools.shifter._refH() ) ? "happier" : "less happy" )+" than "+refname+" in "+refyear+":").plot();
|
|
407
|
+
$('#myModal').modal('show');
|
|
408
|
+
}
|
|
409
|
+
// load both of the files
|
|
410
|
+
var csvLoadsRemaining = 2;
|
|
411
|
+
var reffile = "https://hedonometer.org/data/cities/word-vectors/"+refyear+"/"+refname+".csv";
|
|
412
|
+
if (parseInt(refyear) < 2014) reffile+=".new"
|
|
413
|
+
var compfile = "https://hedonometer.org/data/cities/word-vectors/"+compyear+"/"+compname+".csv";
|
|
414
|
+
if (parseInt(compyear) < 2014) compfile+=".new"
|
|
415
|
+
console.log(reffile);
|
|
416
|
+
console.log(compfile);
|
|
417
|
+
var refF;
|
|
418
|
+
var compF;
|
|
419
|
+
d3.text(reffile).then(function(text) {
|
|
420
|
+
refF = text.split(",");
|
|
421
|
+
console.log(refF);
|
|
422
|
+
if (!--csvLoadsRemaining) drawShift();
|
|
423
|
+
});
|
|
424
|
+
d3.text(compfile).then(function(text) {
|
|
425
|
+
compF = text.split(",");
|
|
426
|
+
console.log(compF);
|
|
427
|
+
if (!--csvLoadsRemaining) drawShift();
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
hovergroup.append("button")
|
|
432
|
+
.attr("class","btn btn-sm btn-primary")
|
|
433
|
+
.text("Shift city vs previous year")
|
|
434
|
+
.on("click", function() {
|
|
435
|
+
console.log(d);
|
|
436
|
+
console.log(i);
|
|
437
|
+
popupshift(reftimeseldecoder().cached,d.name,comptimeseldecoder().cached,d.name);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
hovergroup.append("br");
|
|
441
|
+
hovergroup.append("br");
|
|
442
|
+
|
|
443
|
+
hovergroup.append("button")
|
|
444
|
+
.attr("class","btn btn-sm btn-primary")
|
|
445
|
+
.text("Shift city in "+reftimeseldecoder().cached+" vs sum "+reftimeseldecoder().cached)
|
|
446
|
+
.on("click", function() {
|
|
447
|
+
console.log(d);
|
|
448
|
+
console.log(i);
|
|
449
|
+
popupshift(reftimeseldecoder().cached,"US",reftimeseldecoder().cached,d.name);
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
hovergroup.append("br");
|
|
453
|
+
hovergroup.append("br");
|
|
454
|
+
|
|
455
|
+
hovergroup.append("button")
|
|
456
|
+
.attr("class","btn btn-sm btn-primary")
|
|
457
|
+
.text("Shift city in "+comptimeseldecoder().cached+" vs sum "+comptimeseldecoder().cached)
|
|
458
|
+
.on("click", function() {
|
|
459
|
+
console.log(d);
|
|
460
|
+
console.log(i);
|
|
461
|
+
popupshift(comptimeseldecoder().cached,"US",comptimeseldecoder().cached,d.name);
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
hovergroup.append("br");
|
|
465
|
+
hovergroup.append("br");
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
hovergroup.append("button")
|
|
469
|
+
.attr("class","btn btn-xs btn-primary")
|
|
470
|
+
.text("Select as reference for city-city comparison")
|
|
471
|
+
.on("click", function() {
|
|
472
|
+
console.log(d);
|
|
473
|
+
console.log(i);
|
|
474
|
+
refcity = d.name;
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
if (refcity.length > 0) {
|
|
478
|
+
hovergroup.append("br");
|
|
479
|
+
hovergroup.append("br");
|
|
480
|
+
hovergroup.append("button")
|
|
481
|
+
.attr("class","btn btn-xs btn-primary")
|
|
482
|
+
.text("Compare against "+refcity+" in "+comptimeseldecoder().cached)
|
|
483
|
+
.on("click", function() {
|
|
484
|
+
console.log(d);
|
|
485
|
+
console.log(i);
|
|
486
|
+
popupshift(comptimeseldecoder().cached,refcity,comptimeseldecoder().cached,d.name);
|
|
487
|
+
});
|
|
488
|
+
hovergroup.append("br");
|
|
489
|
+
hovergroup.append("br");
|
|
490
|
+
hovergroup.append("button")
|
|
491
|
+
.attr("class","btn btn-xs btn-primary")
|
|
492
|
+
.text("Compare against "+refcity+" in "+reftimeseldecoder().cached)
|
|
493
|
+
.on("click", function() {
|
|
494
|
+
console.log(d);
|
|
495
|
+
console.log(i);
|
|
496
|
+
popupshift(reftimeseldecoder().cached,refcity,reftimeseldecoder().cached,d.name);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
clearTimeout(popuptimer);
|
|
501
|
+
|
|
502
|
+
popuptimer = setTimeout(hidehover,3000);
|
|
503
|
+
})
|
|
504
|
+
.on("mouseout", function(event, d) {
|
|
505
|
+
clearTimeout(popuptimer);
|
|
506
|
+
|
|
507
|
+
popuptimer = setTimeout(hidehover,3000);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
return hedotools.sankey;
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
var replot = function() {
|
|
514
|
+
// assuming that the data has been updated
|
|
515
|
+
// console.log(oldstateselection);
|
|
516
|
+
// console.log(newstateselection);
|
|
517
|
+
|
|
518
|
+
console.log(data);
|
|
519
|
+
|
|
520
|
+
oldstateselection.data(data)
|
|
521
|
+
.transition()
|
|
522
|
+
.duration(3000)
|
|
523
|
+
.text(function(d,i) { return (d.oldindex+1)+". "+d.name; })
|
|
524
|
+
.attr("y",function(d,i) { return y(d.oldindex+1)+11; } );
|
|
525
|
+
|
|
526
|
+
newstateselection.data(data)
|
|
527
|
+
.transition()
|
|
528
|
+
.duration(3000)
|
|
529
|
+
.text(function(d,i) { return (d.newindex+1)+". "+d.name; })
|
|
530
|
+
.attr("y",function(d,i) { return y(d.newindex+1)+11; } );
|
|
531
|
+
|
|
532
|
+
return hedotools.sankey;
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
// need functions to access updated properties
|
|
536
|
+
var GETdata = function() {
|
|
537
|
+
return data;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
var GETnewindices = function() {
|
|
541
|
+
return newindices;
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
var setTitles = function(titles) {
|
|
545
|
+
listlabels = titles;
|
|
546
|
+
return hedotools.sankey;
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
var setSideWidth = function(listTwoByOne) {
|
|
550
|
+
extraSideWidth = listTwoByOne;
|
|
551
|
+
return hedotools.sankey;
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
var setTipOn = function() {
|
|
555
|
+
useTip = true;
|
|
556
|
+
return hedotools.sankey;
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
var opublic = {
|
|
560
|
+
plot: plot,
|
|
561
|
+
setfigure: setfigure,
|
|
562
|
+
setdata: setdata,
|
|
563
|
+
data: GETdata,
|
|
564
|
+
newindices: GETnewindices,
|
|
565
|
+
replot: replot,
|
|
566
|
+
setTitles: setTitles,
|
|
567
|
+
setSideWidth: setSideWidth,
|
|
568
|
+
setTipOn: setTipOn,
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
return opublic;
|
|
572
|
+
|
|
573
|
+
}();
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|