@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,3995 @@
|
|
|
1
|
+
// current usage example:
|
|
2
|
+
// (from the sankey page)
|
|
3
|
+
//
|
|
4
|
+
// hedotools.shifter.shift(allDataOld[hedotools.sankey.newindices()[0]].freq,allDatra[hedotools.sankey.newindices()[0]].freq,lens,words);
|
|
5
|
+
// hedotools.shifter.setfigure(d3.select("#shift01")).setHeight(400).setText("Why "+allDataOld[hedotools.sankey.newindices()[0]].name+" has become "+"happier"+":").plot();
|
|
6
|
+
//
|
|
7
|
+
// there are two options for having it compute the shift
|
|
8
|
+
// calling the .shift() with four arguments does the trick
|
|
9
|
+
// or calling .shifter() with no arguments also does
|
|
10
|
+
// for the latter, need to have defined the variables beforehand
|
|
11
|
+
// using the _lens, _words, etc accessors
|
|
12
|
+
//
|
|
13
|
+
// if the text isn't set, will attempt to grab it using the
|
|
14
|
+
// allData structure (which works in the maps.html)
|
|
15
|
+
//
|
|
16
|
+
// the text setting here removes all p instances in the figure,
|
|
17
|
+
// and then inserts a new one before the svg, inside the figure (using d3.insert)
|
|
18
|
+
//
|
|
19
|
+
// can also use the setText method to set the text
|
|
20
|
+
|
|
21
|
+
// define the shifter module
|
|
22
|
+
hedotools.shifter = function() {
|
|
23
|
+
// for the word type selection
|
|
24
|
+
var shiftselencoder = hedotools.urllib.encoder().varname("wordtypes");
|
|
25
|
+
var shiftseldecoder = hedotools.urllib.decoder().varname("wordtypes").varresult("none");
|
|
26
|
+
// initialize that we have't selected a shift
|
|
27
|
+
var shiftTypeSelect = false;
|
|
28
|
+
var shiftType = -1;
|
|
29
|
+
|
|
30
|
+
// put the status of the viz into the bar
|
|
31
|
+
var viz_type = hedotools.urllib.encoder().varname("viz");
|
|
32
|
+
var viz_type_decoder = hedotools.urllib.decoder().varname("viz").varresult("wordshift");
|
|
33
|
+
var viz_type_use_URL = false;
|
|
34
|
+
// if (viz_type_use_URL) {
|
|
35
|
+
// }
|
|
36
|
+
var _viz_type_use_URL = function(_) {
|
|
37
|
+
var that = this;
|
|
38
|
+
if (!arguments.length) return viz_type_use_URL;
|
|
39
|
+
viz_type_use_URL = _;
|
|
40
|
+
return that;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// set a special variable to make sure all necessary things
|
|
44
|
+
// have been set before shifting
|
|
45
|
+
// (this is a double check on the page loading)
|
|
46
|
+
var loadsremaining = 4;
|
|
47
|
+
|
|
48
|
+
// will need a figure.
|
|
49
|
+
// this needs to be set by setfigure() before plotting
|
|
50
|
+
var figure = d3.select("body");
|
|
51
|
+
|
|
52
|
+
var widthsetexplicitly = false;
|
|
53
|
+
var getfigure = function() {
|
|
54
|
+
return figure;
|
|
55
|
+
}
|
|
56
|
+
var setfigure = function(_) {
|
|
57
|
+
var that = this;
|
|
58
|
+
console.log("setting figure for wordshift");
|
|
59
|
+
figure = _;
|
|
60
|
+
// wrap another relative parent div in there, for the overlay button to pad off of
|
|
61
|
+
figure = figure.append("div").attrs({
|
|
62
|
+
"class": "outwrapper"
|
|
63
|
+
}).styles({
|
|
64
|
+
"position": "relative"
|
|
65
|
+
});
|
|
66
|
+
if (!widthsetexplicitly) {
|
|
67
|
+
grabwidth();
|
|
68
|
+
}
|
|
69
|
+
return that;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
var show_x_axis_bool = false;
|
|
73
|
+
var show_x_axis = function(_) {
|
|
74
|
+
var that = this;
|
|
75
|
+
if (!arguments.length) return show_x_axis_bool;
|
|
76
|
+
show_x_axis_bool = _;
|
|
77
|
+
// give a litter extra space for it
|
|
78
|
+
axeslabelmargin.bottom = axeslabelmargin.bottom + 10;
|
|
79
|
+
return that;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var splitstring = function(_, w, font) {
|
|
83
|
+
// take an array of strings _
|
|
84
|
+
// a formatter f
|
|
85
|
+
// and a max width w (in pixels)
|
|
86
|
+
//
|
|
87
|
+
// return the strings split into an array
|
|
88
|
+
var font = font || (topFontSizeArray[topFontSizeArray.length - 1] + "px " + fontString);
|
|
89
|
+
// console.log(w);
|
|
90
|
+
// console.log(f);
|
|
91
|
+
var splitar = [];
|
|
92
|
+
var newar;
|
|
93
|
+
for (var i = 0; i < _.length; i++) {
|
|
94
|
+
if (_[i].width(font) < w) {
|
|
95
|
+
newar = [_[i]];
|
|
96
|
+
} else {
|
|
97
|
+
var tmp = _[i].split(" ");
|
|
98
|
+
// chop words off until it's long enough
|
|
99
|
+
// this is better if we know that they're
|
|
100
|
+
// not going to be way too long
|
|
101
|
+
// right now a max of two lines
|
|
102
|
+
|
|
103
|
+
// a more general approach would be to march forward...
|
|
104
|
+
// but this could be a lot of .width() calculations
|
|
105
|
+
// really need to keep those at a min
|
|
106
|
+
var leng = false;
|
|
107
|
+
var numi = 0;
|
|
108
|
+
while (!leng) {
|
|
109
|
+
numi += 1;
|
|
110
|
+
// console.log(numi);
|
|
111
|
+
var wt = tmp.slice(0, tmp.length - numi).join(" ");
|
|
112
|
+
// console.log(wt);
|
|
113
|
+
if (wt.width(font) < w) {
|
|
114
|
+
newar = [wt, tmp.slice(tmp.length - numi, tmp.length).join(" ")];
|
|
115
|
+
leng = true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// console.log("adding newar to splitar");
|
|
120
|
+
// console.log(newar);
|
|
121
|
+
// console.log(splitar);
|
|
122
|
+
splitar = splitar.concat(newar);
|
|
123
|
+
// console.log(splitar);
|
|
124
|
+
}
|
|
125
|
+
return splitar;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// set the ones we can
|
|
129
|
+
// since the height is fixed, do all that
|
|
130
|
+
// but just initialize the width-related variables
|
|
131
|
+
|
|
132
|
+
// full width and height. we'll draw the outer svg this big
|
|
133
|
+
var fullwidth = 550;
|
|
134
|
+
var fullheight = 650; // 650; // make sure to change num words too
|
|
135
|
+
|
|
136
|
+
var margin = {
|
|
137
|
+
top: 0,
|
|
138
|
+
right: 0,
|
|
139
|
+
bottom: 0,
|
|
140
|
+
left: 0
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// the width and height that we're going to use
|
|
144
|
+
var boxwidth = fullwidth - margin.left - margin.right;
|
|
145
|
+
var boxheight = fullheight - margin.top - margin.bottom;
|
|
146
|
+
|
|
147
|
+
// margin inside
|
|
148
|
+
var axeslabelmargin = {
|
|
149
|
+
top: 0,
|
|
150
|
+
right: 3,
|
|
151
|
+
bottom: 25,
|
|
152
|
+
left: 23
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// inner width and height
|
|
156
|
+
// used for the axes
|
|
157
|
+
var figwidth = boxwidth - axeslabelmargin.left - axeslabelmargin.right;
|
|
158
|
+
var figheight = boxheight - axeslabelmargin.top - axeslabelmargin.bottom;
|
|
159
|
+
var leftOffsetStatic = axeslabelmargin.left;
|
|
160
|
+
|
|
161
|
+
// individual bar height, and number of words
|
|
162
|
+
// need to be tuned to the height of the plot
|
|
163
|
+
var iBarH = 11;
|
|
164
|
+
var numWords = 37;
|
|
165
|
+
// 37 with height 650 // 23 with height 500 // 28 with height 550
|
|
166
|
+
// I should be able to compute this?
|
|
167
|
+
|
|
168
|
+
// max length of words to plot
|
|
169
|
+
var maxChars = 20;
|
|
170
|
+
|
|
171
|
+
// all inside the axes
|
|
172
|
+
var yHeight = (7 + 17 * 3 + 14 + 5 - 13); // 101
|
|
173
|
+
// where to draw the line below the summary bars
|
|
174
|
+
var barHeight = (7 + 17 * 3 + 15 - 13); // 95
|
|
175
|
+
var figcenter = figwidth / 2;
|
|
176
|
+
|
|
177
|
+
// pull the width, set the height fixed
|
|
178
|
+
var grabwidth = function() {
|
|
179
|
+
// console.log("setting width from figure");
|
|
180
|
+
// console.log(parseInt(figure.style("width")));
|
|
181
|
+
// use d3.min to set a max width of fullwidth
|
|
182
|
+
fullwidth = d3.min([parseInt(figure.style("width")), fullwidth]);
|
|
183
|
+
boxwidth = fullwidth - margin.left - margin.right;
|
|
184
|
+
figwidth = boxwidth - axeslabelmargin.left - axeslabelmargin.right;
|
|
185
|
+
figcenter = figwidth / 2;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var setWidth = function(_) {
|
|
189
|
+
if (!arguments.length) return fullwidth;
|
|
190
|
+
widthsetexplicitly = true;
|
|
191
|
+
fullwidth = _;
|
|
192
|
+
boxwidth = fullwidth - margin.left - margin.right;
|
|
193
|
+
figwidth = boxwidth - axeslabelmargin.left - axeslabelmargin.right;
|
|
194
|
+
figcenter = figwidth / 2;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// pull the width, set the height fixed
|
|
198
|
+
var setHeight = function(_) {
|
|
199
|
+
var that = this;
|
|
200
|
+
if (!arguments.length) return fullheight;
|
|
201
|
+
fullheight = _;
|
|
202
|
+
boxheight = fullheight - margin.top - margin.bottom;
|
|
203
|
+
figheight = boxheight - axeslabelmargin.top - axeslabelmargin.bottom;
|
|
204
|
+
return that;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// will be set by setdata() or shift() functions
|
|
208
|
+
var sortedMag;
|
|
209
|
+
var sortedType;
|
|
210
|
+
var sortedWords;
|
|
211
|
+
var sortedWordsRaw;
|
|
212
|
+
var sortedWordsEn;
|
|
213
|
+
var sortedWordsEnRaw;
|
|
214
|
+
var sumTypes;
|
|
215
|
+
var refH;
|
|
216
|
+
var compH;
|
|
217
|
+
|
|
218
|
+
var _sortedMag = function(_) {
|
|
219
|
+
var that = this;
|
|
220
|
+
if (!arguments.length) return sortedMag;
|
|
221
|
+
sortedMag = _;
|
|
222
|
+
return that;
|
|
223
|
+
}
|
|
224
|
+
var _sortedType = function(_) {
|
|
225
|
+
var that = this;
|
|
226
|
+
if (!arguments.length) return sortedType;
|
|
227
|
+
sortedType = _;
|
|
228
|
+
return that;
|
|
229
|
+
}
|
|
230
|
+
var _sortedWords = function(_) {
|
|
231
|
+
var that = this;
|
|
232
|
+
if (!arguments.length) return sortedWords;
|
|
233
|
+
sortedWords = _;
|
|
234
|
+
return that;
|
|
235
|
+
}
|
|
236
|
+
var _sortedWordsRaw = function(_) {
|
|
237
|
+
var that = this;
|
|
238
|
+
if (!arguments.length) return sortedWordsRaw;
|
|
239
|
+
sortedWordsRaw = _;
|
|
240
|
+
return that;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
var xlabel_text = "Per word average happiness shift";
|
|
244
|
+
var _xlabel_text = function(_) {
|
|
245
|
+
var that = this;
|
|
246
|
+
if (!arguments.length) return xlabel_text;
|
|
247
|
+
xlabel_text = _;
|
|
248
|
+
return that;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
var ylabel_text = "Word Rank";
|
|
252
|
+
var _ylabel_text = function(_) {
|
|
253
|
+
var that = this;
|
|
254
|
+
if (!arguments.length) return ylabel_text;
|
|
255
|
+
ylabel_text = _;
|
|
256
|
+
return that;
|
|
257
|
+
}
|
|
258
|
+
var _refH = function(_) {
|
|
259
|
+
var that = this;
|
|
260
|
+
if (!arguments.length) return refH;
|
|
261
|
+
refH = _;
|
|
262
|
+
return that;
|
|
263
|
+
}
|
|
264
|
+
var _compH = function(_) {
|
|
265
|
+
var that = this;
|
|
266
|
+
if (!arguments.length) return compH;
|
|
267
|
+
compH = _;
|
|
268
|
+
return that;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
var reset = true;
|
|
272
|
+
var _reset = function(_) {
|
|
273
|
+
var that = this;
|
|
274
|
+
if (!arguments.length) return reset;
|
|
275
|
+
reset = _;
|
|
276
|
+
return that;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
var get_word_index = function(w) {
|
|
280
|
+
var ind = -1;
|
|
281
|
+
for (var i = 0; i < words.length; i++) {
|
|
282
|
+
if (w === words[i]) {
|
|
283
|
+
ind = i;
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return ind;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// let's make this just toggle the state
|
|
291
|
+
// you can force it to turn on by setting the _reset function
|
|
292
|
+
// to set the reset bool to be false, then calling toggle
|
|
293
|
+
var resetbuttontoggle = function() {
|
|
294
|
+
var that = this;
|
|
295
|
+
reset = !reset;
|
|
296
|
+
resetButton(reset);
|
|
297
|
+
if (reset) {
|
|
298
|
+
figure.select("g.help").style("visibility", "visible");
|
|
299
|
+
figure.selectAll("text.credit").style("visibility", "visible");
|
|
300
|
+
} else {
|
|
301
|
+
figure.select("g.help").style("visibility", "hidden");
|
|
302
|
+
figure.selectAll("text.credit").style("visibility", "hidden");
|
|
303
|
+
}
|
|
304
|
+
return that;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
var setdata = function(a, b, c, d, e, f) {
|
|
308
|
+
var that = this;
|
|
309
|
+
// console.log("setting data");
|
|
310
|
+
sortedMag = a;
|
|
311
|
+
sortedType = b;
|
|
312
|
+
sortedWords = c;
|
|
313
|
+
sortedWordsRaw = c;
|
|
314
|
+
sumTypes = d;
|
|
315
|
+
refH = e;
|
|
316
|
+
compH = f;
|
|
317
|
+
loadsremaining = 0;
|
|
318
|
+
return that;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ******************************************************************************** //
|
|
322
|
+
// all of this stuff deals with setting the top text //
|
|
323
|
+
// which has become the most haphazard part so far //
|
|
324
|
+
// -AR 2015-07-28 //
|
|
325
|
+
//
|
|
326
|
+
// right now, we can just set the text ourselves completely, or have it set
|
|
327
|
+
// automatically
|
|
328
|
+
|
|
329
|
+
// have control over:
|
|
330
|
+
// -number of bold lines (top N lines, default 1)
|
|
331
|
+
// -each line's size
|
|
332
|
+
// -each line's color (which, doesn't seem to have an effect)
|
|
333
|
+
// -whether custom text is split or not
|
|
334
|
+
|
|
335
|
+
// this variable controls whether the top strings are checked for length
|
|
336
|
+
// and split, if necessary
|
|
337
|
+
// - only used if compatison text is set explicitly
|
|
338
|
+
var split_top_strings = true;
|
|
339
|
+
var _split_top_strings = function(_) {
|
|
340
|
+
var that = this;
|
|
341
|
+
if (!arguments.length) return split_top_strings;
|
|
342
|
+
split_top_strings = _;
|
|
343
|
+
return that;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
var numBoldLines = 1;
|
|
347
|
+
var setTextBold = function(_) {
|
|
348
|
+
var that = this;
|
|
349
|
+
if (!arguments.length) return numBoldLines;
|
|
350
|
+
numBoldLines = _;
|
|
351
|
+
return that;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// only support up to 5 lines....
|
|
355
|
+
var colorArray = ["#202020", "#D8D8D8", "#D8D8D8", "#D8D8D8", "#D8D8D8"];
|
|
356
|
+
var topFontSizeArray = [16, 12, 12, 12, 12];
|
|
357
|
+
// var topFontSizeArray = [20,16,16,16,16];
|
|
358
|
+
|
|
359
|
+
var setTextColors = function(_) {
|
|
360
|
+
var that = this;
|
|
361
|
+
if (!arguments.length) return colorArray;
|
|
362
|
+
colorArray = _;
|
|
363
|
+
return that;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
var setTopTextSizes = function(_) {
|
|
367
|
+
var that = this;
|
|
368
|
+
if (!arguments.length) return topFontSizeArray;
|
|
369
|
+
topFontSizeArray = _;
|
|
370
|
+
return that;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
var comparisonText = [""];
|
|
374
|
+
|
|
375
|
+
var setText = function(_) {
|
|
376
|
+
var that = this;
|
|
377
|
+
if (!arguments.length) return _;
|
|
378
|
+
comparisonText = _;
|
|
379
|
+
return that;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// end of the top text stuff //
|
|
383
|
+
// ******************************************************************************** //
|
|
384
|
+
|
|
385
|
+
var numwordstoplot = 10;
|
|
386
|
+
|
|
387
|
+
var refF;
|
|
388
|
+
var compF;
|
|
389
|
+
var lens;
|
|
390
|
+
var complens;
|
|
391
|
+
var stoprange = [4, 6];
|
|
392
|
+
var words;
|
|
393
|
+
var words_en;
|
|
394
|
+
var translate = false;
|
|
395
|
+
|
|
396
|
+
var _stoprange = function(_) {
|
|
397
|
+
var that = this;
|
|
398
|
+
if (!arguments.length) return stoprange;
|
|
399
|
+
stoprange = _;
|
|
400
|
+
return that;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
var _refF = function(_) {
|
|
404
|
+
var that = this;
|
|
405
|
+
if (!arguments.length) return refF;
|
|
406
|
+
refF = _;
|
|
407
|
+
// what better place to check for this
|
|
408
|
+
// some datasets have less than 200 words
|
|
409
|
+
numwordstoplot = d3.min([refF.length, numwordstoplot])
|
|
410
|
+
loadsremaining--;
|
|
411
|
+
return that;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
var _compF = function(_) {
|
|
415
|
+
var that = this;
|
|
416
|
+
if (!arguments.length) return compF;
|
|
417
|
+
compF = _;
|
|
418
|
+
loadsremaining--;
|
|
419
|
+
return that;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
var _lens = function(_) {
|
|
423
|
+
var that = this;
|
|
424
|
+
if (!arguments.length) return lens;
|
|
425
|
+
lens = _;
|
|
426
|
+
loadsremaining--;
|
|
427
|
+
return that;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
var _complens = function(_) {
|
|
431
|
+
var that = this;
|
|
432
|
+
if (!arguments.length) return complens;
|
|
433
|
+
complens = _;
|
|
434
|
+
return that;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
var _words = function(_) {
|
|
438
|
+
var that = this;
|
|
439
|
+
if (!arguments.length) return words;
|
|
440
|
+
words = _;
|
|
441
|
+
loadsremaining--;
|
|
442
|
+
return that;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
var _words_en = function(_) {
|
|
446
|
+
var that = this;
|
|
447
|
+
if (!arguments.length) return words_en;
|
|
448
|
+
words_en = _;
|
|
449
|
+
translate = true;
|
|
450
|
+
return that;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
var ignoreWords = ["nigga", "niggas", "niggaz", "nigger"];
|
|
454
|
+
|
|
455
|
+
var ignore = function(_) {
|
|
456
|
+
var that = this;
|
|
457
|
+
if (!arguments.length) return ignoreWords;
|
|
458
|
+
// refresh the list each time
|
|
459
|
+
ignoreWords = ["nigga", "niggas", "niggaz", "nigger"];
|
|
460
|
+
ignoreWords = ignoreWords.concat(_);
|
|
461
|
+
// console.log(_);
|
|
462
|
+
// console.log(ignoreWords);
|
|
463
|
+
return that;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
var stop = function() {
|
|
467
|
+
var that = this;
|
|
468
|
+
// first check if all the loads are done
|
|
469
|
+
// WARNING
|
|
470
|
+
// could not get this loop to stop!
|
|
471
|
+
// even when the other variables are set
|
|
472
|
+
// while (loadsremaining > 0) { console.log("waiting"); };
|
|
473
|
+
for (var i = 0; i < lens.length; i++) {
|
|
474
|
+
var include = true;
|
|
475
|
+
// check if in removed word list
|
|
476
|
+
for (var k = 0; k < ignoreWords.length; k++) {
|
|
477
|
+
if (ignoreWords[k] == words[i]) {
|
|
478
|
+
include = false;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
// check if underneath lens cover
|
|
482
|
+
if (lens[i] > stoprange[0] && lens[i] < stoprange[1]) {
|
|
483
|
+
include = false;
|
|
484
|
+
}
|
|
485
|
+
// include it, or set to 0
|
|
486
|
+
if (!include) {
|
|
487
|
+
refF[i] = 0;
|
|
488
|
+
compF[i] = 0;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return that;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// stop an individual vector
|
|
495
|
+
var istopper = function(fvec) {
|
|
496
|
+
for (var i = 0; i < lens.length; i++) {
|
|
497
|
+
var include = true;
|
|
498
|
+
// check if in removed word list
|
|
499
|
+
for (var k = 0; k < ignoreWords.length; k++) {
|
|
500
|
+
if (ignoreWords[k] == words[i]) {
|
|
501
|
+
include = false;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
// check if underneath lens cover
|
|
505
|
+
if (lens[i] > stoprange[0] && lens[i] < stoprange[1]) {
|
|
506
|
+
include = false;
|
|
507
|
+
}
|
|
508
|
+
// include it, or set to 0
|
|
509
|
+
if (!include) {
|
|
510
|
+
fvec[i] = 0;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return fvec;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
var prefix = true;
|
|
517
|
+
|
|
518
|
+
var concatter = function() {
|
|
519
|
+
if (prefix) {
|
|
520
|
+
// new method, with numbers prefixed
|
|
521
|
+
// log everything
|
|
522
|
+
// console.log(sortedMag);
|
|
523
|
+
// console.log(sortedWords);
|
|
524
|
+
// console.log(sortedWordsEn);
|
|
525
|
+
// console.log(sortedType);
|
|
526
|
+
// console.log(refF);
|
|
527
|
+
// console.log(compF);
|
|
528
|
+
// console.log(lens);
|
|
529
|
+
// console.log(words);
|
|
530
|
+
sortedWords = sortedWords.map(function(d, i) {
|
|
531
|
+
if (sortedType[i] == 0) {
|
|
532
|
+
return ((i + 1) + ". ").concat(d.concat("-\u2193")); // down // increase in happs
|
|
533
|
+
} else if (sortedType[i] == 1) {
|
|
534
|
+
return ((i + 1) + ". ").concat(d.concat("+\u2193")); // decrease in happs
|
|
535
|
+
} else if (sortedType[i] == 2) {
|
|
536
|
+
return ((i + 1) + ". ").concat(d.concat("-\u2191")); // up
|
|
537
|
+
} else {
|
|
538
|
+
return ((i + 1) + ". ").concat(d.concat("+\u2191"));
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
if (translate) {
|
|
542
|
+
sortedWordsEn = sortedWordsEn.map(function(d, i) {
|
|
543
|
+
if (sortedType[i] == 0) {
|
|
544
|
+
return ((i + 1) + ". ").concat(d.concat("-\u2193"));
|
|
545
|
+
} else if (sortedType[i] == 1) {
|
|
546
|
+
return ((i + 1) + ". ").concat(d.concat("+\u2193"));
|
|
547
|
+
} else if (sortedType[i] == 2) {
|
|
548
|
+
return ((i + 1) + ". ").concat(d.concat("-\u2191"));
|
|
549
|
+
} else {
|
|
550
|
+
return ((i + 1) + ". ").concat(d.concat("+\u2191"));
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
} else {
|
|
555
|
+
// old method, without numbers prefixed
|
|
556
|
+
sortedWords = sortedWords.map(function(d, i) {
|
|
557
|
+
// d = ((i+1)+". ").concat(d);
|
|
558
|
+
if (sortedType[i] == 0) {
|
|
559
|
+
return ((i + 1) + ". ").concat(d.concat("-\u2193"));
|
|
560
|
+
} else if (sortedType[i] == 1) {
|
|
561
|
+
return ((i + 1) + ". ").concat("\u2193+".concat(d));
|
|
562
|
+
} else if (sortedType[i] == 2) {
|
|
563
|
+
return ((i + 1) + ". ").concat("\u2191-".concat(d));
|
|
564
|
+
} else {
|
|
565
|
+
return ((i + 1) + ". ").concat(d.concat("+\u2191"));
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
var shift = function(a, b, c, d) {
|
|
572
|
+
var that = this;
|
|
573
|
+
refF = a;
|
|
574
|
+
compF = b;
|
|
575
|
+
lens = c;
|
|
576
|
+
words = d;
|
|
577
|
+
loadsremaining = 0;
|
|
578
|
+
shifter();
|
|
579
|
+
return that;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// var sortedMagFull;
|
|
583
|
+
var sortedTypeFull;
|
|
584
|
+
var distflag = false;
|
|
585
|
+
var plotdist = function(_) {
|
|
586
|
+
var that = this;
|
|
587
|
+
if (!arguments.length) return distflag;
|
|
588
|
+
distflag = _;
|
|
589
|
+
return that;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
var shiftMag;
|
|
593
|
+
var shiftType;
|
|
594
|
+
|
|
595
|
+
var _shiftMag = function(_) {
|
|
596
|
+
var that = this;
|
|
597
|
+
if (!arguments.length) return shiftMag;
|
|
598
|
+
shiftMag = _;
|
|
599
|
+
return that;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
var _shiftType = function(_) {
|
|
603
|
+
var that = this;
|
|
604
|
+
if (!arguments.length) return shiftType;
|
|
605
|
+
shiftType = _;
|
|
606
|
+
return that;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
var shifter = function() {
|
|
610
|
+
// console.log("running the shifter");
|
|
611
|
+
var that = this;
|
|
612
|
+
/* shift two frequency vectors
|
|
613
|
+
-assume they've been zero-ed for stop words
|
|
614
|
+
-lens is of full length
|
|
615
|
+
-words is a list of utf8 strings
|
|
616
|
+
|
|
617
|
+
return an object with the sorted quantities for plotting the shift
|
|
618
|
+
*/
|
|
619
|
+
|
|
620
|
+
//normalize frequencies
|
|
621
|
+
var Nref = 0.0;
|
|
622
|
+
var Ncomp = 0.0;
|
|
623
|
+
var lensLength = d3.min([refF.length, compF.length, words.length, lens.length]);
|
|
624
|
+
for (var i = 0; i < lensLength; i++) {
|
|
625
|
+
Nref += parseFloat(refF[i]);
|
|
626
|
+
Ncomp += parseFloat(compF[i]);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// for (var i=0; i<refF.length; i++) {
|
|
630
|
+
// refF[i] = parseFloat(refF[i])/Nref;
|
|
631
|
+
// compF[i] = parseFloat(compF[i])/Ncomp;
|
|
632
|
+
// }
|
|
633
|
+
|
|
634
|
+
// compute reference happiness
|
|
635
|
+
refH = 0.0;
|
|
636
|
+
for (var i = 0; i < lensLength; i++) {
|
|
637
|
+
refH += refF[i] * parseFloat(lens[i]);
|
|
638
|
+
}
|
|
639
|
+
// normalize at the end to minimize floating point errors
|
|
640
|
+
refH = refH / Nref;
|
|
641
|
+
// console.log(refH);
|
|
642
|
+
|
|
643
|
+
// compute reference variance
|
|
644
|
+
// var refV = 0.0;
|
|
645
|
+
// for (var i=0; i<refF.length; i++) {
|
|
646
|
+
// refV += refF[i]*Math.pow(parseFloat(lens[i])-refH,2);
|
|
647
|
+
// }
|
|
648
|
+
// refV = refV/Nref;
|
|
649
|
+
// // console.log(refV);
|
|
650
|
+
|
|
651
|
+
// compute comparison happiness
|
|
652
|
+
compH = 0.0;
|
|
653
|
+
for (var i = 0; i < lensLength; i++) {
|
|
654
|
+
compH += compF[i] * parseFloat(lens[i]);
|
|
655
|
+
}
|
|
656
|
+
compH = compH / Ncomp;
|
|
657
|
+
|
|
658
|
+
// do the shifting
|
|
659
|
+
shiftMag = Array(lensLength);
|
|
660
|
+
shiftType = Array(lensLength);
|
|
661
|
+
var freqDiff = 0.0;
|
|
662
|
+
for (var i = 0; i < lensLength; i++) {
|
|
663
|
+
freqDiff = compF[i] / Ncomp - refF[i] / Nref;
|
|
664
|
+
shiftMag[i] = (parseFloat(lens[i]) - refH) * freqDiff;
|
|
665
|
+
if (freqDiff > 0) {
|
|
666
|
+
shiftType[i] = 2;
|
|
667
|
+
} else {
|
|
668
|
+
shiftType[i] = 0
|
|
669
|
+
}
|
|
670
|
+
if (parseFloat(lens[i]) > refH) {
|
|
671
|
+
shiftType[i] += 1;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// +2 for frequency up
|
|
676
|
+
// +1 for happier
|
|
677
|
+
// =>
|
|
678
|
+
// 0 sad, down
|
|
679
|
+
// 1 happy, down
|
|
680
|
+
// 2 sad, up
|
|
681
|
+
// 3 happy, up
|
|
682
|
+
|
|
683
|
+
// do the sorting
|
|
684
|
+
var indices = Array(lensLength);
|
|
685
|
+
for (var i = 0; i < lensLength; i++) {
|
|
686
|
+
indices[i] = i;
|
|
687
|
+
}
|
|
688
|
+
indices.sort(function(a, b) {
|
|
689
|
+
return Math.abs(shiftMag[a]) < Math.abs(shiftMag[b]) ? 1 : Math.abs(shiftMag[a]) > Math.abs(shiftMag[b]) ? -1 : 0;
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
sortedMag = Array(numwordstoplot);
|
|
693
|
+
sortedType = Array(numwordstoplot);
|
|
694
|
+
sortedWords = Array(numwordstoplot);
|
|
695
|
+
|
|
696
|
+
// console.log(numwordstoplot);
|
|
697
|
+
// console.log(indices);
|
|
698
|
+
|
|
699
|
+
for (var i = 0; i < numwordstoplot; i++) {
|
|
700
|
+
sortedMag[i] = shiftMag[indices[i]];
|
|
701
|
+
sortedType[i] = shiftType[indices[i]]
|
|
702
|
+
var tmpword = words[indices[i]];
|
|
703
|
+
// add 1 to maxChars, because I'll add the ellipsis
|
|
704
|
+
if (tmpword.length > maxChars + 2) {
|
|
705
|
+
var shorterword = tmpword.slice(0, maxChars);
|
|
706
|
+
// check that the last char isn't a space (if it is, delete it)
|
|
707
|
+
if (shorterword[shorterword.length - 1] === " ") {
|
|
708
|
+
sortedWords[i] = shorterword.slice(0, shorterword.length - 1) + "\u2026";
|
|
709
|
+
} else {
|
|
710
|
+
sortedWords[i] = shorterword + "\u2026";
|
|
711
|
+
}
|
|
712
|
+
} else {
|
|
713
|
+
sortedWords[i] = tmpword;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if (distflag) {
|
|
718
|
+
// declare some new variables
|
|
719
|
+
sortedMagFull = Array(lensLength);
|
|
720
|
+
sortedTypeFull = Array(lensLength);
|
|
721
|
+
for (var i = 0; i < lensLength; i++) {
|
|
722
|
+
sortedMagFull[i] = shiftMag[indices[i]];
|
|
723
|
+
sortedTypeFull[i] = shiftType[indices[i]];
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// compute the sum of contributions of different types
|
|
728
|
+
sumTypes = [0.0, 0.0, 0.0, 0.0];
|
|
729
|
+
for (var i = 0; i < lensLength; i++) {
|
|
730
|
+
sumTypes[shiftType[i]] += shiftMag[i];
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// slice them
|
|
734
|
+
// sortedMag = sortedMag.slice(0,numwordstoplot);
|
|
735
|
+
// sortedWords = sortedWords.slice(0,numwordstoplot);
|
|
736
|
+
// sortedType = sortedType.slice(0,numwordstoplot);
|
|
737
|
+
|
|
738
|
+
if (translate) {
|
|
739
|
+
sortedWordsEn = Array(numwordstoplot);
|
|
740
|
+
for (var i = 0; i < numwordstoplot; i++) {
|
|
741
|
+
sortedWordsEn[i] = words_en[indices[i]];
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// // return as an object
|
|
746
|
+
// return {
|
|
747
|
+
// sortedMag: sortedMag,
|
|
748
|
+
// sortedType: sortedType,
|
|
749
|
+
// sortedWords: sortedWords,
|
|
750
|
+
// sumTypes: sumTypes,
|
|
751
|
+
// refH: refH,
|
|
752
|
+
// compH: compH,
|
|
753
|
+
// };
|
|
754
|
+
|
|
755
|
+
sortedWordsRaw = sortedWords;
|
|
756
|
+
sortedWordsRawEn = sortedWordsEn;
|
|
757
|
+
concatter();
|
|
758
|
+
|
|
759
|
+
// allow chaining here too
|
|
760
|
+
return that;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
var nbins = 100;
|
|
765
|
+
var dist;
|
|
766
|
+
var cdist;
|
|
767
|
+
var ntypes = 4;
|
|
768
|
+
var nwords;
|
|
769
|
+
var computedistributions = function() {
|
|
770
|
+
var that = this;
|
|
771
|
+
// bin the distribution of words into a distribution
|
|
772
|
+
// and cumulative
|
|
773
|
+
// there are four types of contributions here (the way
|
|
774
|
+
// the sum has been broken down), so do the distribution
|
|
775
|
+
// for the total, and each of the four bins
|
|
776
|
+
|
|
777
|
+
// nwords = sortedMagFull.length;
|
|
778
|
+
// nwords = 2000;
|
|
779
|
+
var a = 1;
|
|
780
|
+
nwords = -1;
|
|
781
|
+
while (a > Math.pow(10, -6)) {
|
|
782
|
+
nwords++;
|
|
783
|
+
a = Math.abs(sortedMagFull[nwords]);
|
|
784
|
+
}
|
|
785
|
+
// console.log(nwords);
|
|
786
|
+
|
|
787
|
+
dist = Array(nbins);
|
|
788
|
+
cdist = Array(nbins);
|
|
789
|
+
|
|
790
|
+
// compute the size of each bin
|
|
791
|
+
// should be a fast way to do this
|
|
792
|
+
// when it doesn't round evenly
|
|
793
|
+
var binsize = Math.floor(nwords / nbins);
|
|
794
|
+
// console.log(binsize);
|
|
795
|
+
|
|
796
|
+
// loop over each bin, initialize it to zero
|
|
797
|
+
// then add each of the types to it
|
|
798
|
+
for (var i = 0; i < nbins; i++) {
|
|
799
|
+
dist[i] = Array(ntypes + 1);
|
|
800
|
+
cdist[i] = Array(ntypes + 1);
|
|
801
|
+
for (var j = 0; j < ntypes + 1; j++) {
|
|
802
|
+
dist[i][j] = 0;
|
|
803
|
+
cdist[i][j] = 0;
|
|
804
|
+
}
|
|
805
|
+
// fast, with the sum
|
|
806
|
+
// console.log(i*binsize);
|
|
807
|
+
// console.log((i+1)*binsize);
|
|
808
|
+
dist[i][4] = d3.sum(sortedMagFull.slice(i * binsize, (i + 1) * binsize));
|
|
809
|
+
// slower, by type
|
|
810
|
+
for (var j = i * binsize; j < (i + 1) * binsize; j++) {
|
|
811
|
+
dist[i][sortedTypeFull[j]] += sortedMagFull[j];
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
// now get the cumulative
|
|
816
|
+
for (var j = 0; j < ntypes + 1; j++) {
|
|
817
|
+
cdist[0][j] = dist[0][j];
|
|
818
|
+
}
|
|
819
|
+
for (var i = 1; i < nbins; i++) {
|
|
820
|
+
for (var j = 0; j < ntypes + 1; j++) {
|
|
821
|
+
cdist[i][j] = cdist[i - 1][j] + dist[i][j];
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
// console.log(dist);
|
|
826
|
+
// console.log(cdist);
|
|
827
|
+
// console.log(cdist[cdist.length-1]);
|
|
828
|
+
return that;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// declare a boat load of private variables
|
|
832
|
+
// to be accessed by the other methods
|
|
833
|
+
var canvas;
|
|
834
|
+
var maxWidth;
|
|
835
|
+
var x;
|
|
836
|
+
var y;
|
|
837
|
+
var topScale;
|
|
838
|
+
var bgrect;
|
|
839
|
+
var xlabel;
|
|
840
|
+
var topbgrect;
|
|
841
|
+
var ylabel;
|
|
842
|
+
var sepline;
|
|
843
|
+
var zoom;
|
|
844
|
+
var axes;
|
|
845
|
+
var fontString = "Latex default, serif";
|
|
846
|
+
var _fontString = function(_) {
|
|
847
|
+
var that = this;
|
|
848
|
+
if (!arguments.length) return fontString;
|
|
849
|
+
fontString = _;
|
|
850
|
+
return that;
|
|
851
|
+
}
|
|
852
|
+
// the inspector computed width of ∑+↓ rendering in latex default (cmr10)
|
|
853
|
+
var sumTextWidth = 34.1562;
|
|
854
|
+
// these are set explicitly on the elements
|
|
855
|
+
var bigshifttextsize = 12;
|
|
856
|
+
var xaxisfontsize = 12;
|
|
857
|
+
var xylabelfontsize = 16;
|
|
858
|
+
var wordfontsize = 12;
|
|
859
|
+
var distlabeltext = 8;
|
|
860
|
+
var creditfontsize = 8;
|
|
861
|
+
var resetfontsize = 12;
|
|
862
|
+
// [16,10,20,10,8,8,13];
|
|
863
|
+
var setFontSizes = function(_) {
|
|
864
|
+
var that = this;
|
|
865
|
+
if (!arguments.length) return [bigshifttextsize, xaxisfontsize, xylabelfontsize, wordfontsize, distlabeltext, creditfontsize, resetfontsize];
|
|
866
|
+
bigshifttextsize = _[0];
|
|
867
|
+
xaxisfontsize = _[1];
|
|
868
|
+
xylabelfontsize = _[2];
|
|
869
|
+
wordfontsize = _[3];
|
|
870
|
+
distlabeltext = _[4];
|
|
871
|
+
creditfontsize = _[5];
|
|
872
|
+
resetfontsize = _[6];
|
|
873
|
+
return that;
|
|
874
|
+
}
|
|
875
|
+
var typeClass = ["negdown", "posdown", "negup", "posup"];
|
|
876
|
+
var colorClass;
|
|
877
|
+
var shiftrects;
|
|
878
|
+
var shifttext;
|
|
879
|
+
var flipVector;
|
|
880
|
+
var maxShiftSum;
|
|
881
|
+
var summaryArray;
|
|
882
|
+
var toptext;
|
|
883
|
+
var toptextheight;
|
|
884
|
+
var credit;
|
|
885
|
+
var help;
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
var xAxis;
|
|
889
|
+
var distgroup;
|
|
890
|
+
var my_shift_id = "shiftsvg";
|
|
891
|
+
var _my_shift_id = function(_) {
|
|
892
|
+
var that = this;
|
|
893
|
+
if (!arguments.length) return my_shift_id;
|
|
894
|
+
my_shift_id = _;
|
|
895
|
+
return that;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
// var bgcolor = "rgba(255,248,220,.2)";
|
|
901
|
+
var bgcolor = "white";
|
|
902
|
+
var setBgcolor = function(_) {
|
|
903
|
+
var that = this;
|
|
904
|
+
if (!arguments.length) return bgcolor;
|
|
905
|
+
bgcolor = _;
|
|
906
|
+
return that;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
var logowidth = 0;
|
|
910
|
+
|
|
911
|
+
function resetfun() {
|
|
912
|
+
// console.log("reset function");
|
|
913
|
+
figure.selectAll(".sumrectR,.sumrectL").styles({
|
|
914
|
+
opacity: "0.7"
|
|
915
|
+
});
|
|
916
|
+
shiftTypeSelect = false;
|
|
917
|
+
shiftType = -1;
|
|
918
|
+
figure.selectAll("rect.shiftrect").transition().duration(1000)
|
|
919
|
+
.attr("transform", function(d, i) {
|
|
920
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
921
|
+
});
|
|
922
|
+
figure.selectAll("text.shifttext").transition().duration(1000)
|
|
923
|
+
.attr("transform", function(d, i) {
|
|
924
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
925
|
+
});
|
|
926
|
+
// d3.selectAll(".resetbutton").remove();
|
|
927
|
+
shiftselencoder.varval("none");
|
|
928
|
+
shiftselencoder.destroy();
|
|
929
|
+
} // resetfun
|
|
930
|
+
|
|
931
|
+
var plot = function() {
|
|
932
|
+
var that = this;
|
|
933
|
+
/* plot the shift
|
|
934
|
+
|
|
935
|
+
-take a d3 selection, and draw the shift SVG on it
|
|
936
|
+
-requires sorted vectors of the shift magnitude, type and word
|
|
937
|
+
for each word
|
|
938
|
+
|
|
939
|
+
*/
|
|
940
|
+
// console.log("plotting shift");
|
|
941
|
+
|
|
942
|
+
// first things first, plot the text on top
|
|
943
|
+
// if there wasn't any text passed, make it
|
|
944
|
+
if (comparisonText[0].length < 1) {
|
|
945
|
+
if (compH >= refH) {
|
|
946
|
+
var happysad = "happier";
|
|
947
|
+
} else {
|
|
948
|
+
var happysad = "less happy";
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// console.log("generating text for wordshift");
|
|
952
|
+
comparisonText = splitstring(
|
|
953
|
+
["Reference happiness: " + refH.toFixed(2), "Comparison happiness: " + compH.toFixed(2), "Why comparison is " + happysad + " than reference:"],
|
|
954
|
+
boxwidth - 10 - logowidth,
|
|
955
|
+
topFontSizeArray[topFontSizeArray.length - 1] + "px " + fontString
|
|
956
|
+
);
|
|
957
|
+
|
|
958
|
+
// console.log(comparisonText);
|
|
959
|
+
} else {
|
|
960
|
+
if (split_top_strings) {
|
|
961
|
+
comparisonText = splitstring(
|
|
962
|
+
comparisonText,
|
|
963
|
+
boxwidth - 10 - logowidth,
|
|
964
|
+
topFontSizeArray[topFontSizeArray.length - 1] + "px " + fontString
|
|
965
|
+
);
|
|
966
|
+
}
|
|
967
|
+
// console.log(comparisonText);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// this would put the text above the svg, in the figure div
|
|
971
|
+
// figure.selectAll("p")
|
|
972
|
+
// .remove();
|
|
973
|
+
// figure.selectAll("p")
|
|
974
|
+
// .data(comparisonText)
|
|
975
|
+
// .enter()
|
|
976
|
+
// .insert("p","svg")
|
|
977
|
+
// .attr("class","shifttitle")
|
|
978
|
+
// .html(function(d) { return d; });
|
|
979
|
+
|
|
980
|
+
// made a new svg
|
|
981
|
+
figure.selectAll("svg").remove();
|
|
982
|
+
canvas = figure.append("svg")
|
|
983
|
+
.attr("id", my_shift_id)
|
|
984
|
+
.attr("width", function() {
|
|
985
|
+
return boxwidth;
|
|
986
|
+
})
|
|
987
|
+
.attr("height", function() {
|
|
988
|
+
return boxheight;
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// this one will be white, and behind EVERYTHING
|
|
992
|
+
bgbgrect = canvas.append("rect")
|
|
993
|
+
.attr("x", 0)
|
|
994
|
+
.attr("y", 0)
|
|
995
|
+
.attr("width", boxwidth)
|
|
996
|
+
.attr("height", boxheight)
|
|
997
|
+
.attr("class", "bgbg")
|
|
998
|
+
.attr("fill", bgcolor);
|
|
999
|
+
|
|
1000
|
+
toptextheight = comparisonText.length * 17 + 13;
|
|
1001
|
+
// console.log(toptextheight);
|
|
1002
|
+
|
|
1003
|
+
// reset this
|
|
1004
|
+
figheight = boxheight - axeslabelmargin.top - axeslabelmargin.bottom - toptextheight;
|
|
1005
|
+
// console.log(figheight);
|
|
1006
|
+
// console.log(yHeight);
|
|
1007
|
+
|
|
1008
|
+
// take the longest of the top five words
|
|
1009
|
+
// console.log("appending to sorted words");
|
|
1010
|
+
// console.log(sortedWords);
|
|
1011
|
+
|
|
1012
|
+
maxWidth = d3.max(sortedWords.slice(0, 7).map(function(d) {
|
|
1013
|
+
return d.width(wordfontsize + "px " + fontString);
|
|
1014
|
+
}));
|
|
1015
|
+
|
|
1016
|
+
// a little extra padding for the words
|
|
1017
|
+
var xpadding = 10;
|
|
1018
|
+
// linear scale function
|
|
1019
|
+
x = d3.scaleLinear()
|
|
1020
|
+
.domain([-Math.abs(sortedMag[0]), Math.abs(sortedMag[0])])
|
|
1021
|
+
.range([maxWidth + xpadding, figwidth - maxWidth - xpadding]);
|
|
1022
|
+
|
|
1023
|
+
// linear scale function
|
|
1024
|
+
y = d3.scaleLinear()
|
|
1025
|
+
.domain([numWords + 1, 1])
|
|
1026
|
+
.range([figheight + 2, yHeight]);
|
|
1027
|
+
|
|
1028
|
+
// zoom object for the axes
|
|
1029
|
+
zoom = d3.zoom()
|
|
1030
|
+
// .y(y) // pass linear scale function
|
|
1031
|
+
// .translate([10,10])
|
|
1032
|
+
// .scaleExtent([0,0])
|
|
1033
|
+
// .translateExtent([[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY],[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]])
|
|
1034
|
+
.translateExtent([
|
|
1035
|
+
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
|
1036
|
+
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY]
|
|
1037
|
+
])
|
|
1038
|
+
.on("zoom", zoomed);
|
|
1039
|
+
|
|
1040
|
+
// create the axes themselves
|
|
1041
|
+
axes = canvas
|
|
1042
|
+
// not using the "svg inside svg" approach again
|
|
1043
|
+
// .append("svg")
|
|
1044
|
+
// .attr("width", figwidth)
|
|
1045
|
+
// .attr("height", figheight)
|
|
1046
|
+
// .attr("class", "shiftcanvas")
|
|
1047
|
+
.append("g")
|
|
1048
|
+
.attr("transform", "translate(" + (axeslabelmargin.left) + "," + (axeslabelmargin.top + toptextheight) + ")")
|
|
1049
|
+
.attr("width", figwidth)
|
|
1050
|
+
.attr("height", figheight)
|
|
1051
|
+
.attr("class", "main");
|
|
1052
|
+
|
|
1053
|
+
// axes.call(zoom);
|
|
1054
|
+
// axes.call(drag);
|
|
1055
|
+
// var dispatch = d3.dispatch("wheel");
|
|
1056
|
+
axes.on("wheel.zoom", zoomed);
|
|
1057
|
+
|
|
1058
|
+
// // don't need these
|
|
1059
|
+
// axes.on("wheel.zoom", null);
|
|
1060
|
+
// axes.on("mousewheel.zoom", null);
|
|
1061
|
+
// // can re-register them...
|
|
1062
|
+
// // axes.on("wheel",function(d) { console.log(d3.event); });
|
|
1063
|
+
// // axes.on("mousewheel",function(d) { console.log(d3.event); });
|
|
1064
|
+
// // now use them to translate (instead of zoom)
|
|
1065
|
+
// axes.on("wheel",function(d) { d3.event.preventDefault(); zoom.translate([0,zoom.translate()[1]+d3.event.wheelDeltaY/2]); zoom.event(axes); });
|
|
1066
|
+
// axes.on("mousewheel",function(d) { d3.event.preventDefault(); zoom.translate([0,zoom.translate()[1]+d3.event.wheelDeltaY/2]); zoom.event(axes); });
|
|
1067
|
+
|
|
1068
|
+
// create the axes background
|
|
1069
|
+
bgrect = axes.append("rect")
|
|
1070
|
+
.attrs({
|
|
1071
|
+
"x": 0,
|
|
1072
|
+
"y": 1,
|
|
1073
|
+
"width": figwidth - 2,
|
|
1074
|
+
"height": figheight - 2,
|
|
1075
|
+
"class": "bg",
|
|
1076
|
+
})
|
|
1077
|
+
.styles({
|
|
1078
|
+
"stroke-width": "0.5",
|
|
1079
|
+
"stroke": "rgb(0,0,0)",
|
|
1080
|
+
"fill": "#FCFCFC",
|
|
1081
|
+
"opacity": "0.96"
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
if (show_x_axis_bool) {
|
|
1085
|
+
// axes creation functions
|
|
1086
|
+
var create_xAxis = function() {
|
|
1087
|
+
return d3.axisBottom()
|
|
1088
|
+
.ticks(4)
|
|
1089
|
+
.scale(x);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
xAxis = create_xAxis()
|
|
1093
|
+
.innerTickSize(3)
|
|
1094
|
+
.outerTickSize(0);
|
|
1095
|
+
|
|
1096
|
+
canvas.append("g")
|
|
1097
|
+
.attr("class", "x axis ")
|
|
1098
|
+
.attr("font-size", xaxisfontsize)
|
|
1099
|
+
.attr("transform", "translate(" + (axeslabelmargin.left) + "," + (yHeight + figheight) + ")")
|
|
1100
|
+
// .attr("transform", "translate(0," + (figheight) + ")")
|
|
1101
|
+
.call(xAxis);
|
|
1102
|
+
|
|
1103
|
+
canvas.selectAll(".tick line").styles({
|
|
1104
|
+
"stroke": "black"
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
// figure.selectAll("p.sumtext.ref")
|
|
1110
|
+
// .data([refH,])
|
|
1111
|
+
// .html(function(d,i) {
|
|
1112
|
+
// if (i===0) {
|
|
1113
|
+
// return "Reference: happiness " + (d.toFixed(3));
|
|
1114
|
+
// }
|
|
1115
|
+
// });
|
|
1116
|
+
|
|
1117
|
+
// figure.selectAll("p.sumtext.comp")
|
|
1118
|
+
// .data([compH,])
|
|
1119
|
+
// .html(function(d,i) {
|
|
1120
|
+
// if (i===0) {
|
|
1121
|
+
// return "Comparison: happiness " + (d.toFixed(3));
|
|
1122
|
+
// }
|
|
1123
|
+
// });
|
|
1124
|
+
|
|
1125
|
+
// addthis_share.passthrough.twitter.text = "Why "+allData[shiftComp].name+" was "+happysad+" than "+allData[shiftRef].name+" in "+timeseldecoder().cached;
|
|
1126
|
+
|
|
1127
|
+
// addthis_share.title = "Why "+allData[shiftComp].name+" was "+happysad+" than "+allData[shiftRef].name+" in "+timeseldecoder().cached;
|
|
1128
|
+
|
|
1129
|
+
// addthis_share.url = document.URL;
|
|
1130
|
+
|
|
1131
|
+
// d3.select("[id=fbtitle]").attr("content","Hedonometer Maps: Andy has been here");
|
|
1132
|
+
|
|
1133
|
+
typeClass = ["negdown", "posdown", "negup", "posup"];
|
|
1134
|
+
|
|
1135
|
+
var colorClass = ["#b3b3ff", "#ffffb3", "#4c4cff", "#ffff4c", "#272727"];
|
|
1136
|
+
|
|
1137
|
+
shiftrects = axes.selectAll("rect.shiftrect")
|
|
1138
|
+
.data(sortedMag)
|
|
1139
|
+
.enter()
|
|
1140
|
+
.append("rect")
|
|
1141
|
+
.attrs({
|
|
1142
|
+
"class": function(d, i) {
|
|
1143
|
+
return "shiftrect " + intStr0[sortedType[i]] + " " + typeClass[sortedType[i]];
|
|
1144
|
+
},
|
|
1145
|
+
// "x": function(d,i) {
|
|
1146
|
+
// if (d>0) { return figcenter; }
|
|
1147
|
+
// else { return x(d)}
|
|
1148
|
+
// },
|
|
1149
|
+
// "y": function(d,i) { return y(i+1); },
|
|
1150
|
+
"id": function(d, i) {
|
|
1151
|
+
return "shiftrect" + i;
|
|
1152
|
+
},
|
|
1153
|
+
"x": 0,
|
|
1154
|
+
"y": 0,
|
|
1155
|
+
"transform": function(d, i) {
|
|
1156
|
+
if (d > 0) {
|
|
1157
|
+
return "translate(" + figcenter + "," + y(i + 1) + ")";
|
|
1158
|
+
} else {
|
|
1159
|
+
return "translate(" + x(d) + "," + y(i + 1) + ")";
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
"height": function(d, i) {
|
|
1163
|
+
return iBarH;
|
|
1164
|
+
},
|
|
1165
|
+
"width": function(d, i) {
|
|
1166
|
+
if ((d) > 0) {
|
|
1167
|
+
return x(d) - x(0);
|
|
1168
|
+
} else {
|
|
1169
|
+
return x(0) - x(d);
|
|
1170
|
+
}
|
|
1171
|
+
},
|
|
1172
|
+
"opacity": "0.7",
|
|
1173
|
+
"stroke-width": "1",
|
|
1174
|
+
"stroke": "rgb(0,0,0)",
|
|
1175
|
+
"fill": function(d, i) {
|
|
1176
|
+
return colorClass[sortedType[i]];
|
|
1177
|
+
},
|
|
1178
|
+
});
|
|
1179
|
+
// .on("mouseover", function(d){
|
|
1180
|
+
// var rectSelection = d3.select(this).styles({opacity:"1.0"});
|
|
1181
|
+
// })
|
|
1182
|
+
// .on("mouseout", function(d){
|
|
1183
|
+
// var rectSelection = d3.select(this).styles({opacity:"0.7"});
|
|
1184
|
+
// });
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
shifttext = axes.selectAll("text.shifttext")
|
|
1188
|
+
.data(sortedMag)
|
|
1189
|
+
.enter()
|
|
1190
|
+
.append("text")
|
|
1191
|
+
.attrs({
|
|
1192
|
+
"class": function(d, i) {
|
|
1193
|
+
return "shifttext " + intStr0[sortedType[i]];
|
|
1194
|
+
},
|
|
1195
|
+
"x": 0,
|
|
1196
|
+
"y": 0,
|
|
1197
|
+
"transform": function(d, i) {
|
|
1198
|
+
if (d > 0) {
|
|
1199
|
+
return "translate(" + (x(d) + 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1200
|
+
} else {
|
|
1201
|
+
return "translate(" + (x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1202
|
+
}
|
|
1203
|
+
},
|
|
1204
|
+
})
|
|
1205
|
+
// .attr("x",function(d,i) { if (d>0) {return x(d)+2;} else {return x(d)-2; } } )
|
|
1206
|
+
// .attr("y",function(d,i) { return y(i+1)+iBarH; } )
|
|
1207
|
+
.styles({
|
|
1208
|
+
"text-anchor": function(d, i) {
|
|
1209
|
+
return ((d < 0) ? "end" : "start");
|
|
1210
|
+
},
|
|
1211
|
+
"font-size": wordfontsize
|
|
1212
|
+
})
|
|
1213
|
+
.text(function(d, i) {
|
|
1214
|
+
return sortedWords[i];
|
|
1215
|
+
});
|
|
1216
|
+
|
|
1217
|
+
if (translate) {
|
|
1218
|
+
// it is one longer than the words, the last entry being what
|
|
1219
|
+
// everything will be set to on "translate all"
|
|
1220
|
+
flipVector = Array(sortedWords.length + 1);
|
|
1221
|
+
for (var i = 0; i < flipVector.length; i++) {
|
|
1222
|
+
flipVector[i] = 0;
|
|
1223
|
+
}
|
|
1224
|
+
flipVector[flipVector.length - 1] = 1;
|
|
1225
|
+
shifttext.on("click", function(d, i) {
|
|
1226
|
+
// goal is to toggle translation
|
|
1227
|
+
// need translation vector
|
|
1228
|
+
//console.log(flipVector[i]);
|
|
1229
|
+
if (flipVector[i]) {
|
|
1230
|
+
d3.select(this).text(sortedWords[i]);
|
|
1231
|
+
flipVector[i] = 0;
|
|
1232
|
+
} else {
|
|
1233
|
+
d3.select(this).text(sortedWordsEn[i]);
|
|
1234
|
+
flipVector[i] = 1;
|
|
1235
|
+
}
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// check if there is a word selection to apply
|
|
1240
|
+
if (shiftseldecoder().current === "posup") {
|
|
1241
|
+
shiftTypeSelect = true;
|
|
1242
|
+
shiftType = 3;
|
|
1243
|
+
resetButton(true);
|
|
1244
|
+
// ((d>0) ? 500 : -500)
|
|
1245
|
+
// ((d>0) ? figcenter : x(d))
|
|
1246
|
+
axes.selectAll("rect.shiftrect.zero").attr("transform", function(d, i) {
|
|
1247
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1248
|
+
});
|
|
1249
|
+
axes.selectAll("text.shifttext.zero").attr("transform", function(d, i) {
|
|
1250
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1251
|
+
});
|
|
1252
|
+
axes.selectAll("rect.shiftrect.one").attr("transform", function(d, i) {
|
|
1253
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1254
|
+
});
|
|
1255
|
+
axes.selectAll("text.shifttext.one").attr("transform", function(d, i) {
|
|
1256
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1257
|
+
});
|
|
1258
|
+
axes.selectAll("rect.shiftrect.two").attr("transform", function(d, i) {
|
|
1259
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1260
|
+
});
|
|
1261
|
+
axes.selectAll("text.shifttext.two").attr("transform", function(d, i) {
|
|
1262
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1263
|
+
});
|
|
1264
|
+
// .attr("transform","translate(0,"+y(i+1)+")");
|
|
1265
|
+
// .attr("transform",function(d,i) { return "translate("+((d>0) ? figcenter : x(d))+","+y(i+1)+")"; });
|
|
1266
|
+
axes.selectAll("rect.shiftrect.three").attr("transform", function(d, i) {
|
|
1267
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1268
|
+
});
|
|
1269
|
+
axes.selectAll("text.shifttext.three").attr("transform", function(d, i) {
|
|
1270
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1271
|
+
});
|
|
1272
|
+
} else if (shiftseldecoder().current === "negdown") {
|
|
1273
|
+
shiftTypeSelect = true;
|
|
1274
|
+
shiftType = 0;
|
|
1275
|
+
resetButton(true);
|
|
1276
|
+
axes.selectAll("rect.shiftrect.zero").attr("transform", function(d, i) {
|
|
1277
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1278
|
+
});
|
|
1279
|
+
axes.selectAll("text.shifttext.zero").attr("transform", function(d, i) {
|
|
1280
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1281
|
+
});
|
|
1282
|
+
axes.selectAll("rect.shiftrect.one").attr("transform", function(d, i) {
|
|
1283
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1284
|
+
});
|
|
1285
|
+
axes.selectAll("text.shifttext.one").attr("transform", function(d, i) {
|
|
1286
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1287
|
+
});
|
|
1288
|
+
axes.selectAll("rect.shiftrect.two").attr("transform", function(d, i) {
|
|
1289
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1290
|
+
});
|
|
1291
|
+
axes.selectAll("text.shifttext.two").attr("transform", function(d, i) {
|
|
1292
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1293
|
+
});
|
|
1294
|
+
axes.selectAll("rect.shiftrect.three").attr("transform", function(d, i) {
|
|
1295
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1296
|
+
});
|
|
1297
|
+
axes.selectAll("text.shifttext.three").attr("transform", function(d, i) {
|
|
1298
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1299
|
+
});
|
|
1300
|
+
} else if (shiftseldecoder().current === "posdown") {
|
|
1301
|
+
shiftTypeSelect = true;
|
|
1302
|
+
shiftType = 1;
|
|
1303
|
+
resetButton(true);
|
|
1304
|
+
axes.selectAll("rect.shiftrect.zero").attr("transform", function(d, i) {
|
|
1305
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1306
|
+
});
|
|
1307
|
+
axes.selectAll("text.shifttext.zero").attr("transform", function(d, i) {
|
|
1308
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1309
|
+
});
|
|
1310
|
+
axes.selectAll("rect.shiftrect.three").attr("transform", function(d, i) {
|
|
1311
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1312
|
+
});
|
|
1313
|
+
axes.selectAll("text.shifttext.three").attr("transform", function(d, i) {
|
|
1314
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1315
|
+
});
|
|
1316
|
+
axes.selectAll("rect.shiftrect.two").attr("transform", function(d, i) {
|
|
1317
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1318
|
+
});
|
|
1319
|
+
axes.selectAll("text.shifttext.two").attr("transform", function(d, i) {
|
|
1320
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1321
|
+
});
|
|
1322
|
+
axes.selectAll("rect.shiftrect.one").attr("transform", function(d, i) {
|
|
1323
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1324
|
+
});
|
|
1325
|
+
axes.selectAll("text.shifttext.one").attr("transform", function(d, i) {
|
|
1326
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1327
|
+
});
|
|
1328
|
+
} else if (shiftseldecoder().current === "negup") {
|
|
1329
|
+
shiftTypeSelect = true;
|
|
1330
|
+
shiftType = 2;
|
|
1331
|
+
resetButton(true);
|
|
1332
|
+
axes.selectAll("rect.shiftrect.zero").attr("transform", function(d, i) {
|
|
1333
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1334
|
+
});
|
|
1335
|
+
axes.selectAll("text.shifttext.zero").attr("transform", function(d, i) {
|
|
1336
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1337
|
+
});
|
|
1338
|
+
axes.selectAll("rect.shiftrect.one").attr("transform", function(d, i) {
|
|
1339
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1340
|
+
});
|
|
1341
|
+
axes.selectAll("text.shifttext.one").attr("transform", function(d, i) {
|
|
1342
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1343
|
+
});
|
|
1344
|
+
axes.selectAll("rect.shiftrect.two").attr("transform", function(d, i) {
|
|
1345
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1346
|
+
});
|
|
1347
|
+
axes.selectAll("text.shifttext.two").attr("transform", function(d, i) {
|
|
1348
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1349
|
+
});
|
|
1350
|
+
axes.selectAll("rect.shiftrect.three").attr("transform", function(d, i) {
|
|
1351
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1352
|
+
});
|
|
1353
|
+
axes.selectAll("text.shifttext.three").attr("transform", function(d, i) {
|
|
1354
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1355
|
+
});
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
// draw a white rectangle to hide the shift bars behind the summary shifts
|
|
1359
|
+
// move x,y to 3 and width to -6 to give the bg a little space
|
|
1360
|
+
topbgrect = axes.append("rect").attr("x", 3).attr("y", 3).attr("width", figwidth - axeslabelmargin.left - 5).attr("height", 73 - 13).attr("fill", "white").styles({
|
|
1361
|
+
"opacity": "1.0"
|
|
1362
|
+
});
|
|
1363
|
+
|
|
1364
|
+
topbgrect2 = canvas.append("rect").attr("x", 0).attr("y", 0).attr("width", boxwidth).attr("height", toptextheight).attr("fill", "white").styles({
|
|
1365
|
+
"opacity": "1.0"
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
// draw the text on top of this rect
|
|
1369
|
+
toptext = canvas.selectAll("text.titletext")
|
|
1370
|
+
.data(comparisonText)
|
|
1371
|
+
.enter()
|
|
1372
|
+
.append("text")
|
|
1373
|
+
.attr("y", function(d, i) {
|
|
1374
|
+
return (i + 1) * 17;
|
|
1375
|
+
})
|
|
1376
|
+
.attr("x", 3)
|
|
1377
|
+
.attr("class", function(d, i) {
|
|
1378
|
+
return "titletext " + intStr[i];
|
|
1379
|
+
})
|
|
1380
|
+
.styles({ // "font-family": "Helvetica Neue",
|
|
1381
|
+
"font-size": function(d, i) {
|
|
1382
|
+
return topFontSizeArray[i];
|
|
1383
|
+
},
|
|
1384
|
+
"line-height": "1.42857143",
|
|
1385
|
+
"color": function(d, i) {
|
|
1386
|
+
return colorArray[i];
|
|
1387
|
+
},
|
|
1388
|
+
// if there are 4 items...make the first two bold
|
|
1389
|
+
"font-weight": function(d, i) {
|
|
1390
|
+
// using this variable numBoldLines
|
|
1391
|
+
if (i < numBoldLines) {
|
|
1392
|
+
return "bold";
|
|
1393
|
+
} else {
|
|
1394
|
+
return "normal";
|
|
1395
|
+
}
|
|
1396
|
+
// if (comparisonText.length > 3) {
|
|
1397
|
+
// if (i < (comparisonText.length - 2) ) {
|
|
1398
|
+
// return "bold";
|
|
1399
|
+
// }
|
|
1400
|
+
// else {
|
|
1401
|
+
// return "normal";
|
|
1402
|
+
// }
|
|
1403
|
+
// }
|
|
1404
|
+
// else {
|
|
1405
|
+
// return "normal";
|
|
1406
|
+
// }
|
|
1407
|
+
},
|
|
1408
|
+
})
|
|
1409
|
+
.text(function(d, i) {
|
|
1410
|
+
return d;
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
bottombgrect = axes.append("rect")
|
|
1414
|
+
.attr("x", 3)
|
|
1415
|
+
.attr("y", fullheight - axeslabelmargin.bottom - toptextheight)
|
|
1416
|
+
.attr("width", figwidth - 2)
|
|
1417
|
+
.attr("height", axeslabelmargin.bottom)
|
|
1418
|
+
.attr("fill", "white")
|
|
1419
|
+
.styles({
|
|
1420
|
+
"opacity": "1.0"
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1423
|
+
// draw the summary things
|
|
1424
|
+
sepline = axes.append("line")
|
|
1425
|
+
.attrs({
|
|
1426
|
+
"x1": 0,
|
|
1427
|
+
"x2": figwidth - 2,
|
|
1428
|
+
"y1": barHeight,
|
|
1429
|
+
"y2": barHeight,
|
|
1430
|
+
})
|
|
1431
|
+
.styles({
|
|
1432
|
+
"stroke-width": "1",
|
|
1433
|
+
"stroke": "black",
|
|
1434
|
+
});
|
|
1435
|
+
|
|
1436
|
+
maxShiftSum = Math.max(Math.abs(sumTypes[1]), Math.abs(sumTypes[2]), sumTypes[0], sumTypes[3], d3.sum(sumTypes));
|
|
1437
|
+
|
|
1438
|
+
topScale = d3.scaleLinear()
|
|
1439
|
+
.domain([-maxShiftSum, maxShiftSum])
|
|
1440
|
+
// .range([figwidth*.12,figwidth*.88]);
|
|
1441
|
+
.range([sumTextWidth, figwidth - sumTextWidth]);
|
|
1442
|
+
|
|
1443
|
+
// define the RHS summary bars so I can add if needed
|
|
1444
|
+
// summaryArray = [sumTypes[3],sumTypes[0],sumTypes[3]+sumTypes[1],d3.sum(sumTypes)];
|
|
1445
|
+
summaryArray = [sumTypes[3], sumTypes[0], d3.sum(sumTypes)];
|
|
1446
|
+
|
|
1447
|
+
typeClass = ["posup", "negdown", "sumgrey"];
|
|
1448
|
+
colorClass = ["#ffff4c", "#b3b3ff", "#272727"];
|
|
1449
|
+
|
|
1450
|
+
axes.selectAll(".sumrectR")
|
|
1451
|
+
.data(summaryArray)
|
|
1452
|
+
.enter()
|
|
1453
|
+
.append("rect")
|
|
1454
|
+
.attrs({
|
|
1455
|
+
"class": function(d, i) {
|
|
1456
|
+
return "sumrectR " + intStr0[i] + " " + typeClass[i];
|
|
1457
|
+
},
|
|
1458
|
+
"x": function(d, i) {
|
|
1459
|
+
if (d > 0) {
|
|
1460
|
+
return figcenter;
|
|
1461
|
+
} else {
|
|
1462
|
+
return topScale(d);
|
|
1463
|
+
}
|
|
1464
|
+
},
|
|
1465
|
+
"y": function(d, i) {
|
|
1466
|
+
if (i < 3) {
|
|
1467
|
+
return i * 17 + 7;
|
|
1468
|
+
} else {
|
|
1469
|
+
return i * 17 + 7 - 2;
|
|
1470
|
+
}
|
|
1471
|
+
},
|
|
1472
|
+
"height": function(d, i) {
|
|
1473
|
+
return 14;
|
|
1474
|
+
},
|
|
1475
|
+
"width": function(d, i) {
|
|
1476
|
+
if (d > 0) {
|
|
1477
|
+
return topScale(d) - figcenter;
|
|
1478
|
+
} else {
|
|
1479
|
+
return figcenter - topScale(d);
|
|
1480
|
+
}
|
|
1481
|
+
},
|
|
1482
|
+
"fill": function(d, i) {
|
|
1483
|
+
return colorClass[i];
|
|
1484
|
+
},
|
|
1485
|
+
})
|
|
1486
|
+
.styles({
|
|
1487
|
+
"opacity": function(d, i) {
|
|
1488
|
+
var specificType = [3, 0, -1];
|
|
1489
|
+
if ((shiftTypeSelect) && (shiftType !== specificType[i])) {
|
|
1490
|
+
return "0.14";
|
|
1491
|
+
} else {
|
|
1492
|
+
return "0.7";
|
|
1493
|
+
}
|
|
1494
|
+
},
|
|
1495
|
+
"stroke-width": "1",
|
|
1496
|
+
"stroke": "rgb(0,0,0)",
|
|
1497
|
+
})
|
|
1498
|
+
.on("mouseover", function(d, i) {
|
|
1499
|
+
var specificType = [3, 0, -1];
|
|
1500
|
+
// if we're in a shift selection
|
|
1501
|
+
if (shiftTypeSelect) {
|
|
1502
|
+
if (shiftType === specificType[i]) {
|
|
1503
|
+
// console.log("in a shift type, and that specific type");
|
|
1504
|
+
var rectSelection = d3.select(this).styles({
|
|
1505
|
+
opacity: "0.7"
|
|
1506
|
+
});
|
|
1507
|
+
} else {
|
|
1508
|
+
// console.log("in a shift type, but not that specific type");
|
|
1509
|
+
var rectSelection = d3.select(this).styles({
|
|
1510
|
+
opacity: "0.3"
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
// not in a shift selection
|
|
1515
|
+
else {
|
|
1516
|
+
// console.log("not in a shift type");
|
|
1517
|
+
var rectSelection = d3.select(this).styles({
|
|
1518
|
+
opacity: "1.0"
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
})
|
|
1522
|
+
.on("mouseout", function(d, i) {
|
|
1523
|
+
var specificType = [3, 0, -1];
|
|
1524
|
+
if (shiftTypeSelect) {
|
|
1525
|
+
if (shiftType === specificType[i]) {
|
|
1526
|
+
// console.log("in a shift type, and that specific type");
|
|
1527
|
+
var rectSelection = d3.select(this).styles({
|
|
1528
|
+
opacity: "0.7"
|
|
1529
|
+
});
|
|
1530
|
+
} else {
|
|
1531
|
+
// console.log("in a shift type, but not that specific type");
|
|
1532
|
+
// console.log(shiftType);
|
|
1533
|
+
// console.log(specificType);
|
|
1534
|
+
// console.log(i);
|
|
1535
|
+
// console.log(specificType[i]);
|
|
1536
|
+
var rectSelection = d3.select(this).styles({
|
|
1537
|
+
opacity: "0.14"
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
} else {
|
|
1541
|
+
// console.log("not in a shift type");
|
|
1542
|
+
var rectSelection = d3.select(this).styles({
|
|
1543
|
+
opacity: "0.7"
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
})
|
|
1547
|
+
.on("click", function(d, i) {
|
|
1548
|
+
var specificType = [3, 0, -1];
|
|
1549
|
+
figure.selectAll(".sumrectR,.sumrectL").styles({
|
|
1550
|
+
opacity: "0.1"
|
|
1551
|
+
});
|
|
1552
|
+
var rectSelection = d3.select(this).styles({
|
|
1553
|
+
opacity: "0.7"
|
|
1554
|
+
});
|
|
1555
|
+
if (i == 0) {
|
|
1556
|
+
shiftTypeSelect = true;
|
|
1557
|
+
shiftType = specificType[i];
|
|
1558
|
+
resetButton(true);
|
|
1559
|
+
shiftselencoder.varval("posup");
|
|
1560
|
+
// shoot them all away
|
|
1561
|
+
//d3.selectAll("rect.shiftrect, text.shifttext").transition().duration(1000).attr("transform",function(d,i) { if (d<0) { return "translate(-500,0)"; } else {return "translate(500,0)"; }});
|
|
1562
|
+
// keep the ones with class "three"
|
|
1563
|
+
//d3.selectAll("rect.shiftrect.three, text.shifttext.three").transition().duration(1000)
|
|
1564
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1565
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1566
|
+
});
|
|
1567
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1568
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1569
|
+
});
|
|
1570
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1571
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1572
|
+
});
|
|
1573
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1574
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1575
|
+
});
|
|
1576
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1577
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1578
|
+
});
|
|
1579
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1580
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1581
|
+
});
|
|
1582
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1583
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1584
|
+
});
|
|
1585
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1586
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1587
|
+
});
|
|
1588
|
+
} else if (i == 1) {
|
|
1589
|
+
shiftTypeSelect = true;
|
|
1590
|
+
shiftType = specificType[i];
|
|
1591
|
+
resetButton(true);
|
|
1592
|
+
shiftselencoder.varval("negdown");
|
|
1593
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1594
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1595
|
+
});
|
|
1596
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1597
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1598
|
+
});
|
|
1599
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1600
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1601
|
+
});
|
|
1602
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1603
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1604
|
+
});
|
|
1605
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1606
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1607
|
+
});
|
|
1608
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1609
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1610
|
+
});
|
|
1611
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1612
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1613
|
+
});
|
|
1614
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1615
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1616
|
+
});
|
|
1617
|
+
} else if (i == 2) {
|
|
1618
|
+
// shiftTypeSelect = true;
|
|
1619
|
+
// d3.selectAll(".sumrectR,.sumrectL").styles({opacity:"0.7"});
|
|
1620
|
+
resetfun();
|
|
1621
|
+
// shiftselencoder.varval("negdown");
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
axes.selectAll(".sumtextR")
|
|
1626
|
+
.data([sumTypes[3], sumTypes[0], d3.sum(sumTypes)])
|
|
1627
|
+
.enter()
|
|
1628
|
+
.append("text")
|
|
1629
|
+
.styles({
|
|
1630
|
+
"text-anchor": function(d, i) {
|
|
1631
|
+
return ((d > 0) ? "start" : "end");
|
|
1632
|
+
},
|
|
1633
|
+
"font-size": bigshifttextsize,
|
|
1634
|
+
})
|
|
1635
|
+
//.attr("y",function(d,i) { if (i<2) {return i*17+17;} else if ((sumTypes[3]+sumTypes[1])*(sumTypes[0]+sumTypes[2])<0) {return i*17+33; } else {return i*17+33; } })
|
|
1636
|
+
// for only three days
|
|
1637
|
+
.attrs({
|
|
1638
|
+
"class": "sumtextR",
|
|
1639
|
+
"id": function(d, i) {
|
|
1640
|
+
return "sumTextR" + i;
|
|
1641
|
+
},
|
|
1642
|
+
"y": function(d, i) {
|
|
1643
|
+
return i * 17 + 17;
|
|
1644
|
+
},
|
|
1645
|
+
"x": function(d, i) {
|
|
1646
|
+
return topScale(d) + 5 * d / Math.abs(d);
|
|
1647
|
+
},
|
|
1648
|
+
})
|
|
1649
|
+
.text(function(d, i) {
|
|
1650
|
+
if (i == 0) {
|
|
1651
|
+
return "\u2211+\u2191";
|
|
1652
|
+
}
|
|
1653
|
+
if (i == 1) {
|
|
1654
|
+
return "\u2211-\u2193";
|
|
1655
|
+
} else {
|
|
1656
|
+
return "\u2211";
|
|
1657
|
+
}
|
|
1658
|
+
});
|
|
1659
|
+
|
|
1660
|
+
// summaryArray = [sumTypes[1],sumTypes[2],sumTypes[0]+sumTypes[2]];
|
|
1661
|
+
summaryArray = [sumTypes[1], sumTypes[2]];
|
|
1662
|
+
|
|
1663
|
+
typeClass = ["posdown", "negup"];
|
|
1664
|
+
colorClass = ["#ffffb3", "#4c4cff"];
|
|
1665
|
+
|
|
1666
|
+
axes.selectAll(".sumrectL")
|
|
1667
|
+
.data(summaryArray)
|
|
1668
|
+
.enter()
|
|
1669
|
+
.append("rect")
|
|
1670
|
+
.attrs({
|
|
1671
|
+
"class": function(d, i) {
|
|
1672
|
+
return "sumrectL " + intStr0[i] + " " + typeClass[i];
|
|
1673
|
+
},
|
|
1674
|
+
"id": function(d, i) {
|
|
1675
|
+
return "sumTextL" + i;
|
|
1676
|
+
},
|
|
1677
|
+
"x": function(d, i) {
|
|
1678
|
+
if (i < 2) {
|
|
1679
|
+
return topScale(d);
|
|
1680
|
+
} else {
|
|
1681
|
+
// place the sum of negatives bar
|
|
1682
|
+
// if they are not opposing
|
|
1683
|
+
if ((sumTypes[3] + sumTypes[1]) * (sumTypes[0] + sumTypes[2]) > 0) {
|
|
1684
|
+
// if positive, place at end of other bar
|
|
1685
|
+
if (d > 0) {
|
|
1686
|
+
return topScale((sumTypes[3] + sumTypes[1]));
|
|
1687
|
+
}
|
|
1688
|
+
// if negative, place at left of other bar, minus length (+topScale(d))
|
|
1689
|
+
else {
|
|
1690
|
+
return topScale(d) - (figcenter - topScale((sumTypes[3] + sumTypes[1])));
|
|
1691
|
+
}
|
|
1692
|
+
} else {
|
|
1693
|
+
if (d > 0) {
|
|
1694
|
+
return figcenter
|
|
1695
|
+
} else {
|
|
1696
|
+
return topScale(d)
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
},
|
|
1701
|
+
"y": function(d, i) {
|
|
1702
|
+
return i * 17 + 7;
|
|
1703
|
+
},
|
|
1704
|
+
"height": function(d, i) {
|
|
1705
|
+
return 14;
|
|
1706
|
+
},
|
|
1707
|
+
"width": function(d, i) {
|
|
1708
|
+
if (d > 0) {
|
|
1709
|
+
return topScale(d) - figcenter;
|
|
1710
|
+
} else {
|
|
1711
|
+
return figcenter - topScale(d);
|
|
1712
|
+
}
|
|
1713
|
+
},
|
|
1714
|
+
"fill": function(d, i) {
|
|
1715
|
+
return colorClass[i];
|
|
1716
|
+
},
|
|
1717
|
+
})
|
|
1718
|
+
.styles({
|
|
1719
|
+
"opacity": function(d, i) {
|
|
1720
|
+
var specificType = [1, 2];
|
|
1721
|
+
if ((shiftTypeSelect) && (shiftType !== specificType[i])) {
|
|
1722
|
+
return "0.14";
|
|
1723
|
+
} else {
|
|
1724
|
+
return "0.7";
|
|
1725
|
+
}
|
|
1726
|
+
},
|
|
1727
|
+
"stroke-width": "1",
|
|
1728
|
+
"stroke": "rgb(0,0,0)"
|
|
1729
|
+
})
|
|
1730
|
+
.on("mouseover", function(d, i) {
|
|
1731
|
+
var specificType = [1, 2];
|
|
1732
|
+
// if we're in a shift selection
|
|
1733
|
+
if (shiftTypeSelect) {
|
|
1734
|
+
if (shiftType === specificType[i]) {
|
|
1735
|
+
// console.log("in a shift type, and that specific type");
|
|
1736
|
+
var rectSelection = d3.select(this).styles({
|
|
1737
|
+
opacity: "0.7"
|
|
1738
|
+
});
|
|
1739
|
+
} else {
|
|
1740
|
+
// console.log("in a shift type, but not that specific type");
|
|
1741
|
+
var rectSelection = d3.select(this).styles({
|
|
1742
|
+
opacity: "0.3"
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
// not in a shift selection
|
|
1747
|
+
else {
|
|
1748
|
+
// console.log("not in a shift type");
|
|
1749
|
+
var rectSelection = d3.select(this).styles({
|
|
1750
|
+
opacity: "1.0"
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
})
|
|
1754
|
+
.on("mouseout", function(d, i) {
|
|
1755
|
+
var specificType = [1, 2];
|
|
1756
|
+
if (shiftTypeSelect) {
|
|
1757
|
+
if (shiftType === specificType[i]) {
|
|
1758
|
+
// console.log("in a shift type, and that specific type");
|
|
1759
|
+
var rectSelection = d3.select(this).styles({
|
|
1760
|
+
opacity: "0.7"
|
|
1761
|
+
});
|
|
1762
|
+
} else {
|
|
1763
|
+
// console.log("in a shift type, but not that specific type");
|
|
1764
|
+
// console.log(shiftType);
|
|
1765
|
+
// console.log(specificType);
|
|
1766
|
+
// console.log(i);
|
|
1767
|
+
// console.log(specificType[i]);
|
|
1768
|
+
var rectSelection = d3.select(this).styles({
|
|
1769
|
+
opacity: "0.14"
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
} else {
|
|
1773
|
+
// console.log("not in a shift type");
|
|
1774
|
+
var rectSelection = d3.select(this).styles({
|
|
1775
|
+
opacity: "0.7"
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
})
|
|
1779
|
+
.on("click", function(d, i) {
|
|
1780
|
+
var specificType = [1, 2];
|
|
1781
|
+
shiftTypeSelect = true;
|
|
1782
|
+
shiftType = specificType[i];
|
|
1783
|
+
figure.selectAll(".sumrectR,.sumrectL").styles({
|
|
1784
|
+
opacity: "0.1"
|
|
1785
|
+
});
|
|
1786
|
+
var rectSelection = d3.select(this).styles({
|
|
1787
|
+
opacity: "0.7"
|
|
1788
|
+
});
|
|
1789
|
+
resetButton(true);
|
|
1790
|
+
if (i == 0) {
|
|
1791
|
+
shiftselencoder.varval("posdown");
|
|
1792
|
+
// together
|
|
1793
|
+
// axes.selectAll("rect.shiftrect.zero, text.shifttext.zero, rect.shiftrect.three, text.shifttext.three, rect.shiftrect.two, text.shifttext.two").transition().duration(1000).attr("transform",function(d,i) { if (d<0) { return "translate(-500,0)"; } else {return "translate(500,0)"; }});
|
|
1794
|
+
// separate
|
|
1795
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1796
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1797
|
+
});
|
|
1798
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1799
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1800
|
+
});
|
|
1801
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1802
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1803
|
+
});
|
|
1804
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1805
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1806
|
+
});
|
|
1807
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1808
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1809
|
+
});
|
|
1810
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1811
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1812
|
+
});
|
|
1813
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1814
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1815
|
+
});
|
|
1816
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1817
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1818
|
+
});
|
|
1819
|
+
} else if (i == 1) {
|
|
1820
|
+
shiftselencoder.varval("negup");
|
|
1821
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1822
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1823
|
+
});
|
|
1824
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
1825
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1826
|
+
});
|
|
1827
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1828
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1829
|
+
});
|
|
1830
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
1831
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1832
|
+
});
|
|
1833
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1834
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
1835
|
+
});
|
|
1836
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
1837
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
1838
|
+
});
|
|
1839
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1840
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
1841
|
+
});
|
|
1842
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
1843
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
1844
|
+
});
|
|
1845
|
+
}
|
|
1846
|
+
});
|
|
1847
|
+
|
|
1848
|
+
axes.selectAll(".sumtextL")
|
|
1849
|
+
.data(summaryArray)
|
|
1850
|
+
.enter()
|
|
1851
|
+
.append("text")
|
|
1852
|
+
.styles({
|
|
1853
|
+
"text-anchor": "end",
|
|
1854
|
+
"font-size": bigshifttextsize,
|
|
1855
|
+
})
|
|
1856
|
+
.attr("class", "sumtextL")
|
|
1857
|
+
.attr("y", function(d, i) {
|
|
1858
|
+
return i * 17 + 17;
|
|
1859
|
+
})
|
|
1860
|
+
.text(function(d, i) {
|
|
1861
|
+
if (i == 0) {
|
|
1862
|
+
return "\u2211+\u2193";
|
|
1863
|
+
} else {
|
|
1864
|
+
return "\u2211-\u2191";
|
|
1865
|
+
}
|
|
1866
|
+
})
|
|
1867
|
+
.attr("x", function(d, i) {
|
|
1868
|
+
return topScale(d) - 5;
|
|
1869
|
+
});
|
|
1870
|
+
|
|
1871
|
+
// x label of shift, outside of the SVG
|
|
1872
|
+
xlabel = canvas.append("text")
|
|
1873
|
+
.text(xlabel_text)
|
|
1874
|
+
.attr("class", "axes-text")
|
|
1875
|
+
.attr("x", axeslabelmargin.left + figcenter) // 350-20-10 for svg width,
|
|
1876
|
+
.attr("y", boxheight - 7)
|
|
1877
|
+
.styles({
|
|
1878
|
+
"font-size": xylabelfontsize,
|
|
1879
|
+
"fill": "#000000",
|
|
1880
|
+
"text-anchor": "middle"
|
|
1881
|
+
});
|
|
1882
|
+
|
|
1883
|
+
ylabel = canvas.append("text")
|
|
1884
|
+
.text(ylabel_text)
|
|
1885
|
+
.attr("class", "axes-text")
|
|
1886
|
+
.attr("x", 18)
|
|
1887
|
+
.attr("y", figheight / 2 + 60 + toptextheight)
|
|
1888
|
+
.attr("font-size", xylabelfontsize)
|
|
1889
|
+
.attr("fill", "#000000")
|
|
1890
|
+
.attr("transform", "rotate(-90.0," + (18) + "," + (figheight / 2 + 60 + toptextheight) + ")");
|
|
1891
|
+
|
|
1892
|
+
axes.property("__zoom", 0);
|
|
1893
|
+
|
|
1894
|
+
function zoomed() {
|
|
1895
|
+
// console.log(d3.event);
|
|
1896
|
+
// console.log(this.__zoom);
|
|
1897
|
+
if ((this.__zoom <= 0) && (d3.event.deltaY < 0)) return;
|
|
1898
|
+
d3.event.preventDefault();
|
|
1899
|
+
// console.log(zoom);
|
|
1900
|
+
// console.log(axes);
|
|
1901
|
+
// console.log(this);
|
|
1902
|
+
// console.log(this.__zoom);
|
|
1903
|
+
// console.log(axes.__zoom);
|
|
1904
|
+
// console.log(axes.property("__zoom"));
|
|
1905
|
+
// axes.call(zoom.transform);
|
|
1906
|
+
// axes.property("__zoom",axes.property("__zoom")+d3.event.deltaY);
|
|
1907
|
+
this.__zoom += d3.event.deltaY / 2;
|
|
1908
|
+
// this prevents scrolling in the wrong direction
|
|
1909
|
+
// if (d3.event.transform.y > 0) {
|
|
1910
|
+
// zoom.translate([0,0]).scale(1);
|
|
1911
|
+
// }
|
|
1912
|
+
var that = this;
|
|
1913
|
+
axes.selectAll("rect.shiftrect")
|
|
1914
|
+
.attr("y", function(d) {
|
|
1915
|
+
return -that.__zoom;
|
|
1916
|
+
});
|
|
1917
|
+
axes.selectAll("text.shifttext")
|
|
1918
|
+
.attr("y", function(d) {
|
|
1919
|
+
return -that.__zoom;
|
|
1920
|
+
});
|
|
1921
|
+
// .attr("y",d3.min([-d3.event.transform.y,0]));
|
|
1922
|
+
// axes.selectAll("text.shifttext")
|
|
1923
|
+
// .attr("y",-d3.event.transform.y);
|
|
1924
|
+
if (distflag) {
|
|
1925
|
+
// console.log(d3.event.translate);
|
|
1926
|
+
// move scaled to the height of the window (23 words)
|
|
1927
|
+
var scaledMove = d3.event.translate.y / (figheight - yHeight);
|
|
1928
|
+
// console.log(scaledMove);
|
|
1929
|
+
// move relative to the height of the box and those 23 words
|
|
1930
|
+
var relMove = scaledMove * distgrouph * numWords / lens.length;
|
|
1931
|
+
// console.log(relMove);
|
|
1932
|
+
figure.select(".distwin").attrs({
|
|
1933
|
+
"y": d3.max([2, -relMove + 2]),
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
}; // zoomed
|
|
1937
|
+
|
|
1938
|
+
// // console.log(figheight);
|
|
1939
|
+
// // attach this guy. cleaner with the group
|
|
1940
|
+
// help = axes.append("g")
|
|
1941
|
+
// .attrs({"class": "help",
|
|
1942
|
+
// "fill": "#B8B8B8",
|
|
1943
|
+
// "transform": "translate("+(5)+","+(figheight-16)+")",
|
|
1944
|
+
// })
|
|
1945
|
+
// .on("click", function() {
|
|
1946
|
+
// window.open("http://hedonometer.org/instructions.html#wordshifts","_blank");
|
|
1947
|
+
// })
|
|
1948
|
+
// .selectAll("text.help")
|
|
1949
|
+
// .data(["click here","for instructions"])
|
|
1950
|
+
// .enter()
|
|
1951
|
+
// .append("text")
|
|
1952
|
+
// .attrs({"class": "help",
|
|
1953
|
+
// "fill": "#B8B8B8",
|
|
1954
|
+
// "x": 0,
|
|
1955
|
+
// "y": function(d,i) { return i*10; },
|
|
1956
|
+
// "font-size": "8.0px", })
|
|
1957
|
+
// .styles({"text-anchor": "start", })
|
|
1958
|
+
// .text(function(d) { return d; });
|
|
1959
|
+
|
|
1960
|
+
if (distflag) {
|
|
1961
|
+
computedistributions();
|
|
1962
|
+
|
|
1963
|
+
// console.log(figheight);
|
|
1964
|
+
// console.log(yHeight);
|
|
1965
|
+
var distgrouph = 250;
|
|
1966
|
+
var distgroupw = 70;
|
|
1967
|
+
var dxspace = 1;
|
|
1968
|
+
var dyspace = 2;
|
|
1969
|
+
|
|
1970
|
+
distgroup = axes.append("g")
|
|
1971
|
+
.attrs({
|
|
1972
|
+
"class": "dist",
|
|
1973
|
+
"fill": "#B8B8B8",
|
|
1974
|
+
"transform": "translate(" + (5) + "," + (figheight - 28 - distgrouph) + ")",
|
|
1975
|
+
});
|
|
1976
|
+
|
|
1977
|
+
distgroup.append("rect")
|
|
1978
|
+
.attrs({
|
|
1979
|
+
"x": 0,
|
|
1980
|
+
"y": 0,
|
|
1981
|
+
"height": distgrouph,
|
|
1982
|
+
"width": distgroupw,
|
|
1983
|
+
"class": "distbg",
|
|
1984
|
+
"stroke-width": "2",
|
|
1985
|
+
"stroke": "rgb(150,150,150)",
|
|
1986
|
+
"fill": "#FCFCFC",
|
|
1987
|
+
"opacity": "0.96",
|
|
1988
|
+
});
|
|
1989
|
+
|
|
1990
|
+
var distx = d3.scaleLinear()
|
|
1991
|
+
.domain(d3.extent(dist.map(function(d) {
|
|
1992
|
+
return d[4];
|
|
1993
|
+
})))
|
|
1994
|
+
.range([dxspace, distgroupw - 2 * dxspace]);
|
|
1995
|
+
|
|
1996
|
+
var disty = d3.scaleLinear()
|
|
1997
|
+
.domain([0, nbins - 1])
|
|
1998
|
+
.range([dyspace, distgrouph - dyspace]);
|
|
1999
|
+
// .range([dyspace,distgrouph-2*dyspace]);
|
|
2000
|
+
|
|
2001
|
+
var line = d3.line()
|
|
2002
|
+
.x(function(d, i) {
|
|
2003
|
+
return distx(d);
|
|
2004
|
+
})
|
|
2005
|
+
.y(function(d, i) {
|
|
2006
|
+
return disty(i);
|
|
2007
|
+
})
|
|
2008
|
+
.curve(d3.curveCardinal);
|
|
2009
|
+
// .interpolate("cardinal");
|
|
2010
|
+
|
|
2011
|
+
// console.log(dist.map(function(d) { return d[4]; }));
|
|
2012
|
+
|
|
2013
|
+
var distline = distgroup.append("path")
|
|
2014
|
+
.datum(dist.map(function(d) {
|
|
2015
|
+
return d[4];
|
|
2016
|
+
}))
|
|
2017
|
+
.attr("class", "line")
|
|
2018
|
+
.attr("d", line)
|
|
2019
|
+
.attr("stroke", "red")
|
|
2020
|
+
.attr("stroke-width", 1.25)
|
|
2021
|
+
.attr("fill", "none");
|
|
2022
|
+
|
|
2023
|
+
var cdistx = d3.scaleLinear()
|
|
2024
|
+
.domain(d3.extent(cdist.map(function(d) {
|
|
2025
|
+
return d[4];
|
|
2026
|
+
})))
|
|
2027
|
+
.range([dxspace, distgroupw - 2 * dxspace]);
|
|
2028
|
+
|
|
2029
|
+
var cline = d3.line()
|
|
2030
|
+
.x(function(d, i) {
|
|
2031
|
+
return cdistx(d);
|
|
2032
|
+
})
|
|
2033
|
+
.y(function(d, i) {
|
|
2034
|
+
return disty(i);
|
|
2035
|
+
})
|
|
2036
|
+
.curve(d3.curveCardinal);
|
|
2037
|
+
// .interpolate("cardinal");
|
|
2038
|
+
|
|
2039
|
+
var cdistline = distgroup.append("path")
|
|
2040
|
+
.datum(cdist.map(function(d) {
|
|
2041
|
+
return d[4];
|
|
2042
|
+
}))
|
|
2043
|
+
.attr("class", "line")
|
|
2044
|
+
.attr("d", cline)
|
|
2045
|
+
.attr("stroke", "blue")
|
|
2046
|
+
.attr("stroke-width", 1.25)
|
|
2047
|
+
.attr("fill", "none");
|
|
2048
|
+
|
|
2049
|
+
// console.log(distgrouph*numWords/lens.length);
|
|
2050
|
+
// console.log(distgrouph*numWords/2000);
|
|
2051
|
+
|
|
2052
|
+
var distwindowrect = distgroup.append("rect")
|
|
2053
|
+
.attrs({
|
|
2054
|
+
"x": 0,
|
|
2055
|
+
"y": 2,
|
|
2056
|
+
"height": distgrouph * numWords / nwords,
|
|
2057
|
+
"width": distgroupw,
|
|
2058
|
+
"class": "distwin",
|
|
2059
|
+
"stroke-width": "0.75",
|
|
2060
|
+
"stroke": "rgb(20,20,20)",
|
|
2061
|
+
"fill": "#FCFCFC",
|
|
2062
|
+
"opacity": "0.6",
|
|
2063
|
+
});
|
|
2064
|
+
|
|
2065
|
+
var nwordstext = distgroup.append("text")
|
|
2066
|
+
.attrs({
|
|
2067
|
+
"x": distgroupw + 2,
|
|
2068
|
+
"y": distgrouph + 2,
|
|
2069
|
+
"class": "nwordslabel",
|
|
2070
|
+
})
|
|
2071
|
+
.styles({
|
|
2072
|
+
"fill": "#B8B8B8",
|
|
2073
|
+
"font-size": distlabeltext,
|
|
2074
|
+
"text-anchor": "start",
|
|
2075
|
+
})
|
|
2076
|
+
.text(nwords);
|
|
2077
|
+
|
|
2078
|
+
distgroup.append("text")
|
|
2079
|
+
.attrs({
|
|
2080
|
+
"x": distgroupw + 2,
|
|
2081
|
+
"y": 2,
|
|
2082
|
+
"class": "zerolabel",
|
|
2083
|
+
})
|
|
2084
|
+
.styles({
|
|
2085
|
+
"fill": "#B8B8B8",
|
|
2086
|
+
"font-size": distlabeltext,
|
|
2087
|
+
"text-anchor": "start",
|
|
2088
|
+
})
|
|
2089
|
+
.text("0");
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
credit = axes.selectAll("text.credit")
|
|
2093
|
+
// .data(["visualization by","@andyreagan","word shifts by","@hedonometer"])
|
|
2094
|
+
.data(["visualization by", "@andyreagan", ])
|
|
2095
|
+
.enter()
|
|
2096
|
+
.append("text")
|
|
2097
|
+
.attrs({
|
|
2098
|
+
"class": "credit",
|
|
2099
|
+
"x": (figwidth - 5),
|
|
2100
|
+
"y": function(d, i) {
|
|
2101
|
+
return figheight - 15 + i * 10;
|
|
2102
|
+
},
|
|
2103
|
+
})
|
|
2104
|
+
.styles({
|
|
2105
|
+
"text-anchor": "end",
|
|
2106
|
+
"fill": "#B8B8B8",
|
|
2107
|
+
"font-size": creditfontsize,
|
|
2108
|
+
})
|
|
2109
|
+
.text(function(d) {
|
|
2110
|
+
return d;
|
|
2111
|
+
});
|
|
2112
|
+
|
|
2113
|
+
// get this inside of the plot...so that resizeshift won't get called
|
|
2114
|
+
// too early (before a shift has been plotted)
|
|
2115
|
+
if (!widthsetexplicitly) {
|
|
2116
|
+
d3.select(window).on("resize.shiftplot", resizeshift);
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
if (reset) {
|
|
2120
|
+
// call it
|
|
2121
|
+
resetButton(true);
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
if (translate) {
|
|
2125
|
+
console.log(translate);
|
|
2126
|
+
translateButton();
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
return that;
|
|
2130
|
+
|
|
2131
|
+
}; // hedotools.shifter.plot
|
|
2132
|
+
|
|
2133
|
+
function resetButton(showb) {
|
|
2134
|
+
// console.log("resetbutton function");
|
|
2135
|
+
|
|
2136
|
+
// console.log(showb);
|
|
2137
|
+
// showb = showb || true;
|
|
2138
|
+
// console.log("showing reset button?");
|
|
2139
|
+
// console.log(showb);
|
|
2140
|
+
figure.selectAll(".resetbutton").remove();
|
|
2141
|
+
|
|
2142
|
+
if (showb) {
|
|
2143
|
+
|
|
2144
|
+
var resetGroup = canvas.append("g")
|
|
2145
|
+
.attr("transform", "translate(" + (4) + "," + (56 + toptextheight) + ") rotate(-90)")
|
|
2146
|
+
.attr("class", "resetbutton");
|
|
2147
|
+
|
|
2148
|
+
resetGroup.append("rect")
|
|
2149
|
+
.attr("x", 0)
|
|
2150
|
+
.attr("y", 0)
|
|
2151
|
+
.attr("rx", 3)
|
|
2152
|
+
.attr("ry", 3)
|
|
2153
|
+
.attr("width", 48)
|
|
2154
|
+
.attr("height", 17)
|
|
2155
|
+
.attr("fill", "#F0F0F0") //http://www.w3schools.com/html/html_colors.asp
|
|
2156
|
+
.styles({
|
|
2157
|
+
"stroke-width": "0.5",
|
|
2158
|
+
"stroke": "rgb(0,0,0)"
|
|
2159
|
+
});
|
|
2160
|
+
|
|
2161
|
+
resetGroup.append("text")
|
|
2162
|
+
.text("Reset")
|
|
2163
|
+
.attr("x", 6)
|
|
2164
|
+
.attr("y", 13)
|
|
2165
|
+
.attr("font-size", resetfontsize);
|
|
2166
|
+
|
|
2167
|
+
resetGroup.append("rect")
|
|
2168
|
+
.attr("x", 0)
|
|
2169
|
+
.attr("y", 0)
|
|
2170
|
+
.attr("rx", 3)
|
|
2171
|
+
.attr("ry", 3)
|
|
2172
|
+
.attr("width", 48)
|
|
2173
|
+
.attr("height", 18)
|
|
2174
|
+
.attr("fill", "white") //http://www.w3schools.com/html/html_colors.asp
|
|
2175
|
+
.styles({
|
|
2176
|
+
"opacity": "0.0"
|
|
2177
|
+
})
|
|
2178
|
+
.on("click", function() {
|
|
2179
|
+
resetfun();
|
|
2180
|
+
});
|
|
2181
|
+
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
}; // resetButton
|
|
2185
|
+
|
|
2186
|
+
var replot = function() {
|
|
2187
|
+
var that = this;
|
|
2188
|
+
|
|
2189
|
+
// apply new data to the bars, transition everything
|
|
2190
|
+
// tricky to get the transition right
|
|
2191
|
+
var yHeight = (7 + 17 * 3 + 14 + 5 - 13); // 101
|
|
2192
|
+
|
|
2193
|
+
// linear scale function
|
|
2194
|
+
y.range([figheight + 2, yHeight]);
|
|
2195
|
+
sepline.transition().duration(1000).attrs({
|
|
2196
|
+
"y1": barHeight,
|
|
2197
|
+
"y2": barHeight,
|
|
2198
|
+
});
|
|
2199
|
+
|
|
2200
|
+
if (viz_type_decoder().cached === "table") {
|
|
2201
|
+
// console.log("removing table stuff");
|
|
2202
|
+
newrank.remove();
|
|
2203
|
+
newfreq.remove();
|
|
2204
|
+
newtype.remove();
|
|
2205
|
+
newmag.remove();
|
|
2206
|
+
header.remove();
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
viz_type.varval("wordshift");
|
|
2210
|
+
// console.log("making a wordshift");
|
|
2211
|
+
|
|
2212
|
+
// make sure to update this
|
|
2213
|
+
if (comparisonText[0].length < 1) {
|
|
2214
|
+
if (compH >= refH) {
|
|
2215
|
+
var happysad = "happier";
|
|
2216
|
+
} else {
|
|
2217
|
+
var happysad = "less happy";
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
// console.log("generating text for wordshift");
|
|
2221
|
+
comparisonText = splitstring(
|
|
2222
|
+
["Reference happiness: " + refH.toFixed(2), "Comparison happiness: " + compH.toFixed(2), "Why comparison is " + happysad + " than reference:"],
|
|
2223
|
+
boxwidth - 10 - logowidth,
|
|
2224
|
+
"14px " + fontString
|
|
2225
|
+
);
|
|
2226
|
+
// console.log(comparisonText);
|
|
2227
|
+
} else {
|
|
2228
|
+
if (split_top_strings) {
|
|
2229
|
+
comparisonText = splitstring(
|
|
2230
|
+
comparisonText,
|
|
2231
|
+
boxwidth - 10 - logowidth,
|
|
2232
|
+
"14px " + fontString
|
|
2233
|
+
);
|
|
2234
|
+
}
|
|
2235
|
+
// console.log(comparisonText);
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
// could set a cap to make sure no 0"s
|
|
2239
|
+
maxWidth = d3.max(sortedWords.slice(0, 5).map(function(d) {
|
|
2240
|
+
return d.width(wordfontsize + "px " + fontString);
|
|
2241
|
+
}));
|
|
2242
|
+
|
|
2243
|
+
var xpadding = 10;
|
|
2244
|
+
// linear scale function
|
|
2245
|
+
x.domain([-Math.abs(sortedMag[0]), Math.abs(sortedMag[0])])
|
|
2246
|
+
.range([maxWidth + xpadding, figwidth - maxWidth - xpadding]);
|
|
2247
|
+
|
|
2248
|
+
if (show_x_axis_bool) {
|
|
2249
|
+
canvas.select(".x.axis")
|
|
2250
|
+
.call(xAxis);
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
// get the height again
|
|
2254
|
+
toptextheight = comparisonText.length * 17 + 13;
|
|
2255
|
+
// console.log(toptextheight);
|
|
2256
|
+
|
|
2257
|
+
resetButton(true);
|
|
2258
|
+
|
|
2259
|
+
// reset this
|
|
2260
|
+
figheight = boxheight - axeslabelmargin.top - axeslabelmargin.bottom - toptextheight;
|
|
2261
|
+
|
|
2262
|
+
// linear scale function
|
|
2263
|
+
y.range([figheight + 2, yHeight]);
|
|
2264
|
+
|
|
2265
|
+
axes.attr("transform", "translate(" + (axeslabelmargin.left) + "," + (axeslabelmargin.top + toptextheight) + ")")
|
|
2266
|
+
.attr("height", figheight);
|
|
2267
|
+
|
|
2268
|
+
bgrect.attr("height", figheight - 2).styles({
|
|
2269
|
+
"stroke-width": 0.5,
|
|
2270
|
+
"stroke": "rgb(20,20,20)"
|
|
2271
|
+
});
|
|
2272
|
+
|
|
2273
|
+
topbgrect2.attr("height", toptextheight);
|
|
2274
|
+
|
|
2275
|
+
// // console.log(figheight);
|
|
2276
|
+
// canvas.selectAll("g.help").remove();
|
|
2277
|
+
// help.remove();
|
|
2278
|
+
// help = axes.append("g")
|
|
2279
|
+
// .attrs({"class": "help",
|
|
2280
|
+
// "fill": "#B8B8B8",
|
|
2281
|
+
// "transform": "translate("+(5)+","+(figheight-16)+")",
|
|
2282
|
+
// })
|
|
2283
|
+
// .on("click", function() {
|
|
2284
|
+
// window.open("http://hedonometer.org/instructions.html#wordshifts","_blank");
|
|
2285
|
+
// })
|
|
2286
|
+
// .selectAll("text.help")
|
|
2287
|
+
// .data(["click here","for instructions"])
|
|
2288
|
+
// .enter()
|
|
2289
|
+
// .append("text")
|
|
2290
|
+
// .attrs({"class": "help",
|
|
2291
|
+
// "fill": "#B8B8B8",
|
|
2292
|
+
// "x": 0,
|
|
2293
|
+
// "y": function(d,i) { return i*10; },
|
|
2294
|
+
// "font-size": "8.0px", })
|
|
2295
|
+
// .styles({"text-anchor": "start", })
|
|
2296
|
+
// .text(function(d) { return d; });
|
|
2297
|
+
|
|
2298
|
+
|
|
2299
|
+
// since I really want this on there (in safari)
|
|
2300
|
+
// go through the extra trouble of removing it first
|
|
2301
|
+
canvas.selectAll("text.credit").remove();
|
|
2302
|
+
credit.remove();
|
|
2303
|
+
credit = axes.selectAll("text.credit")
|
|
2304
|
+
.data(["visualization by", "@andyreagan"])
|
|
2305
|
+
.enter()
|
|
2306
|
+
.append("text")
|
|
2307
|
+
.attrs({
|
|
2308
|
+
"class": "credit",
|
|
2309
|
+
"fill": "#B8B8B8",
|
|
2310
|
+
"x": (figwidth - 5),
|
|
2311
|
+
"y": function(d, i) {
|
|
2312
|
+
return figheight - 15 + i * 10;
|
|
2313
|
+
},
|
|
2314
|
+
"font-size": "8.0px",
|
|
2315
|
+
})
|
|
2316
|
+
.styles({
|
|
2317
|
+
"text-anchor": "end",
|
|
2318
|
+
})
|
|
2319
|
+
.text(function(d) {
|
|
2320
|
+
return d;
|
|
2321
|
+
});
|
|
2322
|
+
|
|
2323
|
+
// console.log("the comparison text in replot is:");
|
|
2324
|
+
// console.log(comparisonText);
|
|
2325
|
+
// console.log(toptext);
|
|
2326
|
+
canvas.selectAll("text.titletext").remove();
|
|
2327
|
+
toptext.remove();
|
|
2328
|
+
toptext = canvas.selectAll("text.titletext")
|
|
2329
|
+
.data(comparisonText)
|
|
2330
|
+
.enter()
|
|
2331
|
+
.append("text")
|
|
2332
|
+
.attrs({
|
|
2333
|
+
"y": function(d, i) {
|
|
2334
|
+
return (i + 1) * 17;
|
|
2335
|
+
},
|
|
2336
|
+
"x": 3,
|
|
2337
|
+
"class": function(d, i) {
|
|
2338
|
+
return "titletext " + intStr[i];
|
|
2339
|
+
},
|
|
2340
|
+
})
|
|
2341
|
+
.styles({ // "font-family": "Helvetica Neue",
|
|
2342
|
+
"font-size": function(d, i) {
|
|
2343
|
+
return topFontSizeArray[i];
|
|
2344
|
+
},
|
|
2345
|
+
"line-height": "1.42857143",
|
|
2346
|
+
"color": function(d, i) {
|
|
2347
|
+
return colorArray[i];
|
|
2348
|
+
},
|
|
2349
|
+
// if there are 4 items...make the first two bold
|
|
2350
|
+
"font-weight": function(d, i) {
|
|
2351
|
+
// using this variable numBoldLines
|
|
2352
|
+
if (i < numBoldLines) {
|
|
2353
|
+
return "bold";
|
|
2354
|
+
} else {
|
|
2355
|
+
return "normal";
|
|
2356
|
+
}
|
|
2357
|
+
},
|
|
2358
|
+
})
|
|
2359
|
+
.text(function(d, i) {
|
|
2360
|
+
return d;
|
|
2361
|
+
});
|
|
2362
|
+
|
|
2363
|
+
bottombgrect.attr("y", fullheight - axeslabelmargin.bottom - toptextheight);
|
|
2364
|
+
|
|
2365
|
+
// both of these need their y height reset
|
|
2366
|
+
// resetButton(true);
|
|
2367
|
+
|
|
2368
|
+
// if (translate) {
|
|
2369
|
+
// translateButton();
|
|
2370
|
+
// }
|
|
2371
|
+
|
|
2372
|
+
var newbars = axes.selectAll("rect.shiftrect").data(sortedMag);
|
|
2373
|
+
var newwords = axes.selectAll("text.shifttext").data(sortedMag);
|
|
2374
|
+
// console.log(sortedWords);
|
|
2375
|
+
// console.log(sortedMag);
|
|
2376
|
+
// console.log(compF);
|
|
2377
|
+
|
|
2378
|
+
var transition_duration = 0;
|
|
2379
|
+
if (shiftseldecoder().current === "none" || shiftseldecoder().current.length === 0) {
|
|
2380
|
+
transition_duration = 1500;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
newbars.transition().duration(1500)
|
|
2385
|
+
.attrs({
|
|
2386
|
+
"fill": function(d, i) {
|
|
2387
|
+
if (sortedType[i] == 2) {
|
|
2388
|
+
return "#4C4CFF";
|
|
2389
|
+
} else if (sortedType[i] == 3) {
|
|
2390
|
+
return "#FFFF4C";
|
|
2391
|
+
} else if (sortedType[i] == 0) {
|
|
2392
|
+
return "#B3B3FF";
|
|
2393
|
+
} else {
|
|
2394
|
+
return "#FFFFB3";
|
|
2395
|
+
}
|
|
2396
|
+
},
|
|
2397
|
+
"class": function(d, i) {
|
|
2398
|
+
return "shiftrect " + intStr0[sortedType[i]];
|
|
2399
|
+
},
|
|
2400
|
+
// "x":function(d,i) {
|
|
2401
|
+
// if (d>0) { return figcenter; }
|
|
2402
|
+
// else { return x(d)} },
|
|
2403
|
+
// "y": function(d,i) { return y(i+1); },
|
|
2404
|
+
"x": 0,
|
|
2405
|
+
"y": 0,
|
|
2406
|
+
"transform": function(d, i) {
|
|
2407
|
+
if (d > 0) {
|
|
2408
|
+
return "translate(" + figcenter + "," + y(i + 1) + ")";
|
|
2409
|
+
} else {
|
|
2410
|
+
return "translate(" + x(d) + "," + y(i + 1) + ")";
|
|
2411
|
+
}
|
|
2412
|
+
},
|
|
2413
|
+
"height": function(d, i) {
|
|
2414
|
+
return iBarH;
|
|
2415
|
+
},
|
|
2416
|
+
"width": function(d, i) {
|
|
2417
|
+
if ((d) > 0) {
|
|
2418
|
+
return x(d) - x(0);
|
|
2419
|
+
} else {
|
|
2420
|
+
return x(0) - x(d);
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
});
|
|
2424
|
+
|
|
2425
|
+
newwords.transition().duration(1500)
|
|
2426
|
+
.attrs({
|
|
2427
|
+
"class": function(d, i) {
|
|
2428
|
+
return "shifttext " + intStr0[sortedType[i]];
|
|
2429
|
+
},
|
|
2430
|
+
"x": 0,
|
|
2431
|
+
"y": 0,
|
|
2432
|
+
"transform": function(d, i) {
|
|
2433
|
+
if (d > 0) {
|
|
2434
|
+
return "translate(" + (x(d) + 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
2435
|
+
} else {
|
|
2436
|
+
return "translate(" + (x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
2437
|
+
}
|
|
2438
|
+
},
|
|
2439
|
+
})
|
|
2440
|
+
// .attr("class", function(d,i) { return "shifttext "+intStr0[sortedType[i]]; })
|
|
2441
|
+
// .attr("transform", null)
|
|
2442
|
+
// .attr("y",function(d,i) { return y(i+1)+iBarH; })
|
|
2443
|
+
// .attr("x",function(d,i) { if (d>0) {return x(d)+2;} else {return x(d)-2; } } )
|
|
2444
|
+
.styles({
|
|
2445
|
+
"text-anchor": function(d, i) {
|
|
2446
|
+
if (sortedMag[i] < 0) {
|
|
2447
|
+
return "end";
|
|
2448
|
+
} else {
|
|
2449
|
+
return "start";
|
|
2450
|
+
}
|
|
2451
|
+
},
|
|
2452
|
+
"font-size": wordfontsize,
|
|
2453
|
+
})
|
|
2454
|
+
.text(function(d, i) {
|
|
2455
|
+
return sortedWords[i];
|
|
2456
|
+
});
|
|
2457
|
+
|
|
2458
|
+
|
|
2459
|
+
console.log(shiftseldecoder().current);
|
|
2460
|
+
if (shiftseldecoder().current === "posup") {
|
|
2461
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2462
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2463
|
+
});
|
|
2464
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2465
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2466
|
+
});
|
|
2467
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2468
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2469
|
+
});
|
|
2470
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2471
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2472
|
+
});
|
|
2473
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2474
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2475
|
+
});
|
|
2476
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2477
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2478
|
+
});
|
|
2479
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2480
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
2481
|
+
});
|
|
2482
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2483
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
2484
|
+
});
|
|
2485
|
+
} else if (shiftseldecoder().current === "negdown") {
|
|
2486
|
+
console.log("moving the words to show only negdown");
|
|
2487
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2488
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
2489
|
+
});
|
|
2490
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2491
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
2492
|
+
});
|
|
2493
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2494
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2495
|
+
});
|
|
2496
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2497
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2498
|
+
});
|
|
2499
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2500
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2501
|
+
});
|
|
2502
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2503
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2504
|
+
});
|
|
2505
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2506
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2507
|
+
});
|
|
2508
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2509
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2510
|
+
});
|
|
2511
|
+
} else if (shiftseldecoder().current === "posdown") {
|
|
2512
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2513
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2514
|
+
});
|
|
2515
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2516
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2517
|
+
});
|
|
2518
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2519
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2520
|
+
});
|
|
2521
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2522
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2523
|
+
});
|
|
2524
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2525
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2526
|
+
});
|
|
2527
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2528
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2529
|
+
});
|
|
2530
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2531
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
2532
|
+
});
|
|
2533
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2534
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
2535
|
+
});
|
|
2536
|
+
} else if (shiftseldecoder().current === "negup") {
|
|
2537
|
+
axes.selectAll("rect.shiftrect.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2538
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2539
|
+
});
|
|
2540
|
+
axes.selectAll("text.shifttext.zero").transition().duration(1000).attr("transform", function(d, i) {
|
|
2541
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2542
|
+
});
|
|
2543
|
+
axes.selectAll("rect.shiftrect.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2544
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2545
|
+
});
|
|
2546
|
+
axes.selectAll("text.shifttext.one").transition().duration(1000).attr("transform", function(d, i) {
|
|
2547
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2548
|
+
});
|
|
2549
|
+
axes.selectAll("rect.shiftrect.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2550
|
+
return "translate(" + ((d > 0) ? figcenter : x(d)) + "," + y(i + 1) + ")";
|
|
2551
|
+
});
|
|
2552
|
+
axes.selectAll("text.shifttext.two").transition().duration(1000).attr("transform", function(d, i) {
|
|
2553
|
+
return "translate(" + ((d > 0) ? x(d) + 2 : x(d) - 2) + "," + (y(i + 1) + iBarH) + ")";
|
|
2554
|
+
});
|
|
2555
|
+
axes.selectAll("rect.shiftrect.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2556
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + y(i + 1) + ")";
|
|
2557
|
+
});
|
|
2558
|
+
axes.selectAll("text.shifttext.three").transition().duration(1000).attr("transform", function(d, i) {
|
|
2559
|
+
return "translate(" + ((d > 0) ? 500 : -500) + "," + (y(i + 1) + iBarH) + ")";
|
|
2560
|
+
});
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
maxShiftSum = Math.max(Math.abs(sumTypes[1]), Math.abs(sumTypes[2]), sumTypes[0], sumTypes[3]);
|
|
2564
|
+
|
|
2565
|
+
topScale.domain([-maxShiftSum, maxShiftSum]);
|
|
2566
|
+
|
|
2567
|
+
// define the RHS summary bars so I can add if needed
|
|
2568
|
+
// var summaryArray = [sumTypes[3],sumTypes[0],sumTypes[3]+sumTypes[1],d3.sum(sumTypes)];
|
|
2569
|
+
summaryArray = [sumTypes[3], sumTypes[0], d3.sum(sumTypes)];
|
|
2570
|
+
|
|
2571
|
+
var newRtopbars = axes.selectAll(".sumrectR")
|
|
2572
|
+
.data(summaryArray);
|
|
2573
|
+
|
|
2574
|
+
newRtopbars.transition().duration(1500)
|
|
2575
|
+
.attr("x", function(d, i) {
|
|
2576
|
+
if (d > 0) {
|
|
2577
|
+
return figcenter;
|
|
2578
|
+
} else {
|
|
2579
|
+
return topScale(d)
|
|
2580
|
+
}
|
|
2581
|
+
})
|
|
2582
|
+
.attr("width", function(d, i) {
|
|
2583
|
+
if (d > 0) {
|
|
2584
|
+
return topScale(d) - figcenter;
|
|
2585
|
+
} else {
|
|
2586
|
+
return figcenter - topScale(d);
|
|
2587
|
+
}
|
|
2588
|
+
});
|
|
2589
|
+
|
|
2590
|
+
var newRtoptext = axes.selectAll(".sumtextR")
|
|
2591
|
+
.data([sumTypes[3], sumTypes[0], d3.sum(sumTypes)]);
|
|
2592
|
+
|
|
2593
|
+
newRtoptext.transition().duration(1500).attr("class", "sumtextR")
|
|
2594
|
+
.style("text-anchor", function(d, i) {
|
|
2595
|
+
if (d > 0) {
|
|
2596
|
+
return "start";
|
|
2597
|
+
} else {
|
|
2598
|
+
return "end";
|
|
2599
|
+
}
|
|
2600
|
+
})
|
|
2601
|
+
.attr("x", function(d, i) {
|
|
2602
|
+
return topScale(d) + 5 * d / Math.abs(d);
|
|
2603
|
+
});
|
|
2604
|
+
|
|
2605
|
+
summaryArray = [sumTypes[1], sumTypes[2], sumTypes[0] + sumTypes[2]];
|
|
2606
|
+
|
|
2607
|
+
var newLtopbars = axes.selectAll(".sumrectL")
|
|
2608
|
+
.data(summaryArray);
|
|
2609
|
+
|
|
2610
|
+
newLtopbars.transition().duration(1500).attr("fill", function(d, i) {
|
|
2611
|
+
if (i == 0) {
|
|
2612
|
+
return "#FFFFB3";
|
|
2613
|
+
} else if (i == 1) {
|
|
2614
|
+
return "#4C4CFF";
|
|
2615
|
+
} else {
|
|
2616
|
+
// choose color based on whether increasing/decreasing wins
|
|
2617
|
+
if (d > 0) {
|
|
2618
|
+
return "#B3B3FF";
|
|
2619
|
+
} else {
|
|
2620
|
+
return "#4C4CFF";
|
|
2621
|
+
}
|
|
2622
|
+
}
|
|
2623
|
+
})
|
|
2624
|
+
.attr("x", function(d, i) {
|
|
2625
|
+
if (i < 2) {
|
|
2626
|
+
return topScale(d);
|
|
2627
|
+
} else {
|
|
2628
|
+
// place the sum of negatives bar
|
|
2629
|
+
// if they are not opposing
|
|
2630
|
+
if ((sumTypes[3] + sumTypes[1]) * (sumTypes[0] + sumTypes[2]) > 0) {
|
|
2631
|
+
// if positive, place at end of other bar
|
|
2632
|
+
if (d > 0) {
|
|
2633
|
+
return topScale((sumTypes[3] + sumTypes[1]));
|
|
2634
|
+
}
|
|
2635
|
+
// if negative, place at left of other bar, minus length (+topScale(d))
|
|
2636
|
+
else {
|
|
2637
|
+
return topScale(d) - (figcenter - topScale((sumTypes[3] + sumTypes[1])));
|
|
2638
|
+
}
|
|
2639
|
+
} else {
|
|
2640
|
+
if (d > 0) {
|
|
2641
|
+
return figcenter
|
|
2642
|
+
} else {
|
|
2643
|
+
return topScale(d)
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
})
|
|
2648
|
+
.attr("width", function(d, i) {
|
|
2649
|
+
if (d > 0) {
|
|
2650
|
+
return topScale(d) - figcenter;
|
|
2651
|
+
} else {
|
|
2652
|
+
return figcenter - topScale(d);
|
|
2653
|
+
}
|
|
2654
|
+
});
|
|
2655
|
+
|
|
2656
|
+
var newLtoptext = axes.selectAll(".sumtextL")
|
|
2657
|
+
.data([sumTypes[1], sumTypes[2]]);
|
|
2658
|
+
|
|
2659
|
+
newLtoptext.transition().duration(1500).attr("x", function(d, i) {
|
|
2660
|
+
return topScale(d) - 5;
|
|
2661
|
+
});
|
|
2662
|
+
|
|
2663
|
+
return that;
|
|
2664
|
+
}; // hedotools.shifter.replot
|
|
2665
|
+
|
|
2666
|
+
function translateButton() {
|
|
2667
|
+
console.log("adding the translate button");
|
|
2668
|
+
var translateGroup = canvas.append("g")
|
|
2669
|
+
.attr("class", "translatebutton")
|
|
2670
|
+
.attr("transform", "translate(" + (4) + "," + (136 + toptextheight) + ") rotate(-90)");
|
|
2671
|
+
|
|
2672
|
+
translateGroup.append("rect")
|
|
2673
|
+
.attr("x", 0)
|
|
2674
|
+
.attr("y", 0)
|
|
2675
|
+
.attr("rx", 3)
|
|
2676
|
+
.attr("ry", 3)
|
|
2677
|
+
.attr("width", 75)
|
|
2678
|
+
.attr("height", 17)
|
|
2679
|
+
.attr("fill", "#F0F0F0") //http://www.w3schools.com/html/html_colors.asp
|
|
2680
|
+
.styles({
|
|
2681
|
+
"stroke-width": "0.5",
|
|
2682
|
+
"stroke": "rgb(0,0,0)"
|
|
2683
|
+
});
|
|
2684
|
+
|
|
2685
|
+
translateGroup.append("text")
|
|
2686
|
+
.text("Translate All")
|
|
2687
|
+
.attr("x", 6)
|
|
2688
|
+
.attr("y", 13)
|
|
2689
|
+
.attr("font-size", "11.0px")
|
|
2690
|
+
|
|
2691
|
+
translateGroup.append("rect")
|
|
2692
|
+
.attr("x", 0)
|
|
2693
|
+
.attr("y", 0)
|
|
2694
|
+
.attr("rx", 3)
|
|
2695
|
+
.attr("ry", 3)
|
|
2696
|
+
.attr("width", 75)
|
|
2697
|
+
.attr("height", 18)
|
|
2698
|
+
.attr("fill", "white") //http://www.w3schools.com/html/html_colors.asp
|
|
2699
|
+
.styles({
|
|
2700
|
+
"opacity": "0.0"
|
|
2701
|
+
})
|
|
2702
|
+
.on("click", function() {
|
|
2703
|
+
for (var i = 0; i < flipVector.length - 1; i++) {
|
|
2704
|
+
flipVector[i] = flipVector[flipVector.length - 1];
|
|
2705
|
+
}
|
|
2706
|
+
flipVector[flipVector.length - 1] = (flipVector[flipVector.length - 1] + 1) % 2;
|
|
2707
|
+
// console.log("clicked translate");
|
|
2708
|
+
|
|
2709
|
+
axes.selectAll("text.shifttext").transition().duration(1000)
|
|
2710
|
+
.text(function(d, i) {
|
|
2711
|
+
// goal is to toggle translation
|
|
2712
|
+
// need translation vector
|
|
2713
|
+
//console.log(flipVector[i]);
|
|
2714
|
+
if (flipVector[i]) {
|
|
2715
|
+
return sortedWordsEn[i];
|
|
2716
|
+
} else {
|
|
2717
|
+
return sortedWords[i];
|
|
2718
|
+
}
|
|
2719
|
+
}); // .text()
|
|
2720
|
+
}); // on("click")
|
|
2721
|
+
}; // translateButton
|
|
2722
|
+
|
|
2723
|
+
var selfShifter = function() {
|
|
2724
|
+
var that = this;
|
|
2725
|
+
/* shift one frequency vectors, against itself
|
|
2726
|
+
|
|
2727
|
+
uses self.refF
|
|
2728
|
+
|
|
2729
|
+
-assume it has been zero-ed for stop words
|
|
2730
|
+
-lens is of full length
|
|
2731
|
+
-words is a list of utf8 strings
|
|
2732
|
+
|
|
2733
|
+
return an object with the sorted quantities for plotting the shift
|
|
2734
|
+
*/
|
|
2735
|
+
|
|
2736
|
+
//normalize frequencies
|
|
2737
|
+
var Nref = 0.0;
|
|
2738
|
+
var lensLength = d3.min([refF.length, words.length, lens.length])
|
|
2739
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2740
|
+
Nref += parseFloat(refF[i]);
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
// refute refarison happiness
|
|
2744
|
+
refH = 0.0;
|
|
2745
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2746
|
+
refH += refF[i] * parseFloat(lens[i]);
|
|
2747
|
+
}
|
|
2748
|
+
refH = refH / Nref;
|
|
2749
|
+
compH = 0.000;
|
|
2750
|
+
|
|
2751
|
+
// do the shifting
|
|
2752
|
+
shiftMag = Array(lensLength);
|
|
2753
|
+
shiftType = Array(lensLength);
|
|
2754
|
+
var freqDiff = 0.0;
|
|
2755
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2756
|
+
freqDiff = refF[i] / Nref;
|
|
2757
|
+
shiftMag[i] = (parseFloat(lens[i]) - refH) * freqDiff;
|
|
2758
|
+
// this does just the weighted distribution
|
|
2759
|
+
// (for LabMT, everything is positive)
|
|
2760
|
+
// shiftMag[i] = (parseFloat(lens[i]))*freqDiff;
|
|
2761
|
+
if (freqDiff > 0) {
|
|
2762
|
+
shiftType[i] = 2;
|
|
2763
|
+
} else {
|
|
2764
|
+
shiftType[i] = 0
|
|
2765
|
+
}
|
|
2766
|
+
if (parseFloat(lens[i]) > refH) {
|
|
2767
|
+
shiftType[i] += 1;
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
// +2 for frequency up
|
|
2772
|
+
// +1 for happier
|
|
2773
|
+
// =>
|
|
2774
|
+
// 0 sad, down
|
|
2775
|
+
// 1 happy, down
|
|
2776
|
+
// 2 sad, up
|
|
2777
|
+
// 3 happy, up
|
|
2778
|
+
|
|
2779
|
+
// do the sorting
|
|
2780
|
+
var indices = Array(lensLength);
|
|
2781
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2782
|
+
indices[i] = i;
|
|
2783
|
+
}
|
|
2784
|
+
indices.sort(function(a, b) {
|
|
2785
|
+
return Math.abs(shiftMag[a]) < Math.abs(shiftMag[b]) ? 1 : Math.abs(shiftMag[a]) > Math.abs(shiftMag[b]) ? -1 : 0;
|
|
2786
|
+
});
|
|
2787
|
+
|
|
2788
|
+
sortedMag = Array(numwordstoplot);
|
|
2789
|
+
sortedType = Array(numwordstoplot);
|
|
2790
|
+
sortedWords = Array(numwordstoplot);
|
|
2791
|
+
|
|
2792
|
+
for (var i = 0; i < numwordstoplot; i++) {
|
|
2793
|
+
sortedMag[i] = shiftMag[indices[i]];
|
|
2794
|
+
sortedType[i] = shiftType[indices[i]];
|
|
2795
|
+
sortedWords[i] = words[indices[i]];
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
if (distflag) {
|
|
2799
|
+
// declare some new variables
|
|
2800
|
+
sortedMagFull = Array(lensLength);
|
|
2801
|
+
sortedTypeFull = Array(lensLength);
|
|
2802
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2803
|
+
sortedMagFull[i] = shiftMag[indices[i]];
|
|
2804
|
+
sortedTypeFull[i] = shiftType[indices[i]];
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
// compute the sum of contributions of different types
|
|
2809
|
+
sumTypes = [0.0, 0.0, 0.0, 0.0];
|
|
2810
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2811
|
+
sumTypes[shiftType[i]] += shiftMag[i];
|
|
2812
|
+
}
|
|
2813
|
+
if (translate) {
|
|
2814
|
+
sortedWordsEn = Array(numwordstoplot);
|
|
2815
|
+
for (var i = 0; i < numwordstoplot; i++) {
|
|
2816
|
+
sortedWordsEn[i] = words_en[indices[i]];
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
return that;
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
var dualShifter = function() {
|
|
2824
|
+
var that = this;
|
|
2825
|
+
/* shift two frequency vectors
|
|
2826
|
+
-assume they've been zero-ed for stop words
|
|
2827
|
+
-lens is of full length
|
|
2828
|
+
-words is a list of utf8 strings
|
|
2829
|
+
|
|
2830
|
+
return an object with the sorted quantities for plotting the shift
|
|
2831
|
+
*/
|
|
2832
|
+
|
|
2833
|
+
//normalize frequencies
|
|
2834
|
+
var Nref = 0.0;
|
|
2835
|
+
var Ncomp = 0.0;
|
|
2836
|
+
var lensLength = d3.min([refF.length, compF.length, words.length, lens.length]);
|
|
2837
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2838
|
+
Nref += parseFloat(refF[i]);
|
|
2839
|
+
Ncomp += parseFloat(compF[i]);
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
// for (var i=0; i<refF.length; i++) {
|
|
2843
|
+
// refF[i] = parseFloat(refF[i])/Nref;
|
|
2844
|
+
// compF[i] = parseFloat(compF[i])/Ncomp;
|
|
2845
|
+
// }
|
|
2846
|
+
|
|
2847
|
+
// compute reference happiness
|
|
2848
|
+
refH = 0.0;
|
|
2849
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2850
|
+
refH += refF[i] * parseFloat(lens[i]);
|
|
2851
|
+
}
|
|
2852
|
+
// normalize at the end to minimize floating point errors
|
|
2853
|
+
refH = refH / Nref;
|
|
2854
|
+
// console.log(refH);
|
|
2855
|
+
|
|
2856
|
+
// compute reference variance
|
|
2857
|
+
// var refV = 0.0;
|
|
2858
|
+
// for (var i=0; i<refF.length; i++) {
|
|
2859
|
+
// refV += refF[i]*Math.pow(parseFloat(lens[i])-refH,2);
|
|
2860
|
+
// }
|
|
2861
|
+
// refV = refV/Nref;
|
|
2862
|
+
// // console.log(refV);
|
|
2863
|
+
|
|
2864
|
+
// compute comparison happiness
|
|
2865
|
+
compH = 0.0;
|
|
2866
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2867
|
+
compH += compF[i] * parseFloat(complens[i]);
|
|
2868
|
+
}
|
|
2869
|
+
compH = compH / Ncomp;
|
|
2870
|
+
|
|
2871
|
+
// do the shifting
|
|
2872
|
+
shiftMag = Array(lensLength);
|
|
2873
|
+
shiftType = Array(lensLength);
|
|
2874
|
+
var freqDiff = 0.0;
|
|
2875
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2876
|
+
// shiftMag[i] = (parseFloat(complens[i])-compH)*compF[i]/Ncomp - (parseFloat(lens[i])-refH)*refF[i]/Nref;
|
|
2877
|
+
shiftMag[i] = parseFloat(complens[i]) * compF[i] / Ncomp - parseFloat(lens[i]) * refF[i] / Nref;
|
|
2878
|
+
if (compF[i] / Ncomp > refF[i] / Nref) {
|
|
2879
|
+
shiftType[i] = 2;
|
|
2880
|
+
} else {
|
|
2881
|
+
shiftType[i] = 0
|
|
2882
|
+
}
|
|
2883
|
+
// if (parseFloat(complens[i])-compH > parseFloat(lens[i])-refH) { shiftType[i] += 1;}
|
|
2884
|
+
// this means the word is in the reference, but not comparison
|
|
2885
|
+
if (refF[i] > 0 && compF[i] == 0) {
|
|
2886
|
+
// compare the happiness to ref avg
|
|
2887
|
+
if (parseFloat(lens[i]) > refH) {
|
|
2888
|
+
shiftType[i] += 1;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
// this means the word is in the reference, but not comparison
|
|
2892
|
+
else if (refF[i] == 0 && compF[i] > 0) {
|
|
2893
|
+
// compare the happiness to comp avg
|
|
2894
|
+
if (parseFloat(complens[i]) > compH) {
|
|
2895
|
+
shiftType[i] += 1;
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
// if it's in both, color by the difference
|
|
2899
|
+
else {
|
|
2900
|
+
if (parseFloat(complens[i]) > parseFloat(lens[i])) {
|
|
2901
|
+
shiftType[i] += 1;
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
// +2 for frequency up
|
|
2907
|
+
// +1 for happier
|
|
2908
|
+
// =>
|
|
2909
|
+
// 0 sad, down
|
|
2910
|
+
// 1 happy, down
|
|
2911
|
+
// 2 sad, up
|
|
2912
|
+
// 3 happy, up
|
|
2913
|
+
|
|
2914
|
+
// do the sorting
|
|
2915
|
+
var indices = Array(lensLength);
|
|
2916
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2917
|
+
indices[i] = i;
|
|
2918
|
+
}
|
|
2919
|
+
indices.sort(function(a, b) {
|
|
2920
|
+
return Math.abs(shiftMag[a]) < Math.abs(shiftMag[b]) ? 1 : Math.abs(shiftMag[a]) > Math.abs(shiftMag[b]) ? -1 : 0;
|
|
2921
|
+
});
|
|
2922
|
+
|
|
2923
|
+
sortedMag = Array(numwordstoplot);
|
|
2924
|
+
sortedType = Array(numwordstoplot);
|
|
2925
|
+
sortedWords = Array(numwordstoplot);
|
|
2926
|
+
|
|
2927
|
+
for (var i = 0; i < numwordstoplot; i++) {
|
|
2928
|
+
sortedMag[i] = shiftMag[indices[i]];
|
|
2929
|
+
sortedType[i] = shiftType[indices[i]]
|
|
2930
|
+
var tmpword = words[indices[i]];
|
|
2931
|
+
// add 1 to maxChars, because I'll add the ellipsis
|
|
2932
|
+
if (tmpword.length > maxChars + 2) {
|
|
2933
|
+
var shorterword = tmpword.slice(0, maxChars);
|
|
2934
|
+
// check that the last char isn't a space (if it is, delete it)
|
|
2935
|
+
if (shorterword[shorterword.length - 1] === " ") {
|
|
2936
|
+
sortedWords[i] = shorterword.slice(0, shorterword.length - 1) + "\u2026";
|
|
2937
|
+
} else {
|
|
2938
|
+
sortedWords[i] = shorterword + "\u2026";
|
|
2939
|
+
}
|
|
2940
|
+
} else {
|
|
2941
|
+
sortedWords[i] = tmpword;
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
if (distflag) {
|
|
2946
|
+
// declare some new variables
|
|
2947
|
+
sortedMagFull = Array(lensLength);
|
|
2948
|
+
sortedTypeFull = Array(lensLength);
|
|
2949
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2950
|
+
sortedMagFull[i] = shiftMag[indices[i]];
|
|
2951
|
+
sortedTypeFull[i] = shiftType[indices[i]];
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
// compute the sum of contributions of different types
|
|
2956
|
+
sumTypes = [0.0, 0.0, 0.0, 0.0];
|
|
2957
|
+
for (var i = 0; i < lensLength; i++) {
|
|
2958
|
+
sumTypes[shiftType[i]] += shiftMag[i];
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
// allow chaining here too
|
|
2962
|
+
return that;
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
var word_paragraph = function(i) {
|
|
2966
|
+
var this_type = sortedType[i];
|
|
2967
|
+
return "The word \"" +
|
|
2968
|
+
(sortedWordsRaw[i]) +
|
|
2969
|
+
"\", shown as \"" +
|
|
2970
|
+
(sortedWords[i]) +
|
|
2971
|
+
"\", is a " +
|
|
2972
|
+
(((this_type == 1) || (this_type == 3)) ? "more happy word (+)" : "less happy word (-)") +
|
|
2973
|
+
" than the reference average, and was used " +
|
|
2974
|
+
((this_type > 1) ? "more frequently (\u2191)" : "less frequently (\u2193)") +
|
|
2975
|
+
" in the comparion, bringing the comparison happiness " +
|
|
2976
|
+
(((this_type == 0) || (this_type == 2)) ? "up" : "down") +
|
|
2977
|
+
" by " +
|
|
2978
|
+
(Math.abs(sortedMag[i] / (Math.abs(refH - compH))).toFixed(2)) +
|
|
2979
|
+
"%.";
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
var word_list = function(i) {
|
|
2983
|
+
var this_type = sortedType[i];
|
|
2984
|
+
var sign = ((this_type == 1) || (this_type == 3)) ? "+" : "-";
|
|
2985
|
+
var morelesshappy = ((this_type == 1) || (this_type == 3)) ? "more" : "less";;
|
|
2986
|
+
var frequency = (this_type > 1) ? "\u2191" : "\u2193";
|
|
2987
|
+
var morelessfreq = (this_type > 1) ? "more" : "less";
|
|
2988
|
+
var updown = (sortedMag[i] > 0) ? "up" : "down";
|
|
2989
|
+
var risefall = (sortedMag[i] > 0) ? "rise" : "fall";
|
|
2990
|
+
var leftright = (sortedMag[i] > 0) ? "right" : "left";
|
|
2991
|
+
var index = my_shifter.get_word_index(sortedWordsRaw[i]);
|
|
2992
|
+
return "The word \"" +
|
|
2993
|
+
(sortedWordsRaw[i]) +
|
|
2994
|
+
"\" is shown as \"" +
|
|
2995
|
+
(sortedWords[i]) +
|
|
2996
|
+
"\". Let's break that down: <br>" +
|
|
2997
|
+
"<ul>" +
|
|
2998
|
+
// "<li>The "+sign+" means "+sortedWordsRaw[i]+" is a "+morelesshappy+" happy word ($h_{\\textrm{avg}} {("+sortedWordsRaw[i]+")}=$"+lens[index].toFixed(2)+")"+
|
|
2999
|
+
"<li>The " + sign + " means " + sortedWordsRaw[i] + " is a " + morelesshappy + " happy word" +
|
|
3000
|
+
" than the reference average ($h_{\\textrm{avg}} {(\\textrm{" + sortedWordsRaw[i] + "})}=" + lens[index].toFixed(2) + "$ and $h^{\\textrm{(ref)}}_{\\textrm{avg}}=" + refH.toFixed(2) + "$).</li><li>The " +
|
|
3001
|
+
((this_type > 1) ? "\u2191 means used more" : "\u2193 means used less") +
|
|
3002
|
+
" frequently in the comparison text than reference text (" + commaSeparateNumber(compF[index]) + " times to " + commaSeparateNumber(refF[index]) + " times, such that " +
|
|
3003
|
+
"$p_\\textrm{" + sortedWordsRaw[i] + "}^{\\textrm{(comp)}} = " + (compF[index] / d3.sum(compF)).toFixed(3) + "$ and " + "$p_\\textrm{" + sortedWordsRaw[i] + "}^{\\textrm{(ref)}}=" + (refF[index] / d3.sum(refF)).toFixed(3) + "$" +
|
|
3004
|
+
").</li><li>Together" +
|
|
3005
|
+
// ((this_type > 1) ? " (more" : " (less")+
|
|
3006
|
+
// ", "+
|
|
3007
|
+
// (((this_type == 1) || (this_type == 3)) ? "positive) " : "negative) ")+
|
|
3008
|
+
" this brings the comparison happiness <strong>" +
|
|
3009
|
+
((sortedMag[i] > 0) ? "up" : "down") +
|
|
3010
|
+
"</strong> by " +
|
|
3011
|
+
(Math.abs(sortedMag[i])).toFixed(3) +
|
|
3012
|
+
", or " +
|
|
3013
|
+
(Math.abs(sortedMag[i] / (refH - compH)).toFixed(2)) +
|
|
3014
|
+
"%. We can see this as the individual term in the shift equations' sum: " +
|
|
3015
|
+
' $$\\underbrace{' +
|
|
3016
|
+
' \\left[' +
|
|
3017
|
+
' h_{\\textrm{avg}} {(\\textrm{' + sortedWordsRaw[i] + '})} – h^{\\textrm{(ref)}}_{\\textrm{avg}}' +
|
|
3018
|
+
' \\right]' +
|
|
3019
|
+
' }_{' + sign + '}' +
|
|
3020
|
+
' \\underbrace{' +
|
|
3021
|
+
' \\left[' +
|
|
3022
|
+
' p_\\textrm{' + sortedWordsRaw[i] + '}^{\\textrm{(comp)}} – p_\\textrm{' + sortedWordsRaw[i] + '}^{\\textrm{(ref)}}' +
|
|
3023
|
+
' \\right]' +
|
|
3024
|
+
' }_{\\' + updown + 'arrow}.$$' +
|
|
3025
|
+
"</li></ul>" +
|
|
3026
|
+
(((this_type == 1) || (this_type == 3)) ? "Positive, " : "Negative, ") +
|
|
3027
|
+
((this_type > 1) ? " more frequent (" : " less frequent (") +
|
|
3028
|
+
sign + frequency +
|
|
3029
|
+
") words " +
|
|
3030
|
+
" will always be on the " +
|
|
3031
|
+
leftright +
|
|
3032
|
+
" contributing to a " +
|
|
3033
|
+
risefall +
|
|
3034
|
+
" in happiness.";
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
var add_help_button = function() {
|
|
3038
|
+
// this requires bootstrap for stying
|
|
3039
|
+
// it requires fontawesome for the icon
|
|
3040
|
+
// requires bootstrap, bootstrap-tour for the tour
|
|
3041
|
+
// and it requires mathjax for the equations
|
|
3042
|
+
figure.append("a")
|
|
3043
|
+
.attrs({
|
|
3044
|
+
"class": "btn btn-large btn-default"
|
|
3045
|
+
})
|
|
3046
|
+
.styles({
|
|
3047
|
+
"position": "absolute",
|
|
3048
|
+
// this position starts from the padding on the left
|
|
3049
|
+
// so inside a bootstrap col, this is 15px too far left
|
|
3050
|
+
"left": function() {
|
|
3051
|
+
return (fullwidth - 34) + "px";
|
|
3052
|
+
},
|
|
3053
|
+
})
|
|
3054
|
+
.on("click", function() {
|
|
3055
|
+
wordshift_tour();
|
|
3056
|
+
})
|
|
3057
|
+
.append("i")
|
|
3058
|
+
.attrs({
|
|
3059
|
+
"class": "fa fa-question"
|
|
3060
|
+
});
|
|
3061
|
+
|
|
3062
|
+
// <a class="btn btn-large btn-default" style= onclick="wordshift_tour();"><i class="fa fa-question" aria-hidden="true"></i></a>
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
var logo = false;
|
|
3066
|
+
var drawlogo = function() {
|
|
3067
|
+
var that = this;
|
|
3068
|
+
logo = true;
|
|
3069
|
+
var logosize = d3.min([toptextheight - 10, 80]);
|
|
3070
|
+
logowidth = logosize + 40; // add some extra space
|
|
3071
|
+
// not working yet
|
|
3072
|
+
canvas.append("image")
|
|
3073
|
+
.attrs({
|
|
3074
|
+
"x": (boxwidth - logosize - 10),
|
|
3075
|
+
"y": "0",
|
|
3076
|
+
"width": logosize,
|
|
3077
|
+
"height": logosize,
|
|
3078
|
+
"xlink:href": "data:image/png;base64,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",
|
|
3079
|
+
})
|
|
3080
|
+
.on("click", function() {
|
|
3081
|
+
window.open("http://hedonometer.org", "_blank");
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
var wordshift_tour = function() {
|
|
3086
|
+
// function wordshift_tour() {
|
|
3087
|
+
// Instance the tour
|
|
3088
|
+
console.log("launching the tour");
|
|
3089
|
+
var tour = new Tour({
|
|
3090
|
+
steps: [{
|
|
3091
|
+
element: "#shiftsvg",
|
|
3092
|
+
title: "A quick wordshift whats-what",
|
|
3093
|
+
placement: "auto left",
|
|
3094
|
+
onShown: function() {
|
|
3095
|
+
console.log("first element shown");
|
|
3096
|
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
|
|
3097
|
+
},
|
|
3098
|
+
// content: MathJax.HTML.Element("div",null,['We generate the wordshift from this equation: $$h^{\\textrm{(comp)}}_{\\textrm{avg}} – h^{\\textrm{(ref)}}_{\\textrm{avg}} = $$'])
|
|
3099
|
+
// content: "We generate the wordshift from this equation: $$h^{\\textrm{(comp)}}_{\\textrm{avg}} – h^{\\textrm{(ref)}}_{\\textrm{avg}} = $$"
|
|
3100
|
+
|
|
3101
|
+
content: "Let’s say we have two texts which we call ‘reference’, ${T}^\\textrm{(ref)}$, and ‘comparison’, ${T}^\\textrm{(comp)}$. We want to know why the happiness of the comparison text, $h^{\\textrm{(comp)}}_{\\textrm{avg}}$, is higher or lower than that of the reference text $h^{\\textrm{(ref)}}_{\\textrm{avg}}$." +
|
|
3102
|
+
"<br>To do this, we analyze how each word $w$ which contributes to the difference in average happiness between the two texts:" +
|
|
3103
|
+
' $$h^{\\textrm{(comp)}}_{\\textrm{avg}} – h^{\\textrm{(ref)}}_{\\textrm{avg}} = ' +
|
|
3104
|
+
' \\sum_{w \\in L}' +
|
|
3105
|
+
' \\underbrace{' +
|
|
3106
|
+
' \\left[' +
|
|
3107
|
+
' h_{\\textrm{avg}} {(w)} – h^{\\textrm{(ref)}}_{\\textrm{avg}}' +
|
|
3108
|
+
' \\right]' +
|
|
3109
|
+
' }_{+/-}' +
|
|
3110
|
+
' \\underbrace{' +
|
|
3111
|
+
' \\left[' +
|
|
3112
|
+
' p_w^{\\textrm{(comp)}} – p_w^{\\textrm{(ref)}}' +
|
|
3113
|
+
' \\right]' +
|
|
3114
|
+
' }_{\\uparrow/\\downarrow}.$$' +
|
|
3115
|
+
'Next let\'s take a look at how the top three words contribute.'
|
|
3116
|
+
},
|
|
3117
|
+
{
|
|
3118
|
+
element: "#shiftrect0",
|
|
3119
|
+
// title: "Word with the greatest individual contribution",
|
|
3120
|
+
content: word_list(0),
|
|
3121
|
+
placement: "auto left",
|
|
3122
|
+
onShown: function() {
|
|
3123
|
+
console.log("first element shown");
|
|
3124
|
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
|
|
3125
|
+
},
|
|
3126
|
+
},
|
|
3127
|
+
{
|
|
3128
|
+
element: "#shiftrect1",
|
|
3129
|
+
// title: "Second word",
|
|
3130
|
+
content: word_list(1),
|
|
3131
|
+
placement: "auto left",
|
|
3132
|
+
onShown: function() {
|
|
3133
|
+
console.log("first element shown");
|
|
3134
|
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
|
|
3135
|
+
},
|
|
3136
|
+
},
|
|
3137
|
+
{
|
|
3138
|
+
element: "#shiftrect2",
|
|
3139
|
+
// title: "Third word",
|
|
3140
|
+
content: word_list(2),
|
|
3141
|
+
placement: "auto left",
|
|
3142
|
+
onShown: function() {
|
|
3143
|
+
console.log("first element shown");
|
|
3144
|
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
|
|
3145
|
+
},
|
|
3146
|
+
},
|
|
3147
|
+
{
|
|
3148
|
+
element: "#sumTextR0",
|
|
3149
|
+
// title: "Third word",
|
|
3150
|
+
content: "At the top, we see the relative contributions from each of the four words types, and the total (the grey bar). This particular bar, $\\sum +\\uparrow$, shows the relative contribution to the shift in happiness from positive words that increased in frequency. <br><br>Try clicking this bar to see only those word types. To reset the view, click the grey $\\sum$ bar.<br><br>And that's all for now, we hope this quick what's-what was helpful!",
|
|
3151
|
+
placement: "auto left",
|
|
3152
|
+
onShown: function() {
|
|
3153
|
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
|
|
3154
|
+
},
|
|
3155
|
+
}
|
|
3156
|
+
]
|
|
3157
|
+
});
|
|
3158
|
+
|
|
3159
|
+
// Initialize the tour
|
|
3160
|
+
tour.init();
|
|
3161
|
+
|
|
3162
|
+
// Start the tour
|
|
3163
|
+
// force it, since it's an option
|
|
3164
|
+
tour.restart();
|
|
3165
|
+
tour.start(true);
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
var cloud = function() {
|
|
3169
|
+
var that = this;
|
|
3170
|
+
|
|
3171
|
+
if (viz_type_decoder().cached === "table") {
|
|
3172
|
+
// console.log("removing table stuff");
|
|
3173
|
+
newrank.remove();
|
|
3174
|
+
newfreq.remove();
|
|
3175
|
+
newtype.remove();
|
|
3176
|
+
newmag.remove();
|
|
3177
|
+
header.remove();
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
// push the state the browser URL
|
|
3181
|
+
viz_type.varval("cloud");
|
|
3182
|
+
// console.log("making a cloud");
|
|
3183
|
+
|
|
3184
|
+
// move all the stuff out of the way (table or wordshift)
|
|
3185
|
+
axes.selectAll("rect.shiftrect").transition().duration(1000).attr("x", 1000);
|
|
3186
|
+
axes.selectAll(".sumrectR").transition().duration(2000).attr("x", 1000);
|
|
3187
|
+
axes.selectAll(".sumtextR").transition().duration(2000).attr("x", 1000);
|
|
3188
|
+
axes.selectAll(".sumrectL").transition().duration(2000).attr("x", -1000);
|
|
3189
|
+
axes.selectAll(".sumtextL").transition().duration(2000).attr("x", -1000);
|
|
3190
|
+
// bgrect.style("stroke-width",0.5);
|
|
3191
|
+
bottombgrect.attr("y", 1000);
|
|
3192
|
+
// // need to get rid of the clipping boundary too?
|
|
3193
|
+
// bgrect.remove();
|
|
3194
|
+
xlabel.transition().duration(2000).attr("y", 1000);
|
|
3195
|
+
ylabel.transition().duration(2000).attr("x", -1000);
|
|
3196
|
+
topbgrect.transition().duration(2000).attr("y", -200);
|
|
3197
|
+
sepline.transition().duration(1000).attrs({
|
|
3198
|
+
"y1": -10,
|
|
3199
|
+
"y2": -10,
|
|
3200
|
+
});
|
|
3201
|
+
|
|
3202
|
+
var sizeScale = d3.scaleLinear()
|
|
3203
|
+
.domain([Math.abs(sortedMag[49]), Math.abs(sortedMag[0])])
|
|
3204
|
+
.range([6, 70]);
|
|
3205
|
+
|
|
3206
|
+
// go create a canvas and get the context there
|
|
3207
|
+
// var cloud_canvas = document.createElement("canvas");
|
|
3208
|
+
// cloud_canvas.width = figwidth;
|
|
3209
|
+
// cloud_canvas.height = figheight;
|
|
3210
|
+
// // cloud_canvas.width = 2048;
|
|
3211
|
+
// // cloud_canvas.height = 2048;
|
|
3212
|
+
figure.selectAll("canvas").remove();
|
|
3213
|
+
figure.append("canvas")
|
|
3214
|
+
.attrs({
|
|
3215
|
+
"width": figwidth,
|
|
3216
|
+
"height": figheight,
|
|
3217
|
+
"id": "cloudcanvas"
|
|
3218
|
+
})
|
|
3219
|
+
.styles({
|
|
3220
|
+
"display": "none"
|
|
3221
|
+
});
|
|
3222
|
+
// var cloud_canvas_context = cloud_canvas.getContext("2d");
|
|
3223
|
+
var cloud_canvas_context = document.getElementById("cloudcanvas").getContext("2d");
|
|
3224
|
+
|
|
3225
|
+
figure.append("canvas")
|
|
3226
|
+
.attrs({
|
|
3227
|
+
"width": figwidth,
|
|
3228
|
+
"height": figheight,
|
|
3229
|
+
"id": "cloudcanvas2"
|
|
3230
|
+
})
|
|
3231
|
+
.styles({
|
|
3232
|
+
"display": "none"
|
|
3233
|
+
});
|
|
3234
|
+
|
|
3235
|
+
// var cloud_canvas_context = cloud_canvas.getContext("2d");
|
|
3236
|
+
var cloud_canvas_context_demo = document.getElementById("cloudcanvas2").getContext("2d");
|
|
3237
|
+
|
|
3238
|
+
cloud_canvas_context.textAlign = "center";
|
|
3239
|
+
// cloud_canvas_context.textBaseline = "bottom";
|
|
3240
|
+
cloud_canvas_context.fillStyle = "red";
|
|
3241
|
+
cloud_canvas_context.strokeStyle = "red";
|
|
3242
|
+
cloud_canvas_context.textAlign = "center";
|
|
3243
|
+
cloud_canvas_context.save();
|
|
3244
|
+
|
|
3245
|
+
var nbins = 1;
|
|
3246
|
+
|
|
3247
|
+
// keep track of everything in this data structure
|
|
3248
|
+
var data = sortedWordsRaw.map(function(d, i) {
|
|
3249
|
+
a = {};
|
|
3250
|
+
// text
|
|
3251
|
+
a.text = d;
|
|
3252
|
+
// random rotation
|
|
3253
|
+
a.rotate = Math.round((Math.random() * nbins) - nbins / 2) * 90;
|
|
3254
|
+
// a.rotate = 0;
|
|
3255
|
+
// scale the size (see scale above)
|
|
3256
|
+
a.size = sizeScale(Math.abs(sortedMag[i]));
|
|
3257
|
+
// set the font style using a single string
|
|
3258
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/font
|
|
3259
|
+
a.fontString = a.size + "px " + fontString;
|
|
3260
|
+
// don't let them touch
|
|
3261
|
+
a.padding = 1;
|
|
3262
|
+
// initially space them along the horizontal line
|
|
3263
|
+
// width half of the width
|
|
3264
|
+
a.x = figcenter + (Math.random() - .5) * figwidth / 2;
|
|
3265
|
+
a.y = figheight / 2;
|
|
3266
|
+
return a;
|
|
3267
|
+
});
|
|
3268
|
+
|
|
3269
|
+
var num_to_cloud = 199;
|
|
3270
|
+
|
|
3271
|
+
var size = [figwidth, figheight];
|
|
3272
|
+
var bounds = null;
|
|
3273
|
+
var board = [];
|
|
3274
|
+
var i = -1;
|
|
3275
|
+
while (i++ < num_to_cloud) {
|
|
3276
|
+
var d = data[i];
|
|
3277
|
+
// go and generate the image data
|
|
3278
|
+
// it saves on d
|
|
3279
|
+
|
|
3280
|
+
cloudSpriteSimple(cloud_canvas_context_demo, d, size);
|
|
3281
|
+
|
|
3282
|
+
var cloud_canvas_monochrome = monochrome(cloud_canvas_context.getImageData(0, 0, size[0], size[1]).data);
|
|
3283
|
+
// this will place it (updating x and y)
|
|
3284
|
+
var success = place(board, d, cloud_canvas_monochrome);
|
|
3285
|
+
// reset the bounds
|
|
3286
|
+
// if (bounds) cloudBounds(bounds, d);
|
|
3287
|
+
// else bounds = [{x: d.x + d.x0, y: d.y + d.y0}, {x: d.x + d.x1, y: d.y + d.y1}];
|
|
3288
|
+
// translate such that the rotation actually is centered
|
|
3289
|
+
// put it back to having all of the words
|
|
3290
|
+
cloud_canvas_context.setTransform(1, 0, 0, 1, 0, 0);
|
|
3291
|
+
cloud_canvas_context.save();
|
|
3292
|
+
cloud_canvas_context.font = d.fontString;
|
|
3293
|
+
cloud_canvas_context.lineWidth = 2 * d.padding;
|
|
3294
|
+
cloud_canvas_context.translate(d.x, d.y);
|
|
3295
|
+
cloud_canvas_context.rotate(d.rotate * cloudRadians);
|
|
3296
|
+
// put it in the center (with the translation)
|
|
3297
|
+
cloud_canvas_context.fillText(d.text, 0, 0);
|
|
3298
|
+
cloud_canvas_context.strokeText(d.text, 0, 0);
|
|
3299
|
+
cloud_canvas_context.restore();
|
|
3300
|
+
// console.log(d);
|
|
3301
|
+
}
|
|
3302
|
+
|
|
3303
|
+
// check that the board works
|
|
3304
|
+
// console.log(board);
|
|
3305
|
+
// axes.append("rect")
|
|
3306
|
+
// .attrs({"x": board[0].x0,
|
|
3307
|
+
// "y": board[0].y0,
|
|
3308
|
+
// "width": board[0].w,
|
|
3309
|
+
// "height": board[0].h,})
|
|
3310
|
+
// .styles({"stroke-width": 2,
|
|
3311
|
+
// "stroke": "black",
|
|
3312
|
+
// "fill": "white",
|
|
3313
|
+
// "fill-opacity": "0.0",
|
|
3314
|
+
// });
|
|
3315
|
+
|
|
3316
|
+
// num_to_cloud += 30;
|
|
3317
|
+
var newwords = axes.selectAll("text.shifttext").data(data)
|
|
3318
|
+
.filter(function(d, i) {
|
|
3319
|
+
if (i < num_to_cloud + 1) {
|
|
3320
|
+
return 1;
|
|
3321
|
+
}
|
|
3322
|
+
});
|
|
3323
|
+
|
|
3324
|
+
newwords.text(function(d, i) {
|
|
3325
|
+
return d.text;
|
|
3326
|
+
})
|
|
3327
|
+
.transition().duration(1000)
|
|
3328
|
+
.delay(function(d, i) {
|
|
3329
|
+
return i * 10;
|
|
3330
|
+
})
|
|
3331
|
+
// .style("font-size", function(d,i) { return sizeScale(Math.abs(sortedMag[i])); })
|
|
3332
|
+
// .attr("x",function(d,i) { return Math.random()*100+figcenter; })
|
|
3333
|
+
// .attr("y",function(d,i) { return Math.random()*100+figheight/2; });
|
|
3334
|
+
.attr("placed", function(d, i) {
|
|
3335
|
+
return d.placed;
|
|
3336
|
+
})
|
|
3337
|
+
// .attr("x", function(d,i) { return d.x; })
|
|
3338
|
+
// .attr("y", function(d,i) { return d.y; })
|
|
3339
|
+
.attr("x", function(d, i) {
|
|
3340
|
+
return 0;
|
|
3341
|
+
})
|
|
3342
|
+
.attr("y", function(d, i) {
|
|
3343
|
+
return 0;
|
|
3344
|
+
})
|
|
3345
|
+
.style("text-anchor", "middle")
|
|
3346
|
+
// .style("font-size", function(d) { return d.size + "px"; })
|
|
3347
|
+
// .style("font-family", "\"Impact\", serif")
|
|
3348
|
+
// .style("font", function(d,i) { return d.size + "px " + d.font + ", " + d.style; })
|
|
3349
|
+
.style("font", function(d, i) {
|
|
3350
|
+
return d.fontString;
|
|
3351
|
+
})
|
|
3352
|
+
.attr("transform", function(d, i) {
|
|
3353
|
+
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
|
|
3354
|
+
// return "rotate(" + d.rotate + ")";
|
|
3355
|
+
});
|
|
3356
|
+
|
|
3357
|
+
function place(board, tag, my_monochrome) {
|
|
3358
|
+
// size of the whole figure
|
|
3359
|
+
var perimeter = [{
|
|
3360
|
+
x: 0,
|
|
3361
|
+
y: 0
|
|
3362
|
+
}, {
|
|
3363
|
+
x: size[0],
|
|
3364
|
+
y: size[1]
|
|
3365
|
+
}];
|
|
3366
|
+
// initial position
|
|
3367
|
+
var startX = tag.x;
|
|
3368
|
+
var startY = tag.y;
|
|
3369
|
+
// diagonal length of the board
|
|
3370
|
+
var maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]);
|
|
3371
|
+
// spiral outward!
|
|
3372
|
+
var e = size[0] / size[1];
|
|
3373
|
+
var archimedeanSpiral = function(t) {
|
|
3374
|
+
return [e * t * Math.cos(t), t * Math.sin(t)];
|
|
3375
|
+
};
|
|
3376
|
+
// randomly choose a direction to spin
|
|
3377
|
+
var dt = Math.random() < .5 ? 1 : -1;
|
|
3378
|
+
// start on the other side of 0, with a small timestep
|
|
3379
|
+
var delta = 2;
|
|
3380
|
+
dt = dt * delta;
|
|
3381
|
+
var t = -dt;
|
|
3382
|
+
var dxdy;
|
|
3383
|
+
var dx;
|
|
3384
|
+
var dy;
|
|
3385
|
+
|
|
3386
|
+
// march ahead, setting dxdy as the position of our spiral
|
|
3387
|
+
while (dxdy = archimedeanSpiral(t += dt)) {
|
|
3388
|
+
dx = dxdy[0];
|
|
3389
|
+
dy = dxdy[1];
|
|
3390
|
+
|
|
3391
|
+
// make sure we are not outside the radius
|
|
3392
|
+
// if so, kill it
|
|
3393
|
+
if (Math.min(Math.abs(dx), Math.abs(dy)) >= maxDelta) break;
|
|
3394
|
+
|
|
3395
|
+
// update the position
|
|
3396
|
+
tag.x = startX + dx;
|
|
3397
|
+
tag.y = startY + dy;
|
|
3398
|
+
|
|
3399
|
+
// console.log(dxdy);
|
|
3400
|
+
// axes.selectAll("circle").remove();
|
|
3401
|
+
// axes.append("circle")
|
|
3402
|
+
// .attrs({"cx": tag.x, "cy": tag.y, "r": 1})
|
|
3403
|
+
// .styles({"fill": "red",});
|
|
3404
|
+
|
|
3405
|
+
|
|
3406
|
+
// if the word extends past the edge, keep rotating
|
|
3407
|
+
// (it should come back in!)
|
|
3408
|
+
if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 ||
|
|
3409
|
+
tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue;
|
|
3410
|
+
|
|
3411
|
+
// now let's take the image data from the canvas, and compare the placement
|
|
3412
|
+
// of the data from the tag's sprite
|
|
3413
|
+
// not using the board, (which could store the bounding boxes for a smarter search)
|
|
3414
|
+
|
|
3415
|
+
// for the whole canvas
|
|
3416
|
+
// var cloud_canvas_monochrome = monochrome(cloud_canvas_context.getImageData(0, 0, size[0], size[1]).data);
|
|
3417
|
+
// for the just the bounding box of the sprite
|
|
3418
|
+
// could fetch this from the above....
|
|
3419
|
+
// console.log(cloud_canvas_context.getImageData(tag.x+tag.x0, tag.y-tag.y1, 2*tag.x1, tag.y1));
|
|
3420
|
+
var place_rect = {
|
|
3421
|
+
"x0": Math.floor(tag.x) + tag.x0,
|
|
3422
|
+
"y0": Math.floor(tag.y) - tag.y1,
|
|
3423
|
+
"w": 2 * tag.x1,
|
|
3424
|
+
"h": tag.y1,
|
|
3425
|
+
};
|
|
3426
|
+
place_rect.x1 = place_rect.x0 + place_rect.w;
|
|
3427
|
+
place_rect.y1 = place_rect.y0 + place_rect.h;
|
|
3428
|
+
// var cloud_canvas_monochrome = monochrome(cloud_canvas_context.getImageData(
|
|
3429
|
+
// place_rect.x0,place_rect.y0,place_rect.w,place_rect.h
|
|
3430
|
+
// ).data);
|
|
3431
|
+
|
|
3432
|
+
var cloud_canvas_monochrome = indexer2d(my_monochrome,
|
|
3433
|
+
size[0],
|
|
3434
|
+
place_rect.y0,
|
|
3435
|
+
place_rect.y1,
|
|
3436
|
+
place_rect.x0,
|
|
3437
|
+
place_rect.x1);
|
|
3438
|
+
|
|
3439
|
+
// // console.log(cloud_canvas_monochrome);
|
|
3440
|
+
// console.log(cloud_canvas_monochrome.reduce(function(pv, cv) { return pv + cv; }, 0))
|
|
3441
|
+
// // console.log(tag.sprite);
|
|
3442
|
+
// console.log(tag.sprite.reduce(function(pv, cv) { return pv + cv; }, 0));
|
|
3443
|
+
for (var i = 0; i < tag.sprite.length; i++) {
|
|
3444
|
+
// check that they both have data there
|
|
3445
|
+
if (tag.sprite[i] && cloud_canvas_monochrome[i]) {
|
|
3446
|
+
break
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
// index on the canvas data is tag.x
|
|
3450
|
+
if (i === tag.sprite.length) {
|
|
3451
|
+
board.push(place_rect)
|
|
3452
|
+
// console.log(t);
|
|
3453
|
+
return true;
|
|
3454
|
+
}
|
|
3455
|
+
} // while()
|
|
3456
|
+
// console.log(t);
|
|
3457
|
+
return false;
|
|
3458
|
+
} // place()
|
|
3459
|
+
|
|
3460
|
+
return that;
|
|
3461
|
+
} // hedotools.shifter.cloud
|
|
3462
|
+
|
|
3463
|
+
var newrank;
|
|
3464
|
+
var newfreq;
|
|
3465
|
+
var newtype;
|
|
3466
|
+
var newmag;
|
|
3467
|
+
var header;
|
|
3468
|
+
|
|
3469
|
+
var table = function() {
|
|
3470
|
+
var that = this;
|
|
3471
|
+
|
|
3472
|
+
viz_type.varval("table");
|
|
3473
|
+
|
|
3474
|
+
// console.log("making a table");
|
|
3475
|
+
|
|
3476
|
+
var rankwidth = 20;
|
|
3477
|
+
var wordwidth = 70;
|
|
3478
|
+
var typewidth = 25;
|
|
3479
|
+
var freqwidth = 25;
|
|
3480
|
+
var magwidth = 35;
|
|
3481
|
+
var totalwidth = rankwidth + wordwidth + typewidth + freqwidth + magwidth;
|
|
3482
|
+
// console.log("width of all the text stuff "+totalwidth);
|
|
3483
|
+
var barswidth = figwidth - totalwidth;
|
|
3484
|
+
var aligns = ["start", "start", "middle", "middle", "end", "middle"];
|
|
3485
|
+
// console.log("width left "+barswidth);
|
|
3486
|
+
xpadding = 10;
|
|
3487
|
+
var barcenter = totalwidth + barswidth / 2;
|
|
3488
|
+
var width_offsets = [0, rankwidth, rankwidth + wordwidth, rankwidth + wordwidth + typewidth, rankwidth + wordwidth + typewidth + freqwidth + magwidth, barcenter];
|
|
3489
|
+
|
|
3490
|
+
// linear scale function
|
|
3491
|
+
x.domain([-Math.abs(sortedMag[0]), Math.abs(sortedMag[0])])
|
|
3492
|
+
.range([xpadding, barswidth - xpadding]);
|
|
3493
|
+
|
|
3494
|
+
yHeight = 15;
|
|
3495
|
+
|
|
3496
|
+
// linear scale function
|
|
3497
|
+
y.range([figheight + 2, yHeight]);
|
|
3498
|
+
|
|
3499
|
+
// both of these need their y height reset
|
|
3500
|
+
resetButton(false);
|
|
3501
|
+
|
|
3502
|
+
// if (translate) {
|
|
3503
|
+
// translateButton();
|
|
3504
|
+
// }
|
|
3505
|
+
|
|
3506
|
+
var newbars = axes.selectAll("rect.shiftrect").data(sortedMag);
|
|
3507
|
+
var newwords = axes.selectAll("text.shifttext").data(sortedMag);
|
|
3508
|
+
|
|
3509
|
+
newbars.transition().duration(1000)
|
|
3510
|
+
.attrs({
|
|
3511
|
+
"fill": "grey",
|
|
3512
|
+
"class": function(d, i) {
|
|
3513
|
+
return "shiftrect " + intStr0[sortedType[i]];
|
|
3514
|
+
},
|
|
3515
|
+
"transform": function(d, i) {
|
|
3516
|
+
if (d > 0) {
|
|
3517
|
+
return "translate(" + barcenter + "," + (y(i + 1) + 2.5) + ")";
|
|
3518
|
+
} else {
|
|
3519
|
+
return "translate(" + (x(d) + totalwidth) + "," + (y(i + 1) + 2.5) + ")";
|
|
3520
|
+
}
|
|
3521
|
+
},
|
|
3522
|
+
"height": function(d, i) {
|
|
3523
|
+
return iBarH;
|
|
3524
|
+
},
|
|
3525
|
+
"width": function(d, i) {
|
|
3526
|
+
if ((d) > 0) {
|
|
3527
|
+
return x(d) - x(0);
|
|
3528
|
+
} else {
|
|
3529
|
+
return x(0) - x(d);
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
});
|
|
3533
|
+
|
|
3534
|
+
newwords.transition().duration(1000)
|
|
3535
|
+
.attrs({
|
|
3536
|
+
"class": function(d, i) {
|
|
3537
|
+
return "shifttext " + intStr0[sortedType[i]];
|
|
3538
|
+
},
|
|
3539
|
+
"transform": function(d, i) {
|
|
3540
|
+
return "translate(" + rankwidth + "," + (y(i + 1) + iBarH) + ")";
|
|
3541
|
+
},
|
|
3542
|
+
})
|
|
3543
|
+
.styles({
|
|
3544
|
+
"text-anchor": "start",
|
|
3545
|
+
"font-size": wordfontsize
|
|
3546
|
+
})
|
|
3547
|
+
.text(function(d, i) {
|
|
3548
|
+
return sortedWordsRaw[i];
|
|
3549
|
+
});
|
|
3550
|
+
|
|
3551
|
+
// fix these both for the translate button
|
|
3552
|
+
sortedWords = sortedWordsRaw;
|
|
3553
|
+
if (translate) {
|
|
3554
|
+
sortedWordsEn = sortedWordsEnRaw;
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
newrank = axes.selectAll("text.shiftrank").data(sortedMag)
|
|
3558
|
+
.enter()
|
|
3559
|
+
.append("text")
|
|
3560
|
+
.attr("y", function(d, i) {
|
|
3561
|
+
return y(i + 1) + iBarH;
|
|
3562
|
+
})
|
|
3563
|
+
.attr("x", function(d, i) {
|
|
3564
|
+
return 0;
|
|
3565
|
+
})
|
|
3566
|
+
.styles({
|
|
3567
|
+
"text-anchor": "start",
|
|
3568
|
+
"font-size": wordfontsize
|
|
3569
|
+
})
|
|
3570
|
+
.text(function(d, i) {
|
|
3571
|
+
return (i + 1) + ".";
|
|
3572
|
+
});
|
|
3573
|
+
|
|
3574
|
+
newtype = axes.selectAll("text.shifttype").data(sortedMag)
|
|
3575
|
+
.enter()
|
|
3576
|
+
.append("text")
|
|
3577
|
+
.attr("y", function(d, i) {
|
|
3578
|
+
return y(i + 1) + iBarH;
|
|
3579
|
+
})
|
|
3580
|
+
.attr("x", function(d, i) {
|
|
3581
|
+
return rankwidth + wordwidth;
|
|
3582
|
+
})
|
|
3583
|
+
.styles({
|
|
3584
|
+
"text-anchor": "middle",
|
|
3585
|
+
"font-size": wordfontsize
|
|
3586
|
+
})
|
|
3587
|
+
.text(function(d, i) {
|
|
3588
|
+
if (sortedType[i] == 0) {
|
|
3589
|
+
return "\u002D";
|
|
3590
|
+
} else if (sortedType[i] == 2) {
|
|
3591
|
+
return "\u002D";
|
|
3592
|
+
} // -
|
|
3593
|
+
else {
|
|
3594
|
+
return "\u002B";
|
|
3595
|
+
} // +
|
|
3596
|
+
});
|
|
3597
|
+
|
|
3598
|
+
newfreq = axes.selectAll("text.shiftfreq").data(sortedMag)
|
|
3599
|
+
.enter()
|
|
3600
|
+
.append("text")
|
|
3601
|
+
.attr("y", function(d, i) {
|
|
3602
|
+
return y(i + 1) + iBarH;
|
|
3603
|
+
})
|
|
3604
|
+
.attr("x", function(d, i) {
|
|
3605
|
+
return rankwidth + wordwidth + typewidth;
|
|
3606
|
+
})
|
|
3607
|
+
.styles({
|
|
3608
|
+
"text-anchor": "middle",
|
|
3609
|
+
"font-size": wordfontsize
|
|
3610
|
+
})
|
|
3611
|
+
.text(function(d, i) {
|
|
3612
|
+
if (sortedType[i] == 0) {
|
|
3613
|
+
return "\u2193";
|
|
3614
|
+
} else if (sortedType[i] == 1) {
|
|
3615
|
+
return "\u2193";
|
|
3616
|
+
} else {
|
|
3617
|
+
return "\u2191";
|
|
3618
|
+
}
|
|
3619
|
+
});
|
|
3620
|
+
|
|
3621
|
+
newmag = axes.selectAll("text.shiftmag").data(sortedMag)
|
|
3622
|
+
.enter()
|
|
3623
|
+
.append("text")
|
|
3624
|
+
.attr("y", function(d, i) {
|
|
3625
|
+
return y(i + 1) + iBarH;
|
|
3626
|
+
})
|
|
3627
|
+
.attr("x", function(d, i) {
|
|
3628
|
+
return rankwidth + wordwidth + typewidth + freqwidth + magwidth;
|
|
3629
|
+
})
|
|
3630
|
+
.styles({
|
|
3631
|
+
"text-anchor": "end",
|
|
3632
|
+
"font-size": wordfontsize
|
|
3633
|
+
})
|
|
3634
|
+
.text(function(d, i) {
|
|
3635
|
+
return (d / (Math.abs(compH - refH)) * 100).toFixed(2) + "%";
|
|
3636
|
+
});
|
|
3637
|
+
|
|
3638
|
+
header = axes.selectAll("text.header")
|
|
3639
|
+
.data(["#", "Word", "\u002B/\u002D", "\u2191/\u2193", "% Cont.", "% Cont."])
|
|
3640
|
+
.enter()
|
|
3641
|
+
.append("text")
|
|
3642
|
+
.attrs({
|
|
3643
|
+
"x": function(d, i) {
|
|
3644
|
+
return width_offsets[i];
|
|
3645
|
+
},
|
|
3646
|
+
"y": function(d, i) {
|
|
3647
|
+
return y(0) + iBarH;
|
|
3648
|
+
},
|
|
3649
|
+
})
|
|
3650
|
+
.styles({
|
|
3651
|
+
"text-anchor": function(d, i) {
|
|
3652
|
+
return aligns[i];
|
|
3653
|
+
},
|
|
3654
|
+
"font-size": function(d, i) {
|
|
3655
|
+
return wordfontsize;
|
|
3656
|
+
},
|
|
3657
|
+
})
|
|
3658
|
+
.text(function(d, i) {
|
|
3659
|
+
return d;
|
|
3660
|
+
})
|
|
3661
|
+
|
|
3662
|
+
axes.selectAll(".sumrectR").transition().duration(2000).attr("x", 1000);
|
|
3663
|
+
axes.selectAll(".sumtextR").transition().duration(2000).attr("x", 1000);
|
|
3664
|
+
axes.selectAll(".sumrectL").transition().duration(2000).attr("x", -1000);
|
|
3665
|
+
axes.selectAll(".sumtextL").transition().duration(2000).attr("x", -1000);
|
|
3666
|
+
bgrect.style("stroke-width", 0);
|
|
3667
|
+
bottombgrect.attr("y", 1000);
|
|
3668
|
+
// // need to get rid of the clipping boundary too?
|
|
3669
|
+
// bgrect.remove();
|
|
3670
|
+
xlabel.transition().duration(2000).attr("y", 1000);
|
|
3671
|
+
ylabel.transition().duration(2000).attr("x", -1000);
|
|
3672
|
+
topbgrect.transition().duration(2000).attr("y", -200);
|
|
3673
|
+
sepline.transition().duration(1000).attrs({
|
|
3674
|
+
"y1": "15",
|
|
3675
|
+
"y2": 15,
|
|
3676
|
+
});
|
|
3677
|
+
|
|
3678
|
+
function zoomed() {
|
|
3679
|
+
// console.log(d3.event);
|
|
3680
|
+
if (d3.event.translate[1] > 0) {
|
|
3681
|
+
zoom.translate([0, 0]).scale(1);
|
|
3682
|
+
}
|
|
3683
|
+
newbars.attr("transform", function(d, i) {
|
|
3684
|
+
return "translate(" + ((d > 0) ? barcenter : x(d) + totalwidth) + "," + (y(i + 1) + 2.5) + ")";
|
|
3685
|
+
});
|
|
3686
|
+
newwords.attr("transform", function(d, i) {
|
|
3687
|
+
return "translate(" + ((d > 0) ? rankwidth : rankwidth) + "," + (y(i + 1) + iBarH) + ")";
|
|
3688
|
+
});
|
|
3689
|
+
|
|
3690
|
+
// newbars.attr("y", function(d,i) { return y(i+1) });
|
|
3691
|
+
// newwords.attr("y", function(d,i) { return y(i+1)+iBarH; } );
|
|
3692
|
+
newrank.attr("y", function(d, i) {
|
|
3693
|
+
return y(i + 1) + iBarH;
|
|
3694
|
+
});
|
|
3695
|
+
newtype.attr("y", function(d, i) {
|
|
3696
|
+
return y(i + 1) + iBarH;
|
|
3697
|
+
});
|
|
3698
|
+
newfreq.attr("y", function(d, i) {
|
|
3699
|
+
return y(i + 1) + iBarH;
|
|
3700
|
+
});
|
|
3701
|
+
newmag.attr("y", function(d, i) {
|
|
3702
|
+
return y(i + 1) + iBarH;
|
|
3703
|
+
});
|
|
3704
|
+
|
|
3705
|
+
}; // zoomed
|
|
3706
|
+
|
|
3707
|
+
// zoom = d3.behavior.zoom()
|
|
3708
|
+
// .y(y) // pass linear scale function
|
|
3709
|
+
// // .translate([10,10])
|
|
3710
|
+
// .scaleExtent([1,1])
|
|
3711
|
+
// .on("zoom",zoomed);
|
|
3712
|
+
|
|
3713
|
+
return that;
|
|
3714
|
+
} // hedotools.shifter.table()
|
|
3715
|
+
|
|
3716
|
+
function resizeshift() {
|
|
3717
|
+
var that = this;
|
|
3718
|
+
|
|
3719
|
+
// don't use this function...
|
|
3720
|
+
// not sure why, but the updates don't always seem to work
|
|
3721
|
+
// (need selections, can't pass variables that are local
|
|
3722
|
+
// in scope)
|
|
3723
|
+
return 1;
|
|
3724
|
+
|
|
3725
|
+
fullwidth = parseInt(figure.style("width"));
|
|
3726
|
+
boxwidth = fullwidth - margin.left - margin.right;
|
|
3727
|
+
figwidth = boxwidth - axeslabelmargin.left - axeslabelmargin.right;
|
|
3728
|
+
figcenter = figwidth / 2;
|
|
3729
|
+
// console.log(figcenter);
|
|
3730
|
+
|
|
3731
|
+
canvas.attr("width", boxwidth);
|
|
3732
|
+
axes.attr("width", figwidth);
|
|
3733
|
+
|
|
3734
|
+
x.range([maxWidth + 10, figwidth - maxWidth - 10]);
|
|
3735
|
+
|
|
3736
|
+
topScale.range([figwidth * .12, figwidth * .88]);
|
|
3737
|
+
|
|
3738
|
+
bgrect.attr("width", figwidth);
|
|
3739
|
+
topbgrect.attr("width", figwidth - 5);
|
|
3740
|
+
bottombgrect.attr("width", figwidth - 5);
|
|
3741
|
+
|
|
3742
|
+
// fix the x axis
|
|
3743
|
+
// canvas.select(".x.axis").call(xAxis);
|
|
3744
|
+
|
|
3745
|
+
// get the x label
|
|
3746
|
+
xlabel.transition().duration(2000).attr("x", (leftOffsetStatic + figwidth / 2))
|
|
3747
|
+
.attr("y", boxheight - 7);
|
|
3748
|
+
ylabel.transition().duration(2000).attr("y", figheight / 2 + 60 + toptextheight)
|
|
3749
|
+
.attr("x", 18)
|
|
3750
|
+
.attr("transform", "rotate(-90.0," + (18) + "," + (figheight / 2 + 60 + toptextheight) + ")");
|
|
3751
|
+
|
|
3752
|
+
// the andy reagan credit
|
|
3753
|
+
// credit.attr("x",width-7);
|
|
3754
|
+
|
|
3755
|
+
// line separating summary
|
|
3756
|
+
sepline.attr("x2", figwidth);
|
|
3757
|
+
|
|
3758
|
+
axes.selectAll(".sumrectR")
|
|
3759
|
+
.attr("x", function(d, i) {
|
|
3760
|
+
if (d > 0) {
|
|
3761
|
+
return figcenter;
|
|
3762
|
+
} else {
|
|
3763
|
+
return topScale(d)
|
|
3764
|
+
}
|
|
3765
|
+
})
|
|
3766
|
+
.attr("width", function(d, i) {
|
|
3767
|
+
if (d > 0) {
|
|
3768
|
+
return topScale(d) - figcenter;
|
|
3769
|
+
} else {
|
|
3770
|
+
return figcenter - topScale(d);
|
|
3771
|
+
}
|
|
3772
|
+
});
|
|
3773
|
+
|
|
3774
|
+
axes.selectAll(".sumtextR")
|
|
3775
|
+
.attr("x", function(d, i) {
|
|
3776
|
+
return topScale(d) + 5 * d / Math.abs(d);
|
|
3777
|
+
});
|
|
3778
|
+
|
|
3779
|
+
axes.selectAll(".sumrectL")
|
|
3780
|
+
.attr("x", function(d, i) {
|
|
3781
|
+
if (i < 2) {
|
|
3782
|
+
return topScale(d);
|
|
3783
|
+
} else {
|
|
3784
|
+
// place the sum of negatives bar
|
|
3785
|
+
// if they are not opposing
|
|
3786
|
+
if ((sumTypes[3] + sumTypes[1]) * (sumTypes[0] + sumTypes[2]) > 0) {
|
|
3787
|
+
// if positive, place at end of other bar
|
|
3788
|
+
if (d > 0) {
|
|
3789
|
+
return topScale((sumTypes[3] + sumTypes[1]));
|
|
3790
|
+
}
|
|
3791
|
+
// if negative, place at left of other bar, minus length (+topScale(d))
|
|
3792
|
+
else {
|
|
3793
|
+
return topScale(d) - (figcenter - topScale((sumTypes[3] + sumTypes[1])));
|
|
3794
|
+
}
|
|
3795
|
+
} else {
|
|
3796
|
+
if (d > 0) {
|
|
3797
|
+
return figcenter
|
|
3798
|
+
} else {
|
|
3799
|
+
return topScale(d)
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
})
|
|
3804
|
+
.attr("width", function(d, i) {
|
|
3805
|
+
if (d > 0) {
|
|
3806
|
+
return topScale(d) - figcenter;
|
|
3807
|
+
} else {
|
|
3808
|
+
return figcenter - topScale(d);
|
|
3809
|
+
}
|
|
3810
|
+
});
|
|
3811
|
+
|
|
3812
|
+
axes.selectAll(".sumtextL")
|
|
3813
|
+
.attr("x", function(d, i) {
|
|
3814
|
+
return topScale(d) - 5;
|
|
3815
|
+
});
|
|
3816
|
+
|
|
3817
|
+
shiftrects
|
|
3818
|
+
.attr("x", function(d, i) {
|
|
3819
|
+
if (d > 0) {
|
|
3820
|
+
return figcenter;
|
|
3821
|
+
} else {
|
|
3822
|
+
return x(d);
|
|
3823
|
+
}
|
|
3824
|
+
})
|
|
3825
|
+
.attr("width", function(d, i) {
|
|
3826
|
+
if ((d) > 0) {
|
|
3827
|
+
return x(d) - x(0);
|
|
3828
|
+
} else {
|
|
3829
|
+
return x(0) - x(d);
|
|
3830
|
+
}
|
|
3831
|
+
});
|
|
3832
|
+
|
|
3833
|
+
// all of the lower shift text
|
|
3834
|
+
shifttext.attr("x", function(d, i) {
|
|
3835
|
+
if (d > 0) {
|
|
3836
|
+
return x(d) + 2;
|
|
3837
|
+
} else {
|
|
3838
|
+
return x(d) - 2;
|
|
3839
|
+
}
|
|
3840
|
+
});
|
|
3841
|
+
|
|
3842
|
+
}
|
|
3843
|
+
|
|
3844
|
+
var opublic = {
|
|
3845
|
+
shift: shift,
|
|
3846
|
+
ignore: ignore,
|
|
3847
|
+
setTextBold: setTextBold,
|
|
3848
|
+
stop: stop,
|
|
3849
|
+
istopper: istopper,
|
|
3850
|
+
shifter: shifter,
|
|
3851
|
+
selfShifter: selfShifter,
|
|
3852
|
+
setfigure: setfigure,
|
|
3853
|
+
getfigure: getfigure,
|
|
3854
|
+
setdata: setdata,
|
|
3855
|
+
plot: plot,
|
|
3856
|
+
add_help_button: add_help_button,
|
|
3857
|
+
show_x_axis: show_x_axis,
|
|
3858
|
+
replot: replot,
|
|
3859
|
+
table: table,
|
|
3860
|
+
cloud: cloud,
|
|
3861
|
+
setText: setText,
|
|
3862
|
+
setWidth: setWidth,
|
|
3863
|
+
setHeight: setHeight,
|
|
3864
|
+
setBgcolor: setBgcolor,
|
|
3865
|
+
splitstring: splitstring,
|
|
3866
|
+
drawlogo: drawlogo,
|
|
3867
|
+
resetbuttontoggle: resetbuttontoggle,
|
|
3868
|
+
plotdist: plotdist,
|
|
3869
|
+
_reset: _reset,
|
|
3870
|
+
_stoprange: _stoprange,
|
|
3871
|
+
_refF: _refF,
|
|
3872
|
+
_compF: _compF,
|
|
3873
|
+
_lens: _lens,
|
|
3874
|
+
_complens: _complens,
|
|
3875
|
+
_words: _words,
|
|
3876
|
+
_words_en: _words_en,
|
|
3877
|
+
// boatload more accessor functions
|
|
3878
|
+
_refH: _refH,
|
|
3879
|
+
_compH: _compH,
|
|
3880
|
+
_xlabel_text: _xlabel_text,
|
|
3881
|
+
_ylabel_text: _ylabel_text,
|
|
3882
|
+
setTextColors: setTextColors,
|
|
3883
|
+
setTopTextSizes: setTopTextSizes,
|
|
3884
|
+
_split_top_strings: _split_top_strings,
|
|
3885
|
+
_shiftMag: _shiftMag,
|
|
3886
|
+
_shiftType: _shiftType,
|
|
3887
|
+
dualShifter: dualShifter,
|
|
3888
|
+
setFontSizes: setFontSizes,
|
|
3889
|
+
_fontString: _fontString,
|
|
3890
|
+
_viz_type_use_URL: _viz_type_use_URL,
|
|
3891
|
+
_my_shift_id: _my_shift_id,
|
|
3892
|
+
_sortedMag: _sortedMag,
|
|
3893
|
+
_sortedType: _sortedType,
|
|
3894
|
+
_sortedWords: _sortedWords,
|
|
3895
|
+
_sortedWordsRaw: _sortedWordsRaw,
|
|
3896
|
+
get_word_index: get_word_index,
|
|
3897
|
+
}
|
|
3898
|
+
return opublic;
|
|
3899
|
+
};
|
|
3900
|
+
|
|
3901
|
+
function cloudSpriteSimple(my_canvas_context, d, size) {
|
|
3902
|
+
if (d.sprite) return;
|
|
3903
|
+
|
|
3904
|
+
my_canvas_context.setTransform(1, 0, 0, 1, 0, 0);
|
|
3905
|
+
my_canvas_context.clearRect(0, 0, size[0], size[1]);
|
|
3906
|
+
my_canvas_context.save()
|
|
3907
|
+
|
|
3908
|
+
// set the initial values
|
|
3909
|
+
var x = 0;
|
|
3910
|
+
var y = 0;
|
|
3911
|
+
var maxh = 0;
|
|
3912
|
+
|
|
3913
|
+
my_canvas_context.font = d.fontString;
|
|
3914
|
+
my_canvas_context.textAlign = "center";
|
|
3915
|
+
my_canvas_context.textBaseline = "bottom";
|
|
3916
|
+
my_canvas_context.fillStyle = "red";
|
|
3917
|
+
my_canvas_context.strokeStyle = "red";
|
|
3918
|
+
my_canvas_context.textAlign = "center";
|
|
3919
|
+
my_canvas_context.lineWidth = 2 * d.padding;
|
|
3920
|
+
|
|
3921
|
+
var w = my_canvas_context.measureText(d.text + "m").width,
|
|
3922
|
+
h = d.size;
|
|
3923
|
+
|
|
3924
|
+
d.x0 = Math.floor(-w / 2);
|
|
3925
|
+
d.x1 = Math.ceil(w / 2);
|
|
3926
|
+
d.y0 = 0;
|
|
3927
|
+
d.y1 = Math.ceil(h);
|
|
3928
|
+
|
|
3929
|
+
// translate such that the rotation actually works
|
|
3930
|
+
my_canvas_context.translate(size[0] / 2, size[1] / 2);
|
|
3931
|
+
|
|
3932
|
+
my_canvas_context.rotate(d.rotate * cloudRadians);
|
|
3933
|
+
// put it in the center (with the translation)
|
|
3934
|
+
my_canvas_context.fillText(d.text, 0, 0);
|
|
3935
|
+
|
|
3936
|
+
// test that we contain the text here
|
|
3937
|
+
// my_canvas_context.strokeRect(d.x0, d.y0-d.y1, w, h);
|
|
3938
|
+
|
|
3939
|
+
my_canvas_context.strokeText(d.text, 0, 0);
|
|
3940
|
+
// var pixels = my_canvas_context.getImageData(0, 0, size[0], size[1]).data;
|
|
3941
|
+
// my_canvas_context.setTransform(1, 0, 0, 1, 0, 0);
|
|
3942
|
+
var pixels = my_canvas_context.getImageData(size[0] / 2 + d.x0, size[1] / 2 + d.y0 - d.y1, 2 * d.x1, d.y1).data;
|
|
3943
|
+
// now let's convert this raw RGBA 0-255 data into a monochrome
|
|
3944
|
+
d.sprite = monochrome(pixels);
|
|
3945
|
+
my_canvas_context.restore();
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3948
|
+
function monochrome(pixels) {
|
|
3949
|
+
var a = Array(pixels.length / 4);
|
|
3950
|
+
for (var i = 0; i < a.length; i++) {
|
|
3951
|
+
// standard luminance scale
|
|
3952
|
+
// var L = (0.2126 * pixels[i*4] + 0.7152 * pixels[i*4+1] + 0.0722 * pixels[i*4+2]);
|
|
3953
|
+
// I set the canvas to only show red
|
|
3954
|
+
var L = pixels[i * 4]
|
|
3955
|
+
// don't multiply by the alpha, just make sure the luminance
|
|
3956
|
+
// is more than .1 percent
|
|
3957
|
+
if (L > (.1 * 256)) {
|
|
3958
|
+
a[i] = 1;
|
|
3959
|
+
} else {
|
|
3960
|
+
a[i] = 0;
|
|
3961
|
+
}
|
|
3962
|
+
// a[i] = (L/256 > 0.1) ? 1 : 0;
|
|
3963
|
+
}
|
|
3964
|
+
return a;
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3967
|
+
function collideRects(a, b) {
|
|
3968
|
+
// a and b are both objects with x0,y0 and x1,y1 upper left and lower right points
|
|
3969
|
+
// not right && not left && not above && not below
|
|
3970
|
+
return b.x0 < a.x1 && b.x1 > a.x0 && b.y1 > a.y0 && b.y0 > a.y1;
|
|
3971
|
+
// note that this may need to more complicated if the object is rotated:
|
|
3972
|
+
// depends on the rotation
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3975
|
+
var cloudRadians = Math.PI / 180;
|
|
3976
|
+
|
|
3977
|
+
function indexer2d(a, w, i, ip, j, jp) {
|
|
3978
|
+
// get a[i:ip,j:jp], where a has width w
|
|
3979
|
+
// get the points ip and jp
|
|
3980
|
+
// i goes down, j goes across
|
|
3981
|
+
|
|
3982
|
+
// initialize result
|
|
3983
|
+
var result = Array((ip - i + 1) * (jp - j + 1));
|
|
3984
|
+
|
|
3985
|
+
// go down
|
|
3986
|
+
for (var ii = i; ii <= ip; ii++) {
|
|
3987
|
+
for (var jj = j; jj <= jp; jj++) {
|
|
3988
|
+
// var flat_index = w*ii+jj;
|
|
3989
|
+
// console.log(flat_index);
|
|
3990
|
+
// console.log(ii*(ip-i+1)+(jj-j))
|
|
3991
|
+
result[(ii - i) * (jp - j + 1) + (jj - j)] = a[w * ii + jj]
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
return result;
|
|
3995
|
+
}
|