12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Use of this source code is governed by a BSD-style license that can be
32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// found in the LICENSE file.
42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis'use strict';
62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
72da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.requireStylesheet('tracks.timeline_counter_track');
82da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
92da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('tracks.timeline_canvas_based_track');
102da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('timeline_color_scheme');
112da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui');
122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
132da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.exportTo('tracks', function() {
142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  var palette = tracing.getColorPalette();
162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  /**
182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * A track that displays a TimelineCounter object.
192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * @constructor
202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * @extends {CanvasBasedTrack}
212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   */
222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  var TimelineCounterTrack = base.ui.define(tracks.TimelineCanvasBasedTrack);
242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  TimelineCounterTrack.prototype = {
262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    __proto__: tracks.TimelineCanvasBasedTrack.prototype,
282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    decorate: function() {
302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.classList.add('timeline-counter-track');
312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.addControlButtonElements_(false);
322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.selectedSamples_ = {};
332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.categoryFilter_ = new tracing.TimelineFilter();
342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    /**
372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * Called by all the addToSelection functions on the created selection
382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * hit objects. Override this function on parent classes to add
392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * context-specific information to the hit.
402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     */
412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    decorateHit: function(hit) {
422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    get counter() {
452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return this.counter_;
462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    set counter(counter) {
492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.counter_ = counter;
502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.invalidate();
512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.updateVisibility_();
522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    set categoryFilter(v) {
552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.categoryFilter_ = v;
562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.updateVisibility_();
572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    /**
602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @return {Object} A sparse, mutable map from sample index to bool. Samples
612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * indices the map that are true are drawn as selected. Callers that mutate
622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * the map must manually call invalidate on the track to trigger a redraw.
632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     */
642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    get selectedSamples() {
652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return this.selectedSamples_;
662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    updateVisibility_: function() {
692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.visible = (this.counter_ &&
702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                      this.categoryFilter_.matchCounter(this.counter_));
712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    redraw: function() {
742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var ctr = this.counter_;
752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var ctx = this.ctx_;
762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var canvasW = this.canvas_.width;
772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var canvasH = this.canvas_.height;
782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      ctx.clearRect(0, 0, canvasW, canvasH);
802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Culling parametrs.
822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var vp = this.viewport_;
832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var pixWidth = vp.xViewVectorToWorld(1);
842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var viewLWorld = vp.xViewToWorld(0);
852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var viewRWorld = vp.xViewToWorld(canvasW);
862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Give the viewport a chance to draw onto this canvas.
882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      vp.drawUnderContent(ctx, viewLWorld, viewRWorld, canvasH);
892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Drop sampels that are less than skipDistancePix apart.
912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var skipDistancePix = 1;
922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var skipDistanceWorld = vp.xViewVectorToWorld(skipDistancePix);
932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Begin rendering in world space.
952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      ctx.save();
962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      vp.applyTransformToCanvas(ctx);
972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Figure out where drawing should begin.
992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var numSeries = ctr.numSeries;
1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var numSamples = ctr.numSamples;
1012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var startIndex = tracing.findLowIndexInSortedArray(ctr.timestamps,
1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                         function(x) {
1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                           return x;
1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                         },
1052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                         viewLWorld);
1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      startIndex = startIndex - 1 > 0 ? startIndex - 1 : 0;
1072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Draw indices one by one until we fall off the viewRWorld.
1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var yScale = canvasH / ctr.maxTotal;
1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      for (var seriesIndex = ctr.numSeries - 1;
1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis           seriesIndex >= 0; seriesIndex--) {
1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var colorId = ctr.seriesColors[seriesIndex];
1132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        ctx.fillStyle = palette[colorId];
1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        ctx.beginPath();
1152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // Set iLast and xLast such that the first sample we draw is the
1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // startIndex sample.
1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var iLast = startIndex - 1;
1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var xLast = iLast >= 0 ? ctr.timestamps[iLast] - skipDistanceWorld : -1;
1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var yLastView = canvasH;
1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // Iterate over samples from iLast onward until we either fall off the
1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // viewRWorld or we run out of samples. To avoid drawing too much, after
1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // drawing a sample at xLast, skip subsequent samples that are less than
1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // skipDistanceWorld from xLast.
1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var hasMoved = false;
1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        while (true) {
1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          var i = iLast + 1;
1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          if (i >= numSamples) {
1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ctx.lineTo(xLast, yLastView);
1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ctx.lineTo(xLast + 8 * pixWidth, yLastView);
1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ctx.lineTo(xLast + 8 * pixWidth, canvasH);
1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            break;
1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          }
1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          var x = ctr.timestamps[i];
1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          var y = ctr.totals[i * numSeries + seriesIndex];
1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          var yView = canvasH - (yScale * y);
1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          if (x > viewRWorld) {
1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ctx.lineTo(x, yLastView);
1432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ctx.lineTo(x, canvasH);
1442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            break;
1452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          }
1462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          if (x - xLast < skipDistanceWorld) {
1482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            iLast = i;
1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            continue;
1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          }
1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          if (!hasMoved) {
1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            ctx.moveTo(viewLWorld, canvasH);
1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            hasMoved = true;
1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          }
1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          ctx.lineTo(x, yLastView);
1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          ctx.lineTo(x, yView);
1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          iLast = i;
1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          xLast = x;
1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          yLastView = yView;
1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        }
1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        ctx.closePath();
1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        ctx.fill();
1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      ctx.fillStyle = 'rgba(255, 0, 0, 1)';
1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      for (var i in this.selectedSamples_) {
1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        if (!this.selectedSamples_[i])
1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          continue;
1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var x = ctr.timestamps[i];
1712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        for (var seriesIndex = ctr.numSeries - 1;
1722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis             seriesIndex >= 0; seriesIndex--) {
1732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          var y = ctr.totals[i * numSeries + seriesIndex];
1742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          var yView = canvasH - (yScale * y);
1752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          ctx.fillRect(x - pixWidth, yView - 1, 3 * pixWidth, 3);
1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        }
1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      ctx.restore();
1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Give the viewport a chance to draw over this canvas.
1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      vp.drawOverContent(ctx, viewLWorld, viewRWorld, canvasH);
1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    /**
1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * Adds items intersecting a point to a selection.
1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {number} vX X location to search at, in viewspace.
1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {number} vY Y location to search at, in viewspace.
1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {TimelineSelection} selection Selection to which to add hits.
1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @return {boolean} true if a slice was found, otherwise false.
1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     */
1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    addIntersectingItemsToSelection: function(vX, vY, selection) {
1922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var clientRect = this.getBoundingClientRect();
1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (vY < clientRect.top || vY >= clientRect.bottom)
1942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return false;
1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var pixelRatio = window.devicePixelRatio || 1;
1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var wX = this.viewport_.xViewVectorToWorld(vX * devicePixelRatio);
1982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var ctr = this.counter_;
2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (vX < this.counter_.timestamps[0])
2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return false;
2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var i = tracing.findLowIndexInSortedArray(ctr.timestamps,
2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                function(x) { return x; },
2042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                wX);
2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (i < 0 || i >= ctr.timestamps.length)
2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return false;
2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Sample i is going to either be exactly at wX or slightly above it,
2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // E.g. asking for 7.5 in [7,8] gives i=1. So bump i back by 1 if needed.
2102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (i > 0 && wX > this.counter_.timestamps[i - 1])
2112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        i--;
2122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Some preliminaries.
2142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var canvasH = this.getBoundingClientRect().height;
2152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var yScale = canvasH / ctr.maxTotal;
2162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      /*
2182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Figure out which sample we hit
2192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var seriesIndexHit;
2202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      for (var seriesIndex = 0; seriesIndex < ctr.numSeries; seriesIndex++) {
2212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var y = ctr.totals[i * ctr.numSeries + seriesIndex];
2222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var yView = canvasH - (yScale * y) + clientRect.top;
2232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        if (wY >= yView) {
2242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          seriesIndexHit = seriesIndex;
2252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          break;
2262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        }
2272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
2282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (seriesIndexHit === undefined)
2292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return false;
2302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      */
2312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var hit = selection.addCounterSample(this, this.counter, i);
2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.decorateHit(hit);
2332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return true;
2342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    /**
2372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * Adds items intersecting the given range to a selection.
2382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {number} loVX Lower X bound of the interval to search, in
2392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     *     viewspace.
2402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {number} hiVX Upper X bound of the interval to search, in
2412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     *     viewspace.
2422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {number} loVY Lower Y bound of the interval to search, in
2432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     *     viewspace.
2442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {number} hiVY Upper Y bound of the interval to search, in
2452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     *     viewspace.
2462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @param {TimelineSelection} selection Selection to which to add hits.
2472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     */
2482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    addIntersectingItemsInRangeToSelection: function(
2492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        loVX, hiVX, loVY, hiVY, selection) {
2502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var clientRect = this.getBoundingClientRect();
2522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var a = Math.max(loVY, clientRect.top);
2532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var b = Math.min(hiVY, clientRect.bottom);
2542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (a > b)
2552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return;
2562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var ctr = this.counter_;
2582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var pixelRatio = window.devicePixelRatio || 1;
2602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var loWX = this.viewport_.xViewToWorld(loVX * pixelRatio);
2612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var hiWX = this.viewport_.xViewToWorld(hiVX * pixelRatio);
2622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var iLo = tracing.findLowIndexInSortedArray(ctr.timestamps,
2642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                  function(x) { return x; },
2652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                  loWX);
2662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var iHi = tracing.findLowIndexInSortedArray(ctr.timestamps,
2672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                  function(x) { return x; },
2682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                                  hiWX);
2692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Sample i is going to either be exactly at wX or slightly above it,
2712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // E.g. asking for 7.5 in [7,8] gives i=1. So bump i back by 1 if needed.
2722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (iLo > 0 && loWX > ctr.timestamps[iLo - 1])
2732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        iLo--;
2742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (iHi > 0 && hiWX > ctr.timestamps[iHi - 1])
2752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        iHi--;
2762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      // Iterate over every sample intersecting..
2782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      for (var i = iLo; i <= iHi; i++) {
2792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        if (i >= ctr.timestamps.length)
2802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          continue;
2812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        // TODO(nduca): Pick the seriesIndexHit based on the loY - hiY values.
2832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        var hit = selection.addCounterSample(this, this.counter, i);
2842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.decorateHit(hit);
2852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
2862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
2872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    addAllObjectsMatchingFilterToSelection: function(filter, selection) {
2892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    }
2902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  };
2912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  return {
2932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    TimelineCounterTrack: TimelineCounterTrack
2942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  };
2952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis});
296