Mercurial > hg > mpiwg_geobrowser
comparison lib/GeoTemCo/js/Time/TimeWidget.js @ 0:b57c7821382f
initial
author | Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de> |
---|---|
date | Thu, 28 May 2015 10:28:12 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b57c7821382f |
---|---|
1 /* | |
2 * TimeWidget.js | |
3 * | |
4 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 3 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
19 * MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
23 * @class TimeWidget | |
24 * TableWidget Implementation | |
25 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
26 * @release 1.0 | |
27 * @release date: 2012-07-27 | |
28 * @version date: 2012-07-27 | |
29 * | |
30 * @param {TimeWrapper} core wrapper for interaction to other widgets | |
31 * @param {HTML object} div parent div to append the time widget div | |
32 * @param {JSON} options user specified configuration that overwrites options in TimeConfig.js | |
33 */ | |
34 TimeWidget = function(core, div, options) { | |
35 | |
36 this.core = core; | |
37 this.core.setWidget(this); | |
38 this.timeplot | |
39 this.dataSources | |
40 this.eventSources | |
41 this.tds | |
42 this.timeGeometry | |
43 this.valueGeometry | |
44 this.canvas | |
45 | |
46 this.leftFlagPole | |
47 this.rightFlagPole | |
48 this.rangeBox | |
49 this.leftHandle | |
50 this.rightHandle | |
51 | |
52 this.leftFlagPos = null; | |
53 this.leftFlagTime = null; | |
54 this.rightFlagPos = null; | |
55 this.rightFlagTime = null; | |
56 | |
57 this.mouseDownTime | |
58 this.mouseUpTime | |
59 this.mouseTempTime | |
60 this.mouseDownPos | |
61 this.mouseUpPos | |
62 this.mouseTempPos | |
63 | |
64 this.status | |
65 this.slider | |
66 | |
67 this.iid = GeoTemConfig.getIndependentId('time'); | |
68 this.options = (new TimeConfig(options)).options; | |
69 this.gui = new TimeGui(this, div, this.options, this.iid); | |
70 this.initialize(); | |
71 | |
72 } | |
73 | |
74 TimeWidget.prototype = { | |
75 | |
76 /** | |
77 * clears the timeplot canvas and the timeGeometry properties | |
78 */ | |
79 clearTimeplot : function() { | |
80 this.timeplot._clearCanvas(); | |
81 this.timeGeometry._earliestDate = null; | |
82 this.timeGeometry._latestDate = null; | |
83 this.valueGeometry._minValue = 0; | |
84 this.valueGeometry._maxValue = 0; | |
85 this.highlightedSlice = undefined; | |
86 this.timeGeometry._clearLabels(); | |
87 this.selection = new Selection(); | |
88 }, | |
89 | |
90 /** | |
91 * initializes the timeplot elements with arrays of time objects | |
92 * @param {TimeObject[][]} timeObjects an array of time objects from different (1-4) sets | |
93 */ | |
94 initWidget : function(datasets) { | |
95 this.datasets = datasets; | |
96 var timeObjects = []; | |
97 for (var i = 0; i < datasets.length; i++) { | |
98 timeObjects.push(datasets[i].objects); | |
99 } | |
100 this.clearTimeplot(); | |
101 this.reset(); | |
102 for (var i = 0; i < this.timeplot._plots.length; i++) { | |
103 this.timeplot._plots[i].dispose(); | |
104 } | |
105 this.dataSources = new Array(); | |
106 this.plotInfos = new Array(); | |
107 this.eventSources = new Array(); | |
108 var granularity = 0; | |
109 this.count = 0; | |
110 for (var i = 0; i < timeObjects.length; i++) { | |
111 if( i==0 || !this.options.timeMerge ){ | |
112 var eventSource = new Timeplot.DefaultEventSource(); | |
113 var dataSource = new Timeplot.ColumnSource(eventSource, 1); | |
114 this.dataSources.push(dataSource); | |
115 this.eventSources.push(eventSource); | |
116 var c = GeoTemConfig.getColor(i); | |
117 var plotInfo = Timeplot.createPlotInfo({ | |
118 id : "plot" + i, | |
119 dataSource : dataSource, | |
120 timeGeometry : this.timeGeometry, | |
121 valueGeometry : this.valueGeometry, | |
122 fillGradient : false, | |
123 lineColor : 'rgba(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ', 1)', | |
124 fillColor : 'rgba(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ', 0.3)', | |
125 showValues : true | |
126 }); | |
127 this.plotInfos.push(plotInfo); | |
128 } | |
129 for (var j = 0; j < timeObjects[i].length; j++) { | |
130 var o = timeObjects[i][j]; | |
131 if (o.isTemporal) { | |
132 var g = o.dates[this.options.timeIndex].granularity; | |
133 if (g == null) { | |
134 continue; | |
135 } else if (g > granularity) { | |
136 granularity = g; | |
137 } | |
138 this.count += o.weight; | |
139 } | |
140 } | |
141 } | |
142 this.timeGeometry._granularity = granularity; | |
143 this.timeGeometry._clearLabels(); | |
144 this.timeplot.resetPlots(this.plotInfos); | |
145 if (this.plotInfos.length == 0) { | |
146 this.initLabels(this.timeplot.regularGrid()); | |
147 return; | |
148 } | |
149 this.timeGeometry.extendedDataSource = this.tds; | |
150 this.tds.initialize(this.dataSources, this.eventSources, timeObjects, granularity, this.options.timeUnit, this.gui.timeplotDiv.offsetWidth); | |
151 this.gui.setTimeUnitDropdown(this.tds.availableUnits); | |
152 this.gui.timeUnitDropdown.setEntry(this.tds.getUnitIndex()); | |
153 var plots = this.timeplot._plots; | |
154 for (var i = 0; i < plots.length; i++) { | |
155 plots[i].pins = []; | |
156 plots[i].style = this.style; | |
157 for (var j = 0; j < this.tds.getSliceNumber(); j++) { | |
158 plots[i].pins.push({ | |
159 height : 0, | |
160 count : 0 | |
161 }); | |
162 } | |
163 } | |
164 /* | |
165 var levels = Math.round( (this.tds.timeSlices.length-3)/2 ); | |
166 if( GeoTemConfig.timeZoom ){ | |
167 this.zoomSlider.setMaxAndLevels(levels,levels); | |
168 } | |
169 */ | |
170 this.timeplot.repaint(); | |
171 this.timeplot._resizeCanvas(); | |
172 // set maximum number of slider steps | |
173 var slices = this.tds.timeSlices.length; | |
174 var numSlices = Math.floor(slices / this.canvas.width * this.canvas.height + 0.5); | |
175 | |
176 this.initLabels([]); | |
177 this.initOverview(); | |
178 this.gui.updateTimeQuantity(this.count); | |
179 | |
180 }, | |
181 | |
182 setTimeUnit : function(unit) { | |
183 this.clearTimeplot(); | |
184 this.reset(); | |
185 this.tds.setTimeUnit(unit); | |
186 var plots = this.timeplot._plots; | |
187 for (var i = 0; i < plots.length; i++) { | |
188 plots[i].pins = []; | |
189 plots[i].style = this.style; | |
190 for (var j = 0; j < this.tds.getSliceNumber(); j++) { | |
191 plots[i].pins.push({ | |
192 height : 0, | |
193 count : 0 | |
194 }); | |
195 } | |
196 } | |
197 this.initLabels([]); | |
198 }, | |
199 | |
200 /** | |
201 * initializes the timeplot for the Spatio Temporal Interface. | |
202 * all elements (including their events) that are needed for user interaction are instantiated here, the slider element as well | |
203 */ | |
204 initialize : function() { | |
205 | |
206 this.status = 0; | |
207 this.selection = new Selection(); | |
208 this.paused = true; | |
209 this.dataSources = new Array(); | |
210 this.plotInfos = new Array(); | |
211 this.eventSources = new Array(); | |
212 this.timeGeometry = new Timeplot.DefaultTimeGeometry({ | |
213 gridColor : "#000000", | |
214 axisLabelsPlacement : "top" | |
215 }); | |
216 this.style = 'graph'; | |
217 this.timeGeometry._hideLabels = true; | |
218 this.timeGeometry._granularity = 0; | |
219 this.valueGeometry = new Timeplot.LogarithmicValueGeometry({ | |
220 min : 0 | |
221 }); | |
222 this.valueGeometry.actLinear(); | |
223 | |
224 var plot = this; | |
225 | |
226 this.timeplot = Timeplot.create(this.gui.timeplotDiv, this.plotInfos); | |
227 this.tds = new TimeDataSource(this.options); | |
228 | |
229 this.canvas = this.timeplot.getCanvas(); | |
230 | |
231 this.leftFlagPole = this.timeplot.putDiv("leftflagpole", "timeplot-dayflag-pole"); | |
232 this.rightFlagPole = this.timeplot.putDiv("rightflagpole", "timeplot-dayflag-pole"); | |
233 SimileAjax.Graphics.setOpacity(this.leftFlagPole, 50); | |
234 SimileAjax.Graphics.setOpacity(this.rightFlagPole, 50); | |
235 | |
236 this.rangeBox = this.timeplot.putDiv("rangebox", "range-box"); | |
237 this.rangeBox.style.backgroundColor = plot.options.rangeBoxColor; | |
238 this.rangeBox.style.border = plot.options.rangeBorder; | |
239 | |
240 this.leftHandle = document.createElement("div"); | |
241 this.rightHandle = document.createElement("div"); | |
242 this.gui.plotWindow.appendChild(this.leftHandle); | |
243 this.gui.plotWindow.appendChild(this.rightHandle); | |
244 this.leftHandle.title = GeoTemConfig.getString('leftHandle'); | |
245 this.rightHandle.title = GeoTemConfig.getString('rightHandle'); | |
246 | |
247 this.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
248 this.leftHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
249 this.rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")"; | |
250 this.rightHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
251 | |
252 this.poles = this.timeplot.putDiv("poles", "pole"); | |
253 this.timeplot.placeDiv(this.poles, { | |
254 left : 0, | |
255 bottom : 0, | |
256 width : this.canvas.width, | |
257 height : this.canvas.height, | |
258 display : "block" | |
259 }); | |
260 this.poles.appendChild(document.createElement("canvas")); | |
261 | |
262 this.filterBar = new FilterBar(this, this.gui.filterOptions); | |
263 | |
264 var plot = this; | |
265 | |
266 this.dragButton = document.createElement("div"); | |
267 this.dragButton.title = GeoTemConfig.getString('dragTimeRange'); | |
268 this.cancelButton = document.createElement("div"); | |
269 this.cancelButton.title = GeoTemConfig.getString('clearSelection'); | |
270 this.cancelButton.onclick = function() { | |
271 plot.deselection(); | |
272 } | |
273 | |
274 this.toolbar = document.createElement("div"); | |
275 this.toolbar.setAttribute('class', 'plotToolbar'); | |
276 this.toolbar.style.borderTop = plot.options.rangeBorder; | |
277 this.toolbar.style.textAlign = "center"; | |
278 this.gui.plotWindow.appendChild(this.toolbar); | |
279 | |
280 this.toolbarAbsoluteDiv = document.createElement("div"); | |
281 this.toolbarAbsoluteDiv.setAttribute('class', 'absoluteToolbar'); | |
282 this.toolbar.appendChild(this.toolbarAbsoluteDiv); | |
283 | |
284 this.dragButton.setAttribute('class', 'dragTimeRangeAlt'); | |
285 this.dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")"; | |
286 // this.zoomButton.setAttribute('class','zoomRangeAlt'); | |
287 this.cancelButton.setAttribute('class', 'cancelRangeAlt'); | |
288 this.toolbarAbsoluteDiv.appendChild(this.dragButton); | |
289 this.toolbarAbsoluteDiv.style.width = this.dragButton.offsetWidth + "px"; | |
290 // this.gui.plotWindow.appendChild(this.zoomButton); | |
291 this.gui.plotWindow.appendChild(this.cancelButton); | |
292 | |
293 this.overview = document.createElement("div"); | |
294 this.overview.setAttribute('class', 'timeOverview'); | |
295 this.gui.plotWindow.appendChild(this.overview); | |
296 | |
297 var mousedown = false; | |
298 this.shift = function(shift) { | |
299 if (!mousedown) { | |
300 return; | |
301 } | |
302 if (plot.tds.setShift(shift)) { | |
303 plot.redrawPlot(); | |
304 } | |
305 setTimeout(function() { | |
306 plot.shift(shift); | |
307 }, 200); | |
308 } | |
309 var shiftPressed = function(shift) { | |
310 mousedown = true; | |
311 document.onmouseup = function() { | |
312 mousedown = false; | |
313 document.onmouseup = null; | |
314 } | |
315 plot.shift(shift); | |
316 } | |
317 | |
318 this.shiftLeft = document.createElement("div"); | |
319 this.shiftLeft.setAttribute('class', 'shiftLeft'); | |
320 this.gui.plotWindow.appendChild(this.shiftLeft); | |
321 this.shiftLeft.onmousedown = function() { | |
322 shiftPressed(1); | |
323 } | |
324 | |
325 this.shiftRight = document.createElement("div"); | |
326 this.shiftRight.setAttribute('class', 'shiftRight'); | |
327 this.gui.plotWindow.appendChild(this.shiftRight); | |
328 this.shiftRight.onmousedown = function() { | |
329 shiftPressed(-1); | |
330 } | |
331 | |
332 this.plotLabels = document.createElement("div"); | |
333 this.plotLabels.setAttribute('class', 'plotLabels'); | |
334 this.gui.plotWindow.appendChild(this.plotLabels); | |
335 | |
336 this.initLabels(this.timeplot.regularGrid()); | |
337 | |
338 //Finds the time corresponding to the position x on the timeplot | |
339 var getCorrelatedTime = function(x) { | |
340 if (x >= plot.canvas.width) | |
341 x = plot.canvas.width; | |
342 if (isNaN(x) || x < 0) | |
343 x = 0; | |
344 var t = plot.timeGeometry.fromScreen(x); | |
345 if (t == 0) | |
346 return; | |
347 return plot.dataSources[0].getClosestValidTime(t); | |
348 } | |
349 //Finds the position corresponding to the time t on the timeplot | |
350 var getCorrelatedPosition = function(t) { | |
351 var x = plot.timeGeometry.toScreen(t); | |
352 if (x >= plot.canvas.width) | |
353 x = plot.canvas.width; | |
354 if (isNaN(x) || x < 0) | |
355 x = 0; | |
356 return x; | |
357 } | |
358 //Maps the 2 positions in the right order to left and right bound of the chosen timeRange | |
359 var mapPositions = function(pos1, pos2) { | |
360 if (pos1 > pos2) { | |
361 plot.leftFlagPos = pos2; | |
362 plot.rightFlagPos = pos1; | |
363 } else { | |
364 plot.leftFlagPos = pos1; | |
365 plot.rightFlagPos = pos2; | |
366 } | |
367 plot.leftFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.leftFlagPos)); | |
368 plot.rightFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.rightFlagPos)); | |
369 } | |
370 //Sets the divs corresponding to the actual chosen timeRange | |
371 var setRangeDivs = function() { | |
372 plot.leftFlagPole.style.visibility = "visible"; | |
373 plot.rightFlagPole.style.visibility = "visible"; | |
374 plot.rangeBox.style.visibility = "visible"; | |
375 plot.timeplot.placeDiv(plot.leftFlagPole, { | |
376 left : plot.leftFlagPos, | |
377 bottom : 0, | |
378 height : plot.canvas.height, | |
379 display : "block" | |
380 }); | |
381 plot.timeplot.placeDiv(plot.rightFlagPole, { | |
382 left : plot.rightFlagPos, | |
383 bottom : 0, | |
384 height : plot.canvas.height, | |
385 display : "block" | |
386 }); | |
387 var boxWidth = plot.rightFlagPos - plot.leftFlagPos; | |
388 if (plot.popup) { | |
389 plot.popupClickDiv.style.visibility = "visible"; | |
390 plot.timeplot.placeDiv(plot.popupClickDiv, { | |
391 left : plot.leftFlagPos, | |
392 width : boxWidth + 1, | |
393 height : plot.canvas.height, | |
394 display : "block" | |
395 }); | |
396 } | |
397 plot.timeplot.placeDiv(plot.rangeBox, { | |
398 left : plot.leftFlagPos, | |
399 width : boxWidth + 1, | |
400 height : plot.canvas.height, | |
401 display : "block" | |
402 }); | |
403 var plots = plot.timeplot._plots; | |
404 for ( i = 0; i < plots.length; i++) { | |
405 plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i)); | |
406 plots[i].opacityPlot.style.visibility = "visible"; | |
407 } | |
408 var unit = plot.tds.unit; | |
409 | |
410 var top = plot.gui.plotContainer.offsetTop; | |
411 var left = plot.gui.plotContainer.offsetLeft; | |
412 var leftPos = plot.leftFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft; | |
413 var rightPos = plot.rightFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft; | |
414 var rW = rightPos - leftPos; | |
415 var pW = plot.canvas.width; | |
416 var pL = plot.timeplot.getElement().offsetLeft; | |
417 | |
418 var handleTop = top + Math.floor(plot.gui.timeplotDiv.offsetHeight / 2 - plot.leftHandle.offsetHeight / 2); | |
419 plot.leftHandle.style.visibility = "visible"; | |
420 plot.rightHandle.style.visibility = "visible"; | |
421 plot.leftHandle.style.left = (leftPos - plot.leftHandle.offsetWidth / 2) + "px"; | |
422 plot.rightHandle.style.left = (rightPos - plot.rightHandle.offsetWidth + 1 + plot.rightHandle.offsetWidth / 2) + "px"; | |
423 plot.leftHandle.style.top = handleTop + "px"; | |
424 plot.rightHandle.style.top = handleTop + "px"; | |
425 if (rightPos == leftPos) { | |
426 plot.rightHandle.style.visibility = "hidden"; | |
427 plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "mergedHandle.png" + ")"; | |
428 } else { | |
429 plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
430 } | |
431 plot.cancelButton.style.visibility = "visible"; | |
432 plot.cancelButton.style.top = top + "px"; | |
433 | |
434 if (rW > plot.cancelButton.offsetWidth) { | |
435 plot.cancelButton.style.left = (left + rightPos - plot.cancelButton.offsetWidth) + "px"; | |
436 } else { | |
437 plot.cancelButton.style.left = (left + rightPos) + "px"; | |
438 } | |
439 var tW = plot.toolbarAbsoluteDiv.offsetWidth; | |
440 if (rW >= tW) { | |
441 plot.toolbar.style.left = leftPos + "px"; | |
442 plot.toolbar.style.width = (rW + 1) + "px"; | |
443 plot.toolbarAbsoluteDiv.style.left = ((rW - tW) / 2) + "px"; | |
444 } else { | |
445 plot.toolbar.style.left = (pL + plot.leftFlagPos * (pW - tW) / (pW - rW)) + "px"; | |
446 plot.toolbar.style.width = (tW + 2) + "px"; | |
447 plot.toolbarAbsoluteDiv.style.left = "0px"; | |
448 } | |
449 plot.toolbar.style.top = (top + plot.timeplot.getElement().offsetHeight) + "px"; | |
450 plot.toolbar.style.visibility = "visible"; | |
451 plot.toolbarAbsoluteDiv.style.visibility = "visible"; | |
452 | |
453 } | |
454 var getAbsoluteLeft = function(div) { | |
455 var left = 0; | |
456 while (div) { | |
457 left += div.offsetLeft; | |
458 div = div.offsetParent; | |
459 } | |
460 return left; | |
461 } | |
462 var timeplotLeft = getAbsoluteLeft(plot.timeplot.getElement()); | |
463 | |
464 var checkPolesForStyle = function(x) { | |
465 if (plot.style == 'bars' && plot.leftFlagTime == plot.rightFlagTime) { | |
466 var index = plot.tds.getSliceIndex(plot.leftFlagTime); | |
467 var time1 = plot.leftFlagTime; | |
468 var pos1 = plot.leftFlagPos; | |
469 var time2, pos2; | |
470 if (index == 0) { | |
471 time2 = plot.tds.getSliceTime(index + 1); | |
472 } else if (index == plot.tds.getSliceNumber() - 1) { | |
473 time2 = plot.tds.getSliceTime(index - 1); | |
474 } else { | |
475 if (x < plot.leftFlagPos) { | |
476 time2 = plot.tds.getSliceTime(index - 1); | |
477 } else { | |
478 time2 = plot.tds.getSliceTime(index + 1); | |
479 } | |
480 } | |
481 pos2 = plot.timeGeometry.toScreen(time2); | |
482 mapPositions(pos1, pos2, time1, time2); | |
483 } | |
484 } | |
485 var startX, startY, multiplier; | |
486 | |
487 // mousemove function that causes moving selection of objects and toolbar divs | |
488 var moveToolbar = function(start, actual) { | |
489 var pixelShift = actual - start; | |
490 if (plot.status == 2) { | |
491 var newTime = getCorrelatedTime(startX + pixelShift); | |
492 if (newTime == plot.mouseTempTime) { | |
493 return; | |
494 } | |
495 plot.mouseTempTime = newTime; | |
496 plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime); | |
497 mapPositions(plot.mouseDownPos, plot.mouseTempPos); | |
498 } else if (plot.status == 3) { | |
499 pixelShift *= multiplier; | |
500 var plotPos = actual - timeplotLeft; | |
501 if (plotPos <= plot.canvas.width / 2) { | |
502 var newTime = getCorrelatedTime(startX + pixelShift); | |
503 if (newTime == plot.leftFlagTime) { | |
504 return; | |
505 } | |
506 plot.leftFlagTime = newTime; | |
507 var diff = plot.leftFlagPos; | |
508 plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime); | |
509 diff -= plot.leftFlagPos; | |
510 plot.rightFlagTime = getCorrelatedTime(plot.rightFlagPos - diff); | |
511 plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime); | |
512 } else { | |
513 var newTime = getCorrelatedTime(startY + pixelShift); | |
514 if (newTime == plot.rightFlagTime) { | |
515 return; | |
516 } | |
517 plot.rightFlagTime = newTime; | |
518 var diff = plot.rightFlagPos; | |
519 plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime); | |
520 diff -= plot.rightFlagPos; | |
521 plot.leftFlagTime = getCorrelatedTime(plot.leftFlagPos - diff); | |
522 plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime); | |
523 } | |
524 } | |
525 checkPolesForStyle(actual - timeplotLeft); | |
526 setRangeDivs(); | |
527 plot.timeSelection(); | |
528 } | |
529 // fakes user interaction mouse move | |
530 var playIt = function(start, actual, reset) { | |
531 if (!plot.paused) { | |
532 var pixel = plot.canvas.width / (plot.tds.timeSlices.length - 1 ) / 5; | |
533 var wait = 20 * pixel; | |
534 if (reset) { | |
535 actual = 0; | |
536 } | |
537 moveToolbar(start, actual); | |
538 if (plot.rightFlagPos >= plot.canvas.width) { | |
539 reset = true; | |
540 wait = 1000; | |
541 } else { | |
542 reset = false; | |
543 } | |
544 setTimeout(function() { | |
545 playIt(start, actual + pixel, reset) | |
546 }, wait); | |
547 } | |
548 } | |
549 var setMultiplier = function() { | |
550 var rangeWidth = plot.rightFlagPos - plot.leftFlagPos; | |
551 var toolbarWidth = plot.toolbarAbsoluteDiv.offsetWidth; | |
552 var plotWidth = plot.canvas.width; | |
553 if (rangeWidth < toolbarWidth) { | |
554 multiplier = (plotWidth - rangeWidth) / (plotWidth - toolbarWidth); | |
555 } else { | |
556 multiplier = 1; | |
557 } | |
558 } | |
559 /** | |
560 * starts the animation | |
561 */ | |
562 this.play = function() { | |
563 if (this.leftFlagPos == null) { | |
564 return; | |
565 } | |
566 plot.paused = false; | |
567 plot.gui.updateAnimationButtons(2); | |
568 plot.status = 3; | |
569 setMultiplier(); | |
570 startX = plot.leftFlagPos; | |
571 startY = plot.rightFlagPos; | |
572 var position = Math.round(plot.leftFlagPos); | |
573 playIt(position, position + 1, false); | |
574 } | |
575 /** | |
576 * stops the animation | |
577 */ | |
578 this.stop = function() { | |
579 plot.paused = true; | |
580 plot.status = 0; | |
581 plot.gui.updateAnimationButtons(1); | |
582 } | |
583 // triggers the mousemove function to move the range and toolbar | |
584 var toolbarEvent = function(evt) { | |
585 var left = GeoTemConfig.getMousePosition(evt).left; | |
586 document.onmousemove = function(evt) { | |
587 moveToolbar(left, GeoTemConfig.getMousePosition(evt).left); | |
588 if (plot.popup) { | |
589 plot.popup.reset(); | |
590 } | |
591 } | |
592 } | |
593 var initializeLeft = function() { | |
594 plot.mouseDownTime = plot.rightFlagTime; | |
595 plot.mouseTempTime = plot.leftFlagTime; | |
596 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
597 startX = plot.leftFlagPos; | |
598 } | |
599 var initializeRight = function() { | |
600 plot.mouseDownTime = plot.leftFlagTime; | |
601 plot.mouseTempTime = plot.rightFlagTime; | |
602 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
603 startX = plot.rightFlagPos; | |
604 } | |
605 var initializeDrag = function() { | |
606 startX = plot.leftFlagPos; | |
607 startY = plot.rightFlagPos; | |
608 setMultiplier(); | |
609 } | |
610 var checkBorders = function() { | |
611 if (plot.style == 'bars' && plot.mouseUpTime == plot.mouseDownTime) { | |
612 var index = plot.tds.getSliceIndex(plot.mouseUpTime); | |
613 if (index == 0) { | |
614 plot.mouseUpTime = plot.tds.getSliceTime(index + 1); | |
615 } else if (index == plot.tds.getSliceNumber() - 1) { | |
616 plot.mouseUpTime = plot.tds.getSliceTime(index - 1); | |
617 } else { | |
618 if (plot.x < plot.leftFlagPos) { | |
619 plot.mouseUpTime = plot.tds.getSliceTime(index - 1); | |
620 } else { | |
621 plot.mouseUpTime = plot.tds.getSliceTime(index + 1); | |
622 } | |
623 } | |
624 } | |
625 } | |
626 // handles mousedown on left handle | |
627 this.leftHandle.onmousedown = function(evt) { | |
628 if (plot.status != 2) { | |
629 | |
630 initializeLeft(); | |
631 plot.status = 2; | |
632 toolbarEvent(evt); | |
633 document.onmouseup = function() { | |
634 document.onmousemove = null; | |
635 document.onmouseup = null; | |
636 plot.stop(); | |
637 } | |
638 } | |
639 } | |
640 // handles mousedown on right handle | |
641 this.rightHandle.onmousedown = function(evt) { | |
642 if (plot.status != 2) { | |
643 initializeRight(); | |
644 plot.status = 2; | |
645 toolbarEvent(evt); | |
646 document.onmouseup = function() { | |
647 document.onmousemove = null; | |
648 document.onmouseup = null; | |
649 plot.stop(); | |
650 } | |
651 } | |
652 } | |
653 // handles mousedown on drag button | |
654 this.dragButton.onmousedown = function(evt) { | |
655 if (plot.status != 3) { | |
656 plot.status = 3; | |
657 initializeDrag(); | |
658 toolbarEvent(evt); | |
659 document.onmouseup = function() { | |
660 document.onmousemove = null; | |
661 document.onmouseup = null; | |
662 plot.stop(); | |
663 } | |
664 } | |
665 } | |
666 // handles mousedown-Event on timeplot | |
667 var mouseDownHandler = function(elmt, evt, target) { | |
668 if (plot.dataSources.length > 0) { | |
669 | |
670 plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
671 if (plot.status == 0) { | |
672 var time = getCorrelatedTime(plot.x); | |
673 if (plot.leftFlagPos != null && plot.popup && time >= plot.leftFlagTime && time <= plot.rightFlagTime) { | |
674 var x = plot.leftFlagPos + (plot.rightFlagPos - plot.leftFlagPos) / 2; | |
675 var elements = []; | |
676 for (var i = 0; i < plot.dataSources.length; i++) { | |
677 elements.push([]); | |
678 } | |
679 for (var i = 0; i < plot.selectedObjects.length; i++) { | |
680 if (plot.selectedObjects[i].value == 1) { | |
681 for (var j = 0; j < plot.selectedObjects[i].objects.length; j++) { | |
682 elements[j] = elements[j].concat(plot.selectedObjects[i].objects[j]); | |
683 } | |
684 } | |
685 } | |
686 var labels = []; | |
687 for (var i = 0; i < elements.length; i++) { | |
688 if (elements[i].length == 0) { | |
689 continue; | |
690 } | |
691 var c = GeoTemConfig.getColor(i); | |
692 var color = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
693 var div = document.createElement("div"); | |
694 div.setAttribute('class', 'tagCloudItem'); | |
695 div.style.color = color; | |
696 var label = { | |
697 div : div, | |
698 elements : elements[i] | |
699 }; | |
700 var weight = 0; | |
701 for (j in elements[i] ) { | |
702 weight += elements[i][j].weight; | |
703 } | |
704 var fs = 2 * weight / 1000; | |
705 if (fs > 2) { | |
706 fs = 2; | |
707 } | |
708 div.style.fontSize = (1 + fs) + "em"; | |
709 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + c.hex; | |
710 if (weight == 1) { | |
711 div.innerHTML = weight + " object"; | |
712 } else { | |
713 div.innerHTML = weight + " objects"; | |
714 } | |
715 var appendMouseFunctions = function(label, div, color) { | |
716 div.onclick = function() { | |
717 plot.popup.showLabelContent(label); | |
718 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color; | |
719 } | |
720 div.onmouseover = function() { | |
721 div.style.textShadow = "0 -1px " + color + ", 1px 0 " + color + ", 0 1px " + color + ", -1px 0 " + color; | |
722 } | |
723 div.onmouseout = function() { | |
724 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color; | |
725 } | |
726 } | |
727 appendMouseFunctions(label, div, c.hex); | |
728 labels.push(label); | |
729 } | |
730 if (labels.length > 0) { | |
731 plot.popup.createPopup(x + 20, 0, labels); | |
732 } | |
733 } else { | |
734 plot.deselection(); | |
735 plot.status = 1; | |
736 plot.mouseDownTime = time; | |
737 plot.mouseTempTime = plot.mouseDownTime; | |
738 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
739 mapPositions(plot.mouseDownPos, plot.mouseDownPos, plot.mouseDownTime, plot.mouseDownTime); | |
740 // handles mouseup-Event on timeplot | |
741 document.onmouseup = function() { | |
742 if (plot.status == 1) { | |
743 plot.mouseUpTime = plot.mouseTempTime; | |
744 plot.mouseUpPos = plot.timeGeometry.toScreen(plot.mouseUpTime); | |
745 mapPositions(plot.mouseDownPos, plot.mouseUpPos, plot.mouseDownTime, plot.mouseUpTime); | |
746 checkPolesForStyle(plot.x); | |
747 setRangeDivs(); | |
748 plot.timeSelection(); | |
749 plot.gui.updateAnimationButtons(1); | |
750 document.onmouseup = null; | |
751 plot.status = 0; | |
752 } | |
753 } | |
754 } | |
755 } | |
756 } | |
757 } | |
758 // handles mousemove-Event on timeplot | |
759 var mouseMoveHandler = function(elmt, evt, target) { | |
760 if (plot.dataSources.length > 0) { | |
761 plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
762 if (plot.status == 1) { | |
763 plot.mouseTempTime = getCorrelatedTime(plot.x); | |
764 plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime); | |
765 mapPositions(plot.mouseDownPos, plot.mouseTempPos, plot.mouseDownTime, plot.mouseTempTime); | |
766 checkPolesForStyle(plot.x); | |
767 setRangeDivs(); | |
768 } | |
769 } | |
770 } | |
771 // handles mouseout-Event on timeplot | |
772 var mouseOutHandler = function(elmt, evt, target) { | |
773 if (plot.dataSources.length > 0) { | |
774 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
775 var y = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).y); | |
776 if (x > plot.canvas.width - 2 || isNaN(x) || x < 2) { | |
777 plot.timeHighlight(true); | |
778 plot.highlightedSlice = undefined; | |
779 } else if (y > plot.canvas.height - 2 || isNaN(y) || y < 2) { | |
780 plot.timeHighlight(true); | |
781 plot.highlightedSlice = undefined; | |
782 } | |
783 } | |
784 } | |
785 // handles mouse(h)over-Event on timeplot | |
786 var mouseHoverHandler = function(elmt, evt, target) { | |
787 if (plot.dataSources.length > 0) { | |
788 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
789 var time = getCorrelatedTime(x); | |
790 if (time == undefined) { | |
791 return; | |
792 } | |
793 var highlightSlice; | |
794 var slices = plot.tds.timeSlices; | |
795 var index = plot.tds.getSliceIndex(time); | |
796 if (plot.style == 'graph') { | |
797 highlightSlice = slices[index]; | |
798 } | |
799 if (plot.style == 'bars') { | |
800 var pos = plot.timeGeometry.toScreen(time); | |
801 if (x < pos && index > 0) { | |
802 highlightSlice = slices[index - 1]; | |
803 } else { | |
804 highlightSlice = slices[index]; | |
805 } | |
806 } | |
807 if (plot.highlightedSlice == undefined || plot.highlightedSlice != highlightSlice) { | |
808 plot.highlightedSlice = highlightSlice; | |
809 plot.timeHighlight(false); | |
810 } | |
811 } | |
812 } | |
813 | |
814 this.redrawPlot = function() { | |
815 plot.clearTimeplot(); | |
816 plot.tds.reset(this.timeGeometry); | |
817 plot.timeplot._prepareCanvas(); | |
818 plot.timeplot.repaint(); | |
819 if (plot.leftFlagPos != null) { | |
820 plot.leftFlagPos = getCorrelatedPosition(plot.leftFlagTime); | |
821 plot.rightFlagPos = getCorrelatedPosition(plot.rightFlagTime); | |
822 setRangeDivs(); | |
823 } else { | |
824 plot.displayOverlay(); | |
825 } | |
826 plot.initLabels([]); | |
827 plot.updateOverview(); | |
828 } | |
829 | |
830 this.resetOpacityPlots = function() { | |
831 var plots = plot.timeplot._plots; | |
832 for ( var i = 0; i < plots.length; i++) { | |
833 plots[i]._opacityCanvas.width = this.canvas.width; | |
834 plots[i]._opacityCanvas.height = this.canvas.height; | |
835 if( plot.leftFlagTime != null ){ | |
836 plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i)); | |
837 } | |
838 } | |
839 } | |
840 | |
841 /** | |
842 * handles zoom of the timeplot | |
843 * @param {int} delta the change of zoom | |
844 * @param {Date} time a time that corresponds to a slice, that was clicked | |
845 */ | |
846 /* | |
847 this.zoom = function(delta,time){ | |
848 if( this.eventSources.length == 0 ){ | |
849 if( GeoTemConfig.timeZoom ){ | |
850 this.zoomSlider.setValue(0); | |
851 } | |
852 return false; | |
853 } | |
854 if( time == null ){ | |
855 time = getCorrelatedTime(this.canvas.width/2); | |
856 } | |
857 if( this.tds.setZoom(delta,time,this.leftFlagTime,this.rightFlagTime) ){ | |
858 this.redrawPlot(); | |
859 } | |
860 if( GeoTemConfig.timeZoom ){ | |
861 this.zoomSlider.setValue(this.tds.getZoom()); | |
862 } | |
863 return true; | |
864 } | |
865 */ | |
866 | |
867 // handles mousewheel event on the timeplot | |
868 var mouseWheelHandler = function(elmt, evt, target) { | |
869 if (evt.preventDefault) { | |
870 evt.preventDefault(); | |
871 } | |
872 if (plot.dataSources.length == 0) { | |
873 return; | |
874 } | |
875 var delta = 0; | |
876 if (!evt) | |
877 evt = window.event; | |
878 if (evt.wheelDelta) { | |
879 delta = evt.wheelDelta / 120; | |
880 if (window.opera) | |
881 delta = -delta; | |
882 } else if (evt.detail) { | |
883 delta = -evt.detail / 3; | |
884 } | |
885 if (delta) { | |
886 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
887 var time = getCorrelatedTime(x); | |
888 plot.zoom(delta, time); | |
889 } | |
890 } | |
891 var timeplotElement = this.timeplot.getElement(); | |
892 SimileAjax.DOM.registerEvent(timeplotElement, "mousedown", mouseDownHandler); | |
893 SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler); | |
894 SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseHoverHandler); | |
895 SimileAjax.DOM.registerEvent(timeplotElement, "mouseout", mouseOutHandler); | |
896 if (GeoTemConfig.mouseWheelZoom) { | |
897 //SimileAjax.DOM.registerEvent(timeplotElement, "mousewheel", mouseWheelHandler); | |
898 } | |
899 | |
900 this.gui.setHeight(); | |
901 | |
902 }, | |
903 | |
904 resetOverlay : function() { | |
905 this.poles.style.visibility = "hidden"; | |
906 var plots = this.timeplot._plots; | |
907 for (var i = 0; i < plots.length; i++) { | |
908 for (var j = 0; j < plots[i].pins.length; j++) { | |
909 plots[i].pins[j] = { | |
910 height : 0, | |
911 count : 0 | |
912 }; | |
913 } | |
914 } | |
915 }, | |
916 | |
917 /** | |
918 * resets the timeplot to non selection status | |
919 */ | |
920 reset : function() { | |
921 | |
922 this.leftFlagPole.style.visibility = "hidden"; | |
923 this.rightFlagPole.style.visibility = "hidden"; | |
924 this.rangeBox.style.visibility = "hidden"; | |
925 this.leftHandle.style.visibility = "hidden"; | |
926 this.rightHandle.style.visibility = "hidden"; | |
927 this.toolbar.style.visibility = "hidden"; | |
928 this.toolbarAbsoluteDiv.style.visibility = "hidden"; | |
929 this.cancelButton.style.visibility = "hidden"; | |
930 | |
931 var plots = this.timeplot._plots; | |
932 for (var i = 0; i < plots.length; i++) { | |
933 plots[i].opacityPlot.style.visibility = "hidden"; | |
934 } | |
935 this.resetOverlay(); | |
936 this.filterBar.reset(false); | |
937 | |
938 var slices = this.tds.timeSlices; | |
939 if (slices != undefined) { | |
940 for (var i = 0; i < slices.length; i++) { | |
941 slices[i].reset(); | |
942 } | |
943 } | |
944 | |
945 this.status = 0; | |
946 this.stop(); | |
947 this.gui.updateAnimationButtons(0); | |
948 | |
949 this.leftFlagPos = null; | |
950 this.leftFlagTime = null; | |
951 this.rightFlagPos = null; | |
952 this.rightFlagTime = null; | |
953 | |
954 this.mouseDownTime = null; | |
955 this.mouseUpTime = null; | |
956 this.mouseTempTime = null; | |
957 | |
958 this.mouseDownPos = null; | |
959 this.mouseUpPos = null; | |
960 this.mouseTempPos = null; | |
961 | |
962 if (this.popup) { | |
963 this.popup.reset(); | |
964 this.popupClickDiv.style.visibility = "hidden"; | |
965 } | |
966 | |
967 }, | |
968 | |
969 /** | |
970 * sets a pole on the timeplot | |
971 * @param {Date} time the time of the specific timeslice | |
972 * @param {int[]} the number of selected elements per dataset | |
973 */ | |
974 displayOverlay : function() { | |
975 this.poles.style.visibility = "visible"; | |
976 var cv = this.poles.getElementsByTagName("canvas")[0]; | |
977 cv.width = this.canvas.width; | |
978 cv.height = this.canvas.height; | |
979 if (!cv.getContext && G_vmlCanvasManager) { | |
980 cv = G_vmlCanvasManager.initElement(cv); | |
981 } | |
982 var ctx = cv.getContext('2d'); | |
983 ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | |
984 var plots = this.timeplot._plots; | |
985 var slices = this.tds.timeSlices; | |
986 for (var i = 0; i < slices.length; i++) { | |
987 if (this.style == 'bars' && i + 1 == slices.length) { | |
988 return; | |
989 } | |
990 if (slices[i].overlay() == 0) { | |
991 continue; | |
992 } | |
993 var projStacks = slices[i].projStacks; | |
994 var time = slices[i].date; | |
995 var pos; | |
996 if (this.style == 'graph') { | |
997 pos = this.timeGeometry.toScreen(time); | |
998 } else if (this.style == 'bars') { | |
999 var x1 = this.timeGeometry.toScreen(time); | |
1000 var x2 = this.timeGeometry.toScreen(slices[i + 1].date); | |
1001 pos = (x1 + x2 ) / 2; | |
1002 } | |
1003 var heights = []; | |
1004 var h = 0; | |
1005 for (var j = 0; j < projStacks.length; j++) { | |
1006 var data = plots[j]._dataSource.getData(); | |
1007 for (var k = 0; k < data.times.length; k++) { | |
1008 if (data.times[k].getTime() == time.getTime()) { | |
1009 var height = plots[j]._valueGeometry.toScreen(plots[j]._dataSource.getData().values[k]) * projStacks[j].overlay / projStacks[j].value; | |
1010 heights.push(height); | |
1011 plots[j].pins[i] = { | |
1012 height : height, | |
1013 count : projStacks[j].overlay | |
1014 }; | |
1015 if (height > h) { | |
1016 h = height; | |
1017 } | |
1018 break; | |
1019 } | |
1020 } | |
1021 } | |
1022 ctx.fillStyle = "rgb(102,102,102)"; | |
1023 ctx.beginPath(); | |
1024 ctx.rect(pos - 1, this.canvas.height - h, 2, h); | |
1025 ctx.fill(); | |
1026 for (var j = 0; j < heights.length; j++) { | |
1027 if (heights[j] > 0) { | |
1028 var color = GeoTemConfig.getColor(j); | |
1029 ctx.fillStyle = "rgba(" + color.r1 + "," + color.g1 + "," + color.b1 + ",0.6)"; | |
1030 ctx.beginPath(); | |
1031 ctx.arc(pos, this.canvas.height - heights[j], 2.5, 0, Math.PI * 2, true); | |
1032 ctx.closePath(); | |
1033 ctx.fill(); | |
1034 } | |
1035 } | |
1036 } | |
1037 }, | |
1038 | |
1039 /** | |
1040 * updates the timeplot by displaying place poles, after a selection had been executed in another widget | |
1041 */ | |
1042 highlightChanged : function(timeObjects) { | |
1043 if( !GeoTemConfig.highlightEvents ){ | |
1044 return; | |
1045 } | |
1046 this.resetOverlay(); | |
1047 if (this.selection.valid()) { | |
1048 if (!this.selection.equal(this)) { | |
1049 this.tds.setOverlay(GeoTemConfig.mergeObjects(timeObjects, this.selection.getObjects(this))); | |
1050 } else { | |
1051 this.tds.setOverlay(timeObjects); | |
1052 } | |
1053 } else { | |
1054 this.tds.setOverlay(timeObjects); | |
1055 } | |
1056 this.displayOverlay(); | |
1057 }, | |
1058 | |
1059 /** | |
1060 * updates the timeplot by displaying place poles, after a selection had been executed in another widget | |
1061 */ | |
1062 selectionChanged : function(selection) { | |
1063 if( !GeoTemConfig.selectionEvents ){ | |
1064 return; | |
1065 } | |
1066 this.reset(); | |
1067 this.selection = selection; | |
1068 this.tds.setOverlay(selection.objects); | |
1069 this.displayOverlay(); | |
1070 }, | |
1071 | |
1072 /** | |
1073 * returns the approximate left position of a slice inside the overview representation | |
1074 * @param {Date} time time of the slice | |
1075 */ | |
1076 getOverviewLeft : function(time) { | |
1077 var w = this.overview.offsetWidth; | |
1078 var s = this.tds.earliest().getTime(); | |
1079 var e = this.tds.latest().getTime(); | |
1080 var t = time.getTime(); | |
1081 return Math.round(w * (t - s) / (e - s)); | |
1082 }, | |
1083 | |
1084 /** | |
1085 * visualizes the overview div (shows viewable part of zoomed timeplot) | |
1086 */ | |
1087 initOverview : function() { | |
1088 var labels = this.timeGeometry._grid; | |
1089 if (labels.length == 0) { | |
1090 var plot = this; | |
1091 setTimeout(function() { | |
1092 plot.initOverview(); | |
1093 }, 10); | |
1094 return; | |
1095 } | |
1096 | |
1097 this.overview.style.width = this.canvas.width + "px"; | |
1098 var left = this.gui.timeplotDiv.offsetLeft; | |
1099 this.overview.innerHTML = ""; | |
1100 this.overview.style.left = left + "px"; | |
1101 | |
1102 this.overviewRange = document.createElement("div"); | |
1103 this.overviewRange.setAttribute('class', 'overviewRange'); | |
1104 this.overview.appendChild(this.overviewRange); | |
1105 | |
1106 for (var i = 0; i < labels.length; i++) { | |
1107 var label = document.createElement("div"); | |
1108 label.setAttribute('class', 'overviewLabel'); | |
1109 label.innerHTML = labels[i].label; | |
1110 label.style.left = Math.floor(labels[i].x) + "px"; | |
1111 this.overview.appendChild(label); | |
1112 } | |
1113 | |
1114 this.updateOverview(); | |
1115 }, | |
1116 | |
1117 /** | |
1118 * visualizes the labels of the timeplot | |
1119 */ | |
1120 initLabels : function(labels) { | |
1121 if (labels.length == 0) { | |
1122 labels = this.timeGeometry._grid; | |
1123 if (labels.length == 0) { | |
1124 var plot = this; | |
1125 setTimeout(function() { | |
1126 plot.initLabels([]); | |
1127 }, 10); | |
1128 return; | |
1129 } | |
1130 } | |
1131 this.plotLabels.style.width = this.canvas.width + "px"; | |
1132 var left = this.gui.timeplotDiv.offsetLeft; | |
1133 this.plotLabels.style.left = left + "px"; | |
1134 this.plotLabels.innerHTML = ""; | |
1135 for (var i = 0; i < labels.length; i++) { | |
1136 var label = document.createElement("div"); | |
1137 label.setAttribute('class', 'plotLabel'); | |
1138 label.innerHTML = labels[i].label; | |
1139 label.style.left = Math.floor(labels[i].x) + "px"; | |
1140 this.plotLabels.appendChild(label); | |
1141 } | |
1142 }, | |
1143 | |
1144 /** | |
1145 * updates the overview div | |
1146 */ | |
1147 updateOverview : function() { | |
1148 if (this.tds.getZoom() > 0) { | |
1149 this.plotLabels.style.visibility = "hidden"; | |
1150 this.timeGeometry._hideLabels = false; | |
1151 this.overview.style.visibility = "visible"; | |
1152 this.shiftLeft.style.visibility = "visible"; | |
1153 this.shiftRight.style.visibility = "visible"; | |
1154 var left = this.getOverviewLeft(this.tds.timeSlices[this.tds.leftSlice].date); | |
1155 var right = this.getOverviewLeft(this.tds.timeSlices[this.tds.rightSlice].date); | |
1156 this.overviewRange.style.left = left + "px"; | |
1157 this.overviewRange.style.width = (right - left) + "px"; | |
1158 } else { | |
1159 this.timeGeometry._hideLabels = true; | |
1160 this.plotLabels.style.visibility = "visible"; | |
1161 this.overview.style.visibility = "hidden"; | |
1162 this.shiftLeft.style.visibility = "hidden"; | |
1163 this.shiftRight.style.visibility = "hidden"; | |
1164 } | |
1165 }, | |
1166 | |
1167 /** | |
1168 * returns the time slices which are created by the extended data source | |
1169 */ | |
1170 getSlices : function() { | |
1171 return this.tds.timeSlices; | |
1172 }, | |
1173 | |
1174 timeSelection : function() { | |
1175 var slices = this.tds.timeSlices; | |
1176 var ls, rs; | |
1177 for (var i = 0; i < slices.length; i++) { | |
1178 if (slices[i].date.getTime() == this.leftFlagTime.getTime()) | |
1179 ls = i; | |
1180 if (slices[i].date.getTime() == this.rightFlagTime.getTime()) { | |
1181 if (this.style == 'graph') { | |
1182 rs = i; | |
1183 } | |
1184 if (this.style == 'bars') { | |
1185 rs = i - 1; | |
1186 } | |
1187 } | |
1188 } | |
1189 var selectedObjects = []; | |
1190 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
1191 selectedObjects.push([]); | |
1192 } | |
1193 for (var i = 0; i < slices.length; i++) { | |
1194 if (i >= ls && i <= rs) { | |
1195 for (var j in slices[i].stacks ) { | |
1196 selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements); | |
1197 } | |
1198 } | |
1199 } | |
1200 this.selection = new Selection(selectedObjects, this); | |
1201 this.core.triggerSelection(this.selection); | |
1202 this.filterBar.reset(true); | |
1203 }, | |
1204 | |
1205 deselection : function() { | |
1206 this.reset(); | |
1207 this.selection = new Selection(); | |
1208 this.core.triggerSelection(this.selection); | |
1209 }, | |
1210 | |
1211 filtering : function() { | |
1212 for (var i = 0; i < this.datasets.length; i++) { | |
1213 this.datasets[i].objects = this.selection.objects[i]; | |
1214 } | |
1215 this.core.triggerRefining(this.datasets); | |
1216 }, | |
1217 | |
1218 inverseFiltering : function() { | |
1219 var slices = this.tds.timeSlices; | |
1220 var ls, rs; | |
1221 for (var i = 0; i < slices.length; i++) { | |
1222 if (slices[i].date.getTime() == this.leftFlagTime.getTime()) | |
1223 ls = i; | |
1224 if (slices[i].date.getTime() == this.rightFlagTime.getTime()) { | |
1225 if (this.style == 'graph') { | |
1226 rs = i; | |
1227 } | |
1228 if (this.style == 'bars') { | |
1229 rs = i - 1; | |
1230 } | |
1231 } | |
1232 } | |
1233 var selectedObjects = []; | |
1234 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
1235 selectedObjects.push([]); | |
1236 } | |
1237 for (var i = 0; i < slices.length; i++) { | |
1238 if (i >= ls && i <= rs) { | |
1239 continue; | |
1240 } | |
1241 for (var j in slices[i].stacks ) { | |
1242 selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements); | |
1243 } | |
1244 } | |
1245 this.selection = new Selection(selectedObjects, this); | |
1246 this.filtering(); | |
1247 }, | |
1248 | |
1249 timeHighlight : function(undo) { | |
1250 if (this.status == 0) { | |
1251 var s = this.highlightedSlice; | |
1252 var timeObjects = []; | |
1253 for (var i = 0; i < this.tds.size(); i++) { | |
1254 timeObjects.push([]); | |
1255 } | |
1256 var add = true; | |
1257 if (this.leftFlagTime != null) { | |
1258 if (this.style == 'graph' && s.date >= this.leftFlagTime && s.date <= this.rightFlagTime) { | |
1259 add = false; | |
1260 } | |
1261 if (this.style == 'bars' && s.date >= this.leftFlagTime && s.date < this.rightFlagTime) { | |
1262 add = false; | |
1263 } | |
1264 } | |
1265 if (!undo && add) { | |
1266 for (var i in s.stacks ) { | |
1267 timeObjects[i] = timeObjects[i].concat(s.stacks[i].elements); | |
1268 } | |
1269 } | |
1270 this.core.triggerHighlight(timeObjects); | |
1271 } | |
1272 }, | |
1273 | |
1274 timeRefining : function() { | |
1275 this.core.triggerRefining(this.selection.objects); | |
1276 }, | |
1277 | |
1278 setStyle : function(style) { | |
1279 this.style = style; | |
1280 }, | |
1281 | |
1282 drawLinearPlot : function() { | |
1283 if ( typeof this.valueGeometry != 'undefined') { | |
1284 this.valueGeometry.actLinear(); | |
1285 this.timeplot.repaint(); | |
1286 this.resetOpacityPlots(); | |
1287 this.displayOverlay(); | |
1288 } | |
1289 }, | |
1290 | |
1291 drawLogarithmicPlot : function() { | |
1292 if ( typeof this.valueGeometry != 'undefined') { | |
1293 this.valueGeometry.actLogarithmic(); | |
1294 this.timeplot.repaint(); | |
1295 this.resetOpacityPlots(); | |
1296 this.displayOverlay(); | |
1297 } | |
1298 } | |
1299 } |