1var DEFAULT_RESOLUTION = 5; 2 3Heatmap.prototype.installInputHandlers = function(canvas, resolutionSlider) { 4 var self = this; 5 6 canvas.mousemove(function(event) { 7 var mouseX = event.pageX - canvas.position().left; 8 var mouseY = event.pageY - canvas.position().top; 9 self.draw(); 10 var traces = self.findTracesAt(mouseX, mouseY); 11 for (var i = 0; i < traces.length; ++i) 12 self.drawTrace(traces[i], 0.5); 13 }); 14 15 canvas.click(function(event) { 16 var mouseX = event.pageX - canvas.position().left; 17 var mouseY = event.pageY - canvas.position().top; 18 var traces = self.findTracesAt(mouseX, mouseY); 19 for (var i = 0; i < traces.length; ++i) 20 self.selectTrace(traces[i]); 21 self.draw(); 22 }); 23 24 resolutionSlider.val(DEFAULT_RESOLUTION); 25 resolutionSlider.change(function() { 26 self.resolution = self.h / this.value; 27 self.calculateHeatmap(); 28 self.draw(); 29 }); 30 resolutionSlider.change(); 31}; 32 33Heatmap.prototype.selectTrace = function(trace) { 34 this.drawTraces[trace] = !this.drawTraces[trace]; 35}; 36 37Heatmap.prototype.getTime = function(x) { 38 var time = Math.floor(mapRange(x, 0, this.w, 0, this.revisions.length)); 39 return constrain(time, 0, this.revisions.length - 1); 40}; 41 42Heatmap.prototype.getBucket = function(y) { 43 var bucket = Math.floor(mapRange(y, this.h, 0, 0, this.resolution)); 44 return constrain(bucket, 0, this.resolution - 1); 45}; 46 47Heatmap.prototype.findTracesAt = function(x, y) { 48 var minX = x - 5, minY = y + 5; 49 var maxX = x + 5, maxY = y - 5; 50 51 var minTime = this.getTime(minX), minY = this.getBucket(minY); 52 var maxTime = this.getTime(maxX), maxY = this.getBucket(maxY); 53 54 var traces = {}; // Use an object to avoid duplicates. 55 for (var time = minTime; time <= maxTime; ++time) { 56 for (var bucket = minY; bucket <= maxY; ++bucket) { 57 var revision = this.revisions[time]; 58 if (!this.data[revision]) 59 continue; 60 if (!this.data[revision][bucket]) 61 continue; 62 63 for (var i = 0; i < this.data[revision][bucket].length; ++i) 64 traces[this.data[revision][bucket][i]] = true; 65 } 66 } 67 68 return Object.keys(traces); 69}; 70