| var DEFAULT_RESOLUTION = 5; |
| |
| Heatmap.prototype.installInputHandlers = function(canvas, resolutionSlider) { |
| var self = this; |
| |
| canvas.mousemove(function(event) { |
| var mouseX = event.pageX - canvas.position().left; |
| var mouseY = event.pageY - canvas.position().top; |
| self.draw(); |
| var traces = self.findTracesAt(mouseX, mouseY); |
| for (var i = 0; i < traces.length; ++i) |
| self.drawTrace(traces[i], 0.5); |
| }); |
| |
| canvas.click(function(event) { |
| var mouseX = event.pageX - canvas.position().left; |
| var mouseY = event.pageY - canvas.position().top; |
| var traces = self.findTracesAt(mouseX, mouseY); |
| for (var i = 0; i < traces.length; ++i) |
| self.selectTrace(traces[i]); |
| self.draw(); |
| }); |
| |
| resolutionSlider.val(DEFAULT_RESOLUTION); |
| resolutionSlider.change(function() { |
| self.resolution = self.h / this.value; |
| self.calculateHeatmap(); |
| self.draw(); |
| }); |
| resolutionSlider.change(); |
| }; |
| |
| Heatmap.prototype.selectTrace = function(trace) { |
| this.drawTraces[trace] = !this.drawTraces[trace]; |
| }; |
| |
| Heatmap.prototype.getTime = function(x) { |
| var time = Math.floor(mapRange(x, 0, this.w, 0, this.revisions.length)); |
| return constrain(time, 0, this.revisions.length - 1); |
| }; |
| |
| Heatmap.prototype.getBucket = function(y) { |
| var bucket = Math.floor(mapRange(y, this.h, 0, 0, this.resolution)); |
| return constrain(bucket, 0, this.resolution - 1); |
| }; |
| |
| Heatmap.prototype.findTracesAt = function(x, y) { |
| var minX = x - 5, minY = y + 5; |
| var maxX = x + 5, maxY = y - 5; |
| |
| var minTime = this.getTime(minX), minY = this.getBucket(minY); |
| var maxTime = this.getTime(maxX), maxY = this.getBucket(maxY); |
| |
| var traces = {}; // Use an object to avoid duplicates. |
| for (var time = minTime; time <= maxTime; ++time) { |
| for (var bucket = minY; bucket <= maxY; ++bucket) { |
| var revision = this.revisions[time]; |
| if (!this.data[revision]) |
| continue; |
| if (!this.data[revision][bucket]) |
| continue; |
| |
| for (var i = 0; i < this.data[revision][bucket].length; ++i) |
| traces[this.data[revision][bucket][i]] = true; |
| } |
| } |
| |
| return Object.keys(traces); |
| }; |