-
Notifications
You must be signed in to change notification settings - Fork 0
/
wikiviz.js
264 lines (230 loc) · 9.83 KB
/
wikiviz.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Wiki User Activity Log Analyzer
// Main Visualization Routine
//
// Steps include:
// - Initialize a set of global variables, including for base data structures and SVG components
// - Create the visualization's non-data elements (axes, chart titles, etc.)
// - Construct an initial set of data-driven visuals, first by preparing the data, and then binding this data to graphics
// - Establish user event handlers
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize global variables
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Raw data file name
var dataFileName = "data/wikiactivity.csv"
// Default dates correspond to the sample data we will eventually load
var defaultStartDate = new Date(2013,05,01);
var defaultEndDate = new Date(2014,04,31);
// Set up date chooser controls
// Assume date format of mm-dd-yy
$(function() {
$("#beginDateChooser").datepicker({showAnim: ""});
$("#beginDateChooser").datepicker("setDate", defaultStartDate);
$("#beginDateChooser").datepicker("option", "dateFormat", "mm-dd-yy");
$("#endDateChooser").datepicker({showAnim: ""});
$("#endDateChooser").datepicker("setDate", defaultEndDate);
$("#endDateChooser").datepicker("option", "dateFormat", "mm-dd-yy");
});
// Data structures -- populated below when loading and manipulating data
var departments = [], areas = [], weeks = [], months = [], years = [], deptsOrAreas, subDeptsOrAreas, timeUnits, parseFormat;
var data = [], filteredRawData = [], displayData, startDate, endDate, liveDisplayChooser, userOptions = [], maxUsageOverAllTimeWindows;
// Base SVG components
var mainVisMargin = {
top: 25,
right: 60,
bottom: 100,
left: 60
};
bbMainVis = {
x: mainVisMargin.left,
y: mainVisMargin.top,
w: 960 - mainVisMargin.left - mainVisMargin.right,
h: 570 - mainVisMargin.top - mainVisMargin.bottom
};
var subVisMargin = {
top: 40,
right: 30,
bottom: 40,
left: 30
};
bbSubVis = {
x: subVisMargin.left,
y: subVisMargin.top,
w: 250,
h: 120
};
// Variables for base data structers and other parameters
// Regarding colors, the main visualization cycles through seven of them
// The pie charts use one of the colorbrewer color schemes (loaded via library)
var mainVisColors = d3.scale.ordinal().range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var pieColors = d3.scale.ordinal().domain([1,12]).range(colorbrewer.Set3[12]);
var pie1Layout, pieArc, pie1Group, pie1DataSum, pie2Layout, pieArc, pie2Group, pie2DataSum, subVisOnScreen = false;
var subvis1data, subvis2data, subvisDeptOrArea, subvisTimeUnit, selectBoxData, selectBoxDeptOrArea, selectBoxTimeUnit;
var displayTypeText, subDisplayTypeTextText;
var timeWindows, displayBars;
//The area/department multiple select boxes sort alphabetically by default
var sortStyle = "alphabetical";
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Create SVG components
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main visualization canvas for the stacked bars
canvas = d3.select("#vis").append("svg").attr({
width: bbMainVis.w + mainVisMargin.left + mainVisMargin.right,
height: bbMainVis.h + mainVisMargin.top + mainVisMargin.bottom
}).append("g").attr({
transform: "translate(" + mainVisMargin.left + "," + mainVisMargin.top + ")"
});
// Subvisualization canvases for the drill-down pie charts
subCanvas1 = d3.select("#subvis1").append("svg").attr({
width: bbSubVis.w,
height: bbSubVis.h,
align: "bottom"
}).append("g");
subCanvas2 = d3.select("#subvis2").append("svg").attr({
width: bbSubVis.w,
height: bbSubVis.h,
align: "bottom"
}).append("g");
// Main visualization axes and chart title
var yTickFormat, yDomain, yAxisLabelText, yAxisLabelOffset, xTickFormat, chartTitleText = "";
var xScaleO = d3.scale.ordinal().rangeRoundBands([0, bbMainVis.w], .1);
var xAxisO = d3.svg.axis().scale(xScaleO).orient("bottom");
var yScaleO = d3.scale.linear().rangeRound([bbMainVis.h, 0]);
var yAxisO = d3.svg.axis().scale(yScaleO).orient("left");
var xAxis = canvas.append("g")
.attr("class", "x axis")
.attr("font-family", "sans-serif")
.attr("font-size", "10.5px")
.attr("transform", "translate(" + String(bbMainVis.x) + "," + String(bbMainVis.y + bbMainVis.h) + ")");
var yAxis = canvas.append("g")
.attr("class", "y axis")
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("transform", "translate(" + String(bbMainVis.x) + "," + String(bbMainVis.y) + ")");
var yAxisLabel = yAxis.append("text")
.attr("text-anchor", "end")
.attr("transform", "rotate(-90)");
var chartTitle = yAxis.append("text")
.attr("x", 50)
.attr("y", -25)
.style("font-size", "14px")
.style("font-weight", "bold")
// Tooltip DOM element
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.style("background-color", "white")
.style("border", "3px solid gray")
.style("font-family", "Arial, Helvetica, sans-serif");
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construct initial visuals
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Load the relevant data manipulation and visualization routines
$.when(
loadScript("utilities/userFriendlyDataValue.js"),
loadScript("utilities/pieArcTween.js"),
loadScript("utilities/runFunctionAndShowProgress.js"),
loadScript("dataManipulationRoutines/filterRawData.js"),
loadScript("dataManipulationRoutines/lazyLoadDisplayData.js"),
loadScript("dataManipulationRoutines/catalogUserOptions.js"),
loadScript("dataManipulationRoutines/refreshDeptAreaChoosers.js"),
loadScript("vizRoutines/calcRectSizesAndPositions.js"),
loadScript("vizRoutines/updateXAxis.js"),
loadScript("vizRoutines/updateYAxis.js"),
loadScript("vizRoutines/drawMainViz.js"),
loadScript("vizRoutines/transitionMainViz.js"),
loadScript("vizRoutines/drawSubViz.js"),
loadScript("vizRoutines/transitionSubViz.js"),
loadScript("vizRoutines/subVizText.js"),
loadScript("vizRoutines/clearSubViz.js"),
loadScript("vizRoutines/updateChartTitle.js"),
$.Deferred(function(deferred) { $(deferred.resolve); })
).done(function() {
// Load the raw data
d3.csv(dataFileName, function(csvData) {
data = csvData;
// Populate an initial visualization using the user control defaults
runFunctionAndShowProgress(function(){
filterRawData();
catalogUserOptions();
refreshDeptAreaChoosers();
calcRectSizesAndPositions();
updateXAxis();
updateYAxis();
drawMainViz();
updateChartTitle();
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Establish event handlers
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// User re-filters on departments or areas
d3.selectAll(".promptsRefilter").on("click", function(){runFunctionAndShowProgress(function() {
filterRawData();
catalogUserOptions();
refreshDeptAreaChoosers();
calcRectSizesAndPositions();
updateXAxis();
updateYAxis();
drawMainViz();
updateChartTitle();
});});
// User changes an option that requires a full visualization re-draw
d3.selectAll(".promptsFullUpdate").on("click", function(){runFunctionAndShowProgress(function() {
catalogUserOptions();
calcRectSizesAndPositions();
updateXAxis();
updateYAxis();
drawMainViz();
updateChartTitle();
});});
// User changes an option that requires only visualization transitions
d3.selectAll(".promptsTransition").on("click", function(){runFunctionAndShowProgress(function(){
catalogUserOptions();
calcRectSizesAndPositions();
updateYAxis();
transitionMainViz();
updateChartTitle();
});});
// User cahnges the department / area breakdown
d3.selectAll(".changesBreakdown").on("click", function(){runFunctionAndShowProgress(function() {
catalogUserOptions();
refreshDeptAreaChoosers();
calcRectSizesAndPositions();
updateYAxis();
drawMainViz();
updateChartTitle();
});});
// User sorts departments / areas alphabetically
d3.selectAll(".changesDeptAreaSortAlpha").on("click", function(){runFunctionAndShowProgress(function() {
//Need to transition the whole main vis, because sorting the chooser could have changed the selection
sortStyle = "alphabetical";
catalogUserOptions();
refreshDeptAreaChoosers();
calcRectSizesAndPositions();
updateYAxis();
transitionMainViz();
updateChartTitle();
});});
// User sorts departments / areas according to number of events
d3.selectAll(".changesDeptAreaSortEvents").on("click", function(){runFunctionAndShowProgress(function() {
//Need to transition the whole main vis, because sorting the chooser could have changed the selection
sortStyle = "wikiUsage";
catalogUserOptions();
refreshDeptAreaChoosers();
calcRectSizesAndPositions();
updateYAxis();
transitionMainViz();
updateChartTitle();
});});
// User chooses new departments or areas to display
d3.selectAll(".changesDeptAreaChoices").on("change", function(){runFunctionAndShowProgress(function(){
calcRectSizesAndPositions();
updateYAxis();
transitionMainViz();
updateChartTitle();
});});
});
});