Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3475)

Unified Diff: chrome/browser/resources/tracing/timeline.js

Issue 10161025: Allow about:tracing Counters to be selected (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixen. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/resources/tracing/tests.html ('k') | chrome/browser/resources/tracing/timeline_analysis.css » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/tracing/timeline.js
diff --git a/chrome/browser/resources/tracing/timeline.js b/chrome/browser/resources/tracing/timeline.js
index e38ec41671f64122dcf8e997cea21d0bb39454d8..da9a3ab2843a382b9567b5815414672962a1654d 100644
--- a/chrome/browser/resources/tracing/timeline.js
+++ b/chrome/browser/resources/tracing/timeline.js
@@ -232,6 +232,156 @@ cr.define('tracing', function() {
}
};
+ function TimelineSelectionSliceHit(track, slice) {
+ this.track = track;
+ this.slice = slice;
+ }
+ TimelineSelectionSliceHit.prototype = {
+ get selected() {
+ return this.slice.selected;
+ },
+ set selected(v) {
+ this.slice.selected = v;
+ }
+ };
+
+ function TimelineSelectionCounterSampleHit(track, counter, sampleIndex) {
+ this.track = track;
+ this.counter = counter;
+ this.sampleIndex = sampleIndex;
+ }
+ TimelineSelectionCounterSampleHit.prototype = {
+ get selected() {
+ return this.track.selectedSamples[this.sampleIndex] == true;
+ },
+ set selected(v) {
+ if (v)
+ this.track.selectedSamples[this.sampleIndex] = true;
+ else
+ this.track.selectedSamples[this.sampleIndex] = false;
+ this.track.invalidate();
+ }
+ };
+
+
+ /**
+ * Represents a selection within a Timeline and its associated set of tracks.
+ * @constructor
+ */
+ function TimelineSelection() {
+ this.range_dirty_ = true;
+ this.range_ = {};
+ this.length_ = 0;
+ }
+ TimelineSelection.prototype = {
+ __proto__: Object.prototype,
+
+ get range() {
+ if (this.range_dirty_) {
+ var wmin = Infinity;
+ var wmax = -wmin;
+ for (var i = 0; i < this.length_; i++) {
+ var hit = this[i];
+ if (hit.slice) {
+ wmin = Math.min(wmin, hit.slice.start);
+ wmax = Math.max(wmax, hit.slice.end);
+ }
+ }
+ this.range_ = {
+ min: wmin,
+ max: wmax
+ };
+ this.range_dirty_ = false;
+ }
+ return this.range_;
+ },
+
+ get duration() {
+ return this.range.max - this.range.min;
+ },
+
+ get length() {
+ return this.length_;
+ },
+
+ clear: function() {
+ for (var i = 0; i < this.length_; ++i)
+ delete this[i];
+ this.length_ = 0;
+ this.range_dirty_ = true;
+ },
+
+ push_: function(hit) {
+ this[this.length_++] = hit;
+ this.range_dirty_ = true;
+ return hit;
+ },
+
+ addSlice: function(track, slice) {
+ return this.push_(new TimelineSelectionSliceHit(track, slice));
+ },
+
+ addCounterSample: function(track, counter, sampleIndex) {
+ return this.push_(
+ new TimelineSelectionCounterSampleHit(
+ track, counter, sampleIndex));
+ },
+
+ subSelection: function(index, count) {
+ count = count || 1;
+
+ var selection = new TimelineSelection();
+ selection.range_dirty_ = true;
+ if (index < 0 || index + count > this.length_)
+ throw 'Index out of bounds';
+
+ for (var i = index; i < index + count; i++)
+ selection.push_(this[i]);
+
+ return selection;
+ },
+
+ getCounterSampleHits: function() {
+ var selection = new TimelineSelection();
+ for (var i = 0; i < this.length_; i++)
+ if (this[i] instanceof TimelineSelectionCounterSampleHit)
+ selection.push_(this[i]);
+ return selection;
+ },
+
+ getSliceHits: function() {
+ var selection = new TimelineSelection();
+ for (var i = 0; i < this.length_; i++)
+ if (this[i] instanceof TimelineSelectionSliceHit)
+ selection.push_(this[i]);
+ return selection;
+ },
+
+ map: function(fn) {
+ for (var i = 0; i < this.length_; i++)
+ fn(this[i]);
+ },
+
+ /**
+ * Helper for selection previous or next.
+ * @param {boolean} forwardp If true, select one forward (next).
+ * Else, select previous.
+ * @return {boolean} true if current selection changed.
+ */
+ getShiftedSelection: function(offset) {
+ var newSelection = new TimelineSelection();
+ for (var i = 0; i < this.length_; i++) {
+ var hit = this[i];
+ hit.track.addItemNearToProvidedHitToSelection(
+ hit, offset, newSelection);
+ }
+
+ if (newSelection.length == 0)
+ return undefined;
+ return newSelection;
+ },
+ };
+
/**
* Renders a TimelineModel into a div element, making one
* TimelineTrack for each subrow in each thread of the model, managing
@@ -270,7 +420,7 @@ cr.define('tracing', function() {
this.lastMouseViewPos_ = {x: 0, y: 0};
- this.selection_ = [];
+ this.selection_ = new TimelineSelection();
},
/**
@@ -430,17 +580,15 @@ cr.define('tracing', function() {
},
/**
+ * @param {TimelineFilter} filter The filter to use for finding matches.
+ * @param {TimelineSelection} selection The selection to add matches to.
* @return {Array} An array of objects that match the provided
* TimelineFilter.
*/
- findAllObjectsMatchingFilter: function(filter) {
- var hits = [];
- for (var i = 0; i < this.tracks_.children.length; ++i) {
- var trackHits =
- this.tracks_.children[i].findAllObjectsMatchingFilter(filter);
- Array.prototype.push.apply(hits, trackHits);
- }
- return hits;
+ addAllObjectsMatchingFilterToSelection: function(filter, selection) {
+ for (var i = 0; i < this.tracks_.children.length; ++i)
+ this.tracks_.children[i].addAllObjectsMatchingFilterToSelection(
+ filter, selection);
},
/**
@@ -526,12 +674,21 @@ cr.define('tracing', function() {
onKeydown_: function(e) {
if (!this.listenToKeys_)
return;
+ var sel;
switch (e.keyCode) {
case 37: // left arrow
- this.selectPrevious_(e);
+ sel = this.selection.getShiftedSelection(-1);
+ if (sel) {
+ this.setSelectionAndMakeVisible(sel);
+ e.preventDefault();
+ }
break;
case 39: // right arrow
- this.selectNext_(e);
+ sel = this.selection.getShiftedSelection(1);
+ if (sel) {
+ this.setSelectionAndMakeVisible(sel);
+ e.preventDefault();
+ }
break;
case 9: // TAB
if (this.focusElement.tabIndex == -1) {
@@ -560,60 +717,6 @@ cr.define('tracing', function() {
vp.xPanWorldPosToViewPos(curCenterW, curMouseV, viewWidth);
},
- /** Select the next slice on the timeline. Applies to each track. */
- selectNext_: function(e) {
- if (this.selectAdjoining_(true))
- e.preventDefault();
- },
-
- /** Select the previous slice on the timeline. Applies to each track. */
- selectPrevious_: function(e) {
- if (this.selectAdjoining_(false))
- e.preventDefault();
- },
-
- /**
- * Helper for selection previous or next.
- * @param {boolean} forwardp If true, select one forward (next).
- * Else, select previous.
- * @return {boolean} true if current selection changed.
- */
- selectAdjoining_: function(forwardp) {
- var i, track, slice, adjoining;
- var selection = [];
- var minTime = Number.MAX_VALUE;
- var maxTime = -Number.MAX_VALUE;
- // Try and select next.
- for (i = 0; i < this.selection_.length; i++) {
- adjoining = undefined;
- track = this.selection_[i].track;
- slice = this.selection_[i].slice;
- if (slice) {
- if (forwardp)
- adjoining = track.pickNext(slice);
- else
- adjoining = track.pickPrevious(slice);
- }
- if (adjoining != undefined) {
- selection.push({track: track, slice: adjoining});
- if (slice.start < minTime)
- minTime = slice.start;
- if (slice.start + slice.duration > maxTime)
- maxTime = slice.start + slice.duration;
- }
- }
- if (selection.length == 0) {
- // Nothing adjoining was found; leave the current selection.
- return false;
- }
- this.selection = selection;
-
- // Potentially move the viewport to keep the new selection in view.
- this.viewport_.xPanWorldRangeIntoView(minTime, maxTime,
- this.firstCanvas.width);
- return true;
- },
-
get keyHelp() {
var help = 'Keyboard shortcuts:\n' +
' w/s : Zoom in/out (with shift: go faster)\n' +
@@ -639,38 +742,27 @@ cr.define('tracing', function() {
},
set selection(selection) {
+ if (!(selection instanceof TimelineSelection))
+ throw 'Expected TimelineSelection';
+
// Clear old selection.
var i;
for (i = 0; i < this.selection_.length; i++)
- this.selection_[i].slice.selected = false;
+ this.selection_[i].selected = false;
this.selection_ = selection;
cr.dispatchSimpleEvent(this, 'selectionChange');
for (i = 0; i < this.selection_.length; i++)
- this.selection_[i].slice.selected = true;
+ this.selection_[i].selected = true;
this.viewport_.dispatchChangeEvent(); // Triggers a redraw.
},
- getSelectionRange: function() {
- var wmin = Infinity;
- var wmax = -wmin;
- for (var i = 0; i < this.selection_.length; i++) {
- var hit = this.selection_[i];
- if (hit.slice) {
- wmin = Math.min(wmin, hit.slice.start);
- wmax = Math.max(wmax, hit.slice.end);
- }
- }
- return {
- min: wmin,
- max: wmax
- };
- },
-
setSelectionAndMakeVisible: function(selection, zoomAllowed) {
+ if (!(selection instanceof TimelineSelection))
+ throw 'Expected TimelineSelection';
this.selection = selection;
- var range = this.getSelectionRange();
+ var range = this.selection.range;
var size = this.viewport_.xWorldVectorToView(range.max - range.min);
if (zoomAllowed && size < 50) {
var worldCenter = range.min + (range.max - range.min) * 0.5;
@@ -724,11 +816,9 @@ cr.define('tracing', function() {
onGridToggle_: function(left) {
var tb;
if (left)
- tb = Math.min.apply(Math, this.selection_.map(
- function(x) { return x.slice.start; }));
+ tb = this.selection_.range.min;
else
- tb = Math.max.apply(Math, this.selection_.map(
- function(x) { return x.slice.end; }));
+ tb = this.selection_.range.max;
// Shift the timebase left until its just left of minTimestamp.
var numInterfvalsSinceStart = Math.ceil((tb - this.model_.minTimestamp) /
@@ -801,25 +891,21 @@ cr.define('tracing', function() {
var hiWX = this.viewport_.xViewToWorld(hiX - canv.offsetLeft);
// Figure out what has been hit.
- (function() {
- var selection = [];
- function addHit(type, track, slice) {
- selection.push({track: track, slice: slice});
+ var selection = new TimelineSelection();
+ for (i = 0; i < this.tracks_.children.length; i++) {
+ var track = this.tracks_.children[i];
+
+ // Only check tracks that insersect the rect.
+ var trackClientRect = track.getBoundingClientRect();
+ var a = Math.max(loY, trackClientRect.top);
+ var b = Math.min(hiY, trackClientRect.bottom);
+ if (a <= b) {
+ track.addIntersectingItemsInRangeToSelection(
+ loWX, hiWX, loY, hiY, selection);
}
- for (i = 0; i < this.tracks_.children.length; i++) {
- var track = this.tracks_.children[i];
-
- // Only check tracks that insersect the rect.
- var trackClientRect = track.getBoundingClientRect();
- var a = Math.max(loY, trackClientRect.top);
- var b = Math.min(hiY, trackClientRect.bottom);
- if (a <= b) {
- track.pickRange(loWX, hiWX, loY, hiY, addHit);
- }
- }
- // Activate the new selection.
- this.selection = selection;
- }).call(this);
+ }
+ // Activate the new selection.
+ this.selection = selection;
}
},
@@ -844,6 +930,9 @@ cr.define('tracing', function() {
return {
Timeline: Timeline,
+ TimelineSelectionSliceHit: TimelineSelectionSliceHit,
+ TimelineSelectionCounterSampleHit: TimelineSelectionCounterSampleHit,
+ TimelineSelection: TimelineSelection,
TimelineViewport: TimelineViewport
};
});
« no previous file with comments | « chrome/browser/resources/tracing/tests.html ('k') | chrome/browser/resources/tracing/timeline_analysis.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698