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