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

Side by Side Diff: chrome/browser/resources/tracing/timeline_track.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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 /** 6 /**
7 * @fileoverview Renders an array of slices into the provided div, 7 * @fileoverview Renders an array of slices into the provided div,
8 * using a child canvas element. Uses a FastRectRenderer to draw only 8 * using a child canvas element. Uses a FastRectRenderer to draw only
9 * the visible slices. 9 * the visible slices.
10 */ 10 */
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 this.updateChildTracks_(); 63 this.updateChildTracks_();
64 }, 64 },
65 65
66 get firstCanvas() { 66 get firstCanvas() {
67 if (this.tracks_.length) 67 if (this.tracks_.length)
68 return this.tracks_[0].firstCanvas; 68 return this.tracks_[0].firstCanvas;
69 return undefined; 69 return undefined;
70 }, 70 },
71 71
72 /** 72 /**
73 * Picks a slice, if any, at a given location. 73 * Adds items intersecting a point to a selection.
74 * @param {number} wX X location to search at, in worldspace. 74 * @param {number} wX X location to search at, in worldspace.
75 * @param {number} wY Y location to search at, in offset space. 75 * @param {number} wY Y location to search at, in offset space.
76 * offset space. 76 * offset space.
77 * @param {function():*} onHitCallback Callback to call with the slice, 77 * @param {TimelineSelection} selection Selection to which to add hits.
78 * if one is found.
79 * @return {boolean} true if a slice was found, otherwise false. 78 * @return {boolean} true if a slice was found, otherwise false.
80 */ 79 */
81 pick: function(wX, wY, onHitCallback) { 80 addIntersectingItemsToSelection: function(wX, wY, selection) {
82 for (var i = 0; i < this.tracks_.length; i++) { 81 for (var i = 0; i < this.tracks_.length; i++) {
83 var trackClientRect = this.tracks_[i].getBoundingClientRect(); 82 var trackClientRect = this.tracks_[i].getBoundingClientRect();
84 if (wY >= trackClientRect.top && wY < trackClientRect.bottom) 83 if (wY >= trackClientRect.top && wY < trackClientRect.bottom)
85 return this.tracks_[i].pick(wX, onHitCallback); 84 this.tracks_[i].addIntersectingItemsToSelection(wX, wY, selection);
86 } 85 }
87 return false; 86 return false;
88 }, 87 },
89 88
90 /** 89 /**
91 * Finds slices intersecting the given interval. 90 * Adds items intersecting the given range to a selection.
92 * @param {number} loWX Lower X bound of the interval to search, in 91 * @param {number} loWX Lower X bound of the interval to search, in
93 * worldspace. 92 * worldspace.
94 * @param {number} hiWX Upper X bound of the interval to search, in 93 * @param {number} hiWX Upper X bound of the interval to search, in
95 * worldspace. 94 * worldspace.
96 * @param {number} loY Lower Y bound of the interval to search, in 95 * @param {number} loY Lower Y bound of the interval to search, in
97 * offset space. 96 * offset space.
98 * @param {number} hiY Upper Y bound of the interval to search, in 97 * @param {number} hiY Upper Y bound of the interval to search, in
99 * offset space. 98 * offset space.
100 * @param {function():*} onHitCallback Function to call for each slice 99 * @param {TimelineSelection} selection Selection to which to add hits.
101 * intersecting the interval.
102 */ 100 */
103 pickRange: function(loWX, hiWX, loY, hiY, onHitCallback) { 101 addIntersectingItemsInRangeToSelection: function(
102 loWX, hiWX, loY, hiY, selection) {
104 for (var i = 0; i < this.tracks_.length; i++) { 103 for (var i = 0; i < this.tracks_.length; i++) {
105 var trackClientRect = this.tracks_[i].getBoundingClientRect(); 104 var trackClientRect = this.tracks_[i].getBoundingClientRect();
106 var a = Math.max(loY, trackClientRect.top); 105 var a = Math.max(loY, trackClientRect.top);
107 var b = Math.min(hiY, trackClientRect.bottom); 106 var b = Math.min(hiY, trackClientRect.bottom);
108 if (a <= b) 107 if (a <= b)
109 this.tracks_[i].pickRange(loWX, hiWX, loY, hiY, onHitCallback); 108 this.tracks_[i].addIntersectingItemsInRangeToSelection(
109 loWX, hiWX, loY, hiY, selection);
110 } 110 }
111 }, 111 },
112 112
113 /** 113 addAllObjectsMatchingFilterToSelection: function(filter, selection) {
114 * @return {Array} Objects matching the given filter. 114 for (var i = 0; i < this.tracks_.length; i++)
115 */ 115 this.tracks_[i].addAllObjectsMatchingFilterToSelection(
116 findAllObjectsMatchingFilter: function(filter) { 116 filter, selection);
117 var hits = [];
118 for (var i = 0; i < this.tracks_.length; i++) {
119 var trackHits = this.tracks_[i].findAllObjectsMatchingFilter(filter);
120 Array.prototype.push.apply(hits, trackHits);
121 }
122 return hits;
123 } 117 }
124 }; 118 };
125 119
126 function addControlButtonElements(el, canCollapse) { 120 function addControlButtonElements(el, canCollapse) {
127 var closeEl = document.createElement('div'); 121 var closeEl = document.createElement('div');
128 closeEl.classList.add('timeline-track-button'); 122 closeEl.classList.add('timeline-track-button');
129 closeEl.classList.add('timeline-track-close-button'); 123 closeEl.classList.add('timeline-track-close-button');
130 closeEl.textContent = String.fromCharCode(215); // &times; 124 closeEl.textContent = String.fromCharCode(215); // &times;
131 closeEl.addEventListener('click', function() { 125 closeEl.addEventListener('click', function() {
132 el.style.display = 'None'; 126 el.style.display = 'None';
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 }, 205 },
212 206
213 updateChildTracks_: function() { 207 updateChildTracks_: function() {
214 this.detach(); 208 this.detach();
215 this.textContent = ''; 209 this.textContent = '';
216 this.tracks_ = []; 210 this.tracks_ = [];
217 if (this.thread_) { 211 if (this.thread_) {
218 if (this.thread_.cpuSlices) { 212 if (this.thread_.cpuSlices) {
219 var track = this.addTrack_(this.thread_.cpuSlices); 213 var track = this.addTrack_(this.thread_.cpuSlices);
220 track.height = '4px'; 214 track.height = '4px';
215 track.decorateHit = function(hit) {
216 hit.thread = this.thread_;
217 }
221 } 218 }
222 219
223 if (this.thread_.asyncSlices.length) { 220 if (this.thread_.asyncSlices.length) {
224 var subRows = this.thread_.asyncSlices.subRows; 221 var subRows = this.thread_.asyncSlices.subRows;
225 for (var srI = 0; srI < subRows.length; srI++) { 222 for (var srI = 0; srI < subRows.length; srI++) {
226 var track = this.addTrack_(subRows[srI]); 223 var track = this.addTrack_(subRows[srI]);
224 track.decorateHit = function(hit) {
225 // TODO(simonjam): figure out how to associate subSlice hits back
226 // to their parent slice.
227 }
227 track.asyncStyle = true; 228 track.asyncStyle = true;
228 } 229 }
229 } 230 }
230 231
231 for (var srI = 0; srI < this.thread_.subRows.length; srI++) { 232 for (var srI = 0; srI < this.thread_.subRows.length; srI++) {
232 this.addTrack_(this.thread_.subRows[srI]); 233 var track = this.addTrack_(this.thread_.subRows[srI]);
234 track.decorateHit = function(hit) {
235 hit.thread = this.thread_;
236 }
233 } 237 }
234 238
235 if (this.tracks_.length > 0) { 239 if (this.tracks_.length > 0) {
236 if (this.thread_.cpuSlices) { 240 if (this.thread_.cpuSlices) {
237 this.tracks_[1].heading = this.heading_; 241 this.tracks_[1].heading = this.heading_;
238 this.tracks_[1].tooltip = this.tooltip_; 242 this.tracks_[1].tooltip = this.tooltip_;
239 } else { 243 } else {
240 this.tracks_[0].heading = this.heading_; 244 this.tracks_[0].heading = this.heading_;
241 this.tracks_[0].tooltip = this.tooltip_; 245 this.tracks_[0].tooltip = this.tooltip_;
242 } 246 }
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 * @const 517 * @const
514 */ 518 */
515 SHOULD_ELIDE_TEXT: true, 519 SHOULD_ELIDE_TEXT: true,
516 520
517 decorate: function() { 521 decorate: function() {
518 this.classList.add('timeline-slice-track'); 522 this.classList.add('timeline-slice-track');
519 this.elidedTitleCache = new ElidedTitleCache(); 523 this.elidedTitleCache = new ElidedTitleCache();
520 this.asyncStyle_ = false; 524 this.asyncStyle_ = false;
521 }, 525 },
522 526
527 /**
528 * Called by all the addToSelection functions on the created selection
529 * hit objects. Override this function on parent classes to add
530 * context-specific information to the hit.
531 */
532 decorateHit: function(hit) {
533 },
534
523 get asyncStyle() { 535 get asyncStyle() {
524 return this.asyncStyle_; 536 return this.asyncStyle_;
525 }, 537 },
526 538
527 set asyncStyle(v) { 539 set asyncStyle(v) {
528 this.asyncStyle_ = !!v; 540 this.asyncStyle_ = !!v;
529 this.invalidate(); 541 this.invalidate();
530 }, 542 },
531 543
532 get slices() { 544 get slices() {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 if (drawnWidth * pixWidth < slice.duration) { 673 if (drawnWidth * pixWidth < slice.duration) {
662 var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration); 674 var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration);
663 ctx.fillText(drawnTitle, cX, 2.5, drawnWidth); 675 ctx.fillText(drawnTitle, cX, 2.5, drawnWidth);
664 } 676 }
665 } 677 }
666 } 678 }
667 } 679 }
668 }, 680 },
669 681
670 /** 682 /**
671 * Picks a slice, if any, at a given location. 683 * Finds slices intersecting the given interval.
672 * @param {number} wX X location to search at, in worldspace. 684 * @param {number} wX X location to search at, in worldspace.
673 * @param {number} wY Y location to search at, in offset space. 685 * @param {number} wY Y location to search at, in offset space.
674 * offset space. 686 * offset space.
675 * @param {function():*} onHitCallback Callback to call with the slice, 687 * @param {TimelineSelection} selection Selection to which to add hits.
676 * if one is found.
677 * @return {boolean} true if a slice was found, otherwise false. 688 * @return {boolean} true if a slice was found, otherwise false.
678 */ 689 */
679 pick: function(wX, wY, onHitCallback) { 690 addIntersectingItemsToSelection: function(wX, wY, selection) {
680 var clientRect = this.getBoundingClientRect(); 691 var clientRect = this.getBoundingClientRect();
681 if (wY < clientRect.top || wY >= clientRect.bottom) 692 if (wY < clientRect.top || wY >= clientRect.bottom)
682 return false; 693 return false;
683 var x = tracing.findLowIndexInSortedIntervals(this.slices_, 694 var x = tracing.findLowIndexInSortedIntervals(this.slices_,
684 function(x) { return x.start; }, 695 function(x) { return x.start; },
685 function(x) { return x.duration; }, 696 function(x) { return x.duration; },
686 wX); 697 wX);
687 if (x >= 0 && x < this.slices_.length) { 698 if (x >= 0 && x < this.slices_.length) {
688 onHitCallback('slice', this, this.slices_[x]); 699 var hit = selection.addSlice(this, this.slices_[x]);
700 this.decorateHit(hit);
689 return true; 701 return true;
690 } 702 }
691 return false; 703 return false;
692 }, 704 },
693 705
694 /** 706 /**
695 * Finds slices intersecting the given interval. 707 * Adds items intersecting the given range to a selection.
696 * @param {number} loWX Lower X bound of the interval to search, in 708 * @param {number} loWX Lower X bound of the interval to search, in
697 * worldspace. 709 * worldspace.
698 * @param {number} hiWX Upper X bound of the interval to search, in 710 * @param {number} hiWX Upper X bound of the interval to search, in
699 * worldspace. 711 * worldspace.
700 * @param {number} loY Lower Y bound of the interval to search, in 712 * @param {number} loY Lower Y bound of the interval to search, in
701 * offset space. 713 * offset space.
702 * @param {number} hiY Upper Y bound of the interval to search, in 714 * @param {number} hiY Upper Y bound of the interval to search, in
703 * offset space. 715 * offset space.
704 * @param {function():*} onHitCallback Function to call for each slice 716 * @param {TimelineSelection} selection Selection to which to add hits.
705 * intersecting the interval.
706 */ 717 */
707 pickRange: function(loWX, hiWX, loY, hiY, onHitCallback) { 718 addIntersectingItemsInRangeToSelection: function(
719 loWX, hiWX, loY, hiY, selection) {
708 var clientRect = this.getBoundingClientRect(); 720 var clientRect = this.getBoundingClientRect();
709 var a = Math.max(loY, clientRect.top); 721 var a = Math.max(loY, clientRect.top);
710 var b = Math.min(hiY, clientRect.bottom); 722 var b = Math.min(hiY, clientRect.bottom);
711 if (a > b) 723 if (a > b)
712 return; 724 return;
713 725
714 var that = this; 726 var that = this;
715 function onPickHit(slice) { 727 function onPickHit(slice) {
716 onHitCallback('slice', that, slice); 728 var hit = selection.addSlice(that, slice);
729 that.decorateHit(hit);
717 } 730 }
718 tracing.iterateOverIntersectingIntervals(this.slices_, 731 tracing.iterateOverIntersectingIntervals(this.slices_,
719 function(x) { return x.start; }, 732 function(x) { return x.start; },
720 function(x) { return x.duration; }, 733 function(x) { return x.duration; },
721 loWX, hiWX, 734 loWX, hiWX,
722 onPickHit); 735 onPickHit);
723 }, 736 },
724 737
725 /** 738 /**
726 * Find the index for the given slice. 739 * Find the index for the given slice.
727 * @return {index} Index of the given slice, or undefined. 740 * @return {index} Index of the given slice, or undefined.
728 * @private 741 * @private
729 */ 742 */
730 indexOfSlice_: function(slice) { 743 indexOfSlice_: function(slice) {
731 var index = tracing.findLowIndexInSortedArray(this.slices_, 744 var index = tracing.findLowIndexInSortedArray(this.slices_,
732 function(x) { return x.start; }, 745 function(x) { return x.start; },
733 slice.start); 746 slice.start);
734 while (index < this.slices_.length && 747 while (index < this.slices_.length &&
735 slice.start == this.slices_[index].start && 748 slice.start == this.slices_[index].start &&
736 slice.colorId != this.slices_[index].colorId) { 749 slice.colorId != this.slices_[index].colorId) {
737 index++; 750 index++;
738 } 751 }
739 return index < this.slices_.length ? index : undefined; 752 return index < this.slices_.length ? index : undefined;
740 }, 753 },
741 754
742 /** 755 /**
743 * Return the next slice, if any, after the given slice. 756 * Add the item to the left or right of the provided hit, if any, to the
744 * @param {slice} The previous slice. 757 * selection.
745 * @return {slice} The next slice, or undefined. 758 * @param {slice} The current slice.
759 * @param {Number} offset Number of slices away from the hit to look.
760 * @param {TimelineSelection} selection The selection to add a hit to,
761 * if found.
762 * @return {boolean} Whether a hit was found.
746 * @private 763 * @private
747 */ 764 */
748 pickNext: function(slice) { 765 addItemNearToProvidedHitToSelection: function(hit, offset, selection) {
749 var index = this.indexOfSlice_(slice); 766 if (!hit.slice)
750 if (index != undefined) { 767 return false;
751 if (index < this.slices_.length - 1) 768
752 index++; 769 var index = this.indexOfSlice_(hit.slice);
753 else 770 if (index === undefined)
754 index = undefined; 771 return false;
755 } 772
756 return index != undefined ? this.slices_[index] : undefined; 773 var newIndex = index + offset;
774 if (newIndex < 0 || newIndex >= this.slices_.length)
775 return false;
776
777 var hit = selection.addSlice(this, this.slices_[newIndex]);
778 this.decorateHit(hit);
779 return true;
757 }, 780 },
758 781
759 /** 782 addAllObjectsMatchingFilterToSelection: function(filter, selection) {
760 * Return the previous slice, if any, before the given slice. 783 for (var i = 0; i < this.slices_.length; ++i) {
761 * @param {slice} A slice. 784 if (filter.matchSlice(this.slices_[i])) {
762 * @return {slice} The previous slice, or undefined. 785 var hit = selection.addSlice(this, this.slices_[i]);
763 */ 786 this.decorateHit(hit);
764 pickPrevious: function(slice) { 787 }
765 var index = this.indexOfSlice_(slice); 788 }
766 if (index == 0)
767 return undefined;
768 else if ((index != undefined) && (index > 0))
769 index--;
770 return index != undefined ? this.slices_[index] : undefined;
771 },
772
773 findAllObjectsMatchingFilter: function(filter) {
774 var hits = [];
775 for (var i = 0; i < this.slices_.length; ++i)
776 if (filter.matchSlice(this.slices_[i]))
777 hits.push({track: this,
778 slice: this.slices_[i]});
779 return hits;
780 } 789 }
781 }; 790 };
782 791
783 /** 792 /**
784 * A track that displays the viewport size and scale. 793 * A track that displays the viewport size and scale.
785 * @constructor 794 * @constructor
786 * @extends {CanvasBasedTrack} 795 * @extends {CanvasBasedTrack}
787 */ 796 */
788 797
789 var TimelineViewportTrack = cr.ui.define(CanvasBasedTrack); 798 var TimelineViewportTrack = cr.ui.define(CanvasBasedTrack);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 var xView = Math.floor(curXView + minorMarkDistancePx * i); 898 var xView = Math.floor(curXView + minorMarkDistancePx * i);
890 ctx.moveTo(xView, canvasH - minorTickH); 899 ctx.moveTo(xView, canvasH - minorTickH);
891 ctx.lineTo(xView, canvasH); 900 ctx.lineTo(xView, canvasH);
892 } 901 }
893 902
894 ctx.stroke(); 903 ctx.stroke();
895 } 904 }
896 }, 905 },
897 906
898 /** 907 /**
899 * Picks a slice, if any, at a given location. 908 * Adds items intersecting a point to a selection.
900 * @param {number} wX X location to search at, in worldspace. 909 * @param {number} wX X location to search at, in worldspace.
901 * @param {number} wY Y location to search at, in offset space. 910 * @param {number} wY Y location to search at, in offset space.
902 * offset space. 911 * offset space.
903 * @param {function():*} onHitCallback Callback to call with the slice, 912 * @param {TimelineSelection} selection Selection to which to add hits.
904 * if one is found.
905 * @return {boolean} true if a slice was found, otherwise false. 913 * @return {boolean} true if a slice was found, otherwise false.
906 */ 914 */
907 pick: function(wX, wY, onHitCallback) { 915 addIntersectingItemsToSelection: function(wX, wY, selection) {
908 // Does nothing. There's nothing interesting to pick on the viewport 916 // Does nothing. There's nothing interesting to pick on the viewport
909 // track. 917 // track.
910 }, 918 },
911 919
912 /** 920 /**
913 * Finds slices intersecting the given interval. 921 * Adds items intersecting the given range to a selection.
914 * @param {number} loWX Lower X bound of the interval to search, in 922 * @param {number} loWX Lower X bound of the interval to search, in
915 * worldspace. 923 * worldspace.
916 * @param {number} hiWX Upper X bound of the interval to search, in 924 * @param {number} hiWX Upper X bound of the interval to search, in
917 * worldspace. 925 * worldspace.
918 * @param {number} loY Lower Y bound of the interval to search, in 926 * @param {number} loY Lower Y bound of the interval to search, in
919 * offset space. 927 * offset space.
920 * @param {number} hiY Upper Y bound of the interval to search, in 928 * @param {number} hiY Upper Y bound of the interval to search, in
921 * offset space. 929 * offset space.
922 * @param {function():*} onHitCallback Function to call for each slice 930 * @param {TimelineSelection} selection Selection to which to add hits.
923 * intersecting the interval.
924 */ 931 */
925 pickRange: function(loWX, hiWX, loY, hiY, onHitCallback) { 932 addIntersectingItemsInRangeToSelection: function(
933 loWX, hiWX, loY, hiY, selection) {
926 // Does nothing. There's nothing interesting to pick on the viewport 934 // Does nothing. There's nothing interesting to pick on the viewport
927 // track. 935 // track.
928 }, 936 },
929 937
930 findAllObjectsMatchingFilter: function(filter) { 938 addAllObjectsMatchingFilterToSelection: function(filter, selection) {
931 return [];
932 } 939 }
933 940
934 }; 941 };
935 942
936 /** 943 /**
937 * A track that displays a TimelineCounter object. 944 * A track that displays a TimelineCounter object.
938 * @constructor 945 * @constructor
939 * @extends {CanvasBasedTrack} 946 * @extends {CanvasBasedTrack}
940 */ 947 */
941 948
942 var TimelineCounterTrack = cr.ui.define(CanvasBasedTrack); 949 var TimelineCounterTrack = cr.ui.define(CanvasBasedTrack);
943 950
944 TimelineCounterTrack.prototype = { 951 TimelineCounterTrack.prototype = {
945 952
946 __proto__: CanvasBasedTrack.prototype, 953 __proto__: CanvasBasedTrack.prototype,
947 954
948 decorate: function() { 955 decorate: function() {
949 this.classList.add('timeline-counter-track'); 956 this.classList.add('timeline-counter-track');
950 addControlButtonElements(this, false); 957 addControlButtonElements(this, false);
958 this.selectedSamples_ = {};
959 },
960
961 /**
962 * Called by all the addToSelection functions on the created selection
963 * hit objects. Override this function on parent classes to add
964 * context-specific information to the hit.
965 */
966 decorateHit: function(hit) {
951 }, 967 },
952 968
953 get counter() { 969 get counter() {
954 return this.counter_; 970 return this.counter_;
955 }, 971 },
956 972
957 set counter(counter) { 973 set counter(counter) {
958 this.counter_ = counter; 974 this.counter_ = counter;
959 this.invalidate(); 975 this.invalidate();
960 }, 976 },
961 977
978 /**
979 * @return {Object} A sparce, mutable map from sample index to bool. Samples
980 * indices the map that are true are drawn as selected. Callers that mutate
981 * the map must manually call invalidate on the track to trigger a redraw.
982 */
983 get selectedSamples() {
984 return this.selectedSamples_;
985 },
986
962 redraw: function() { 987 redraw: function() {
963 var ctr = this.counter_; 988 var ctr = this.counter_;
964 var ctx = this.ctx_; 989 var ctx = this.ctx_;
965 var canvasW = this.canvas_.width; 990 var canvasW = this.canvas_.width;
966 var canvasH = this.canvas_.height; 991 var canvasH = this.canvas_.height;
967 992
968 ctx.clearRect(0, 0, canvasW, canvasH); 993 ctx.clearRect(0, 0, canvasW, canvasH);
969 994
970 // Culling parametrs. 995 // Culling parametrs.
971 var vp = this.viewport_; 996 var vp = this.viewport_;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1039 } 1064 }
1040 ctx.lineTo(x, yLastView); 1065 ctx.lineTo(x, yLastView);
1041 ctx.lineTo(x, yView); 1066 ctx.lineTo(x, yView);
1042 iLast = i; 1067 iLast = i;
1043 xLast = x; 1068 xLast = x;
1044 yLastView = yView; 1069 yLastView = yView;
1045 } 1070 }
1046 ctx.closePath(); 1071 ctx.closePath();
1047 ctx.fill(); 1072 ctx.fill();
1048 } 1073 }
1074 ctx.fillStyle = 'rgba(255, 0, 0, 1)';
1075 for (var i in this.selectedSamples_) {
1076 if (!this.selectedSamples_[i])
1077 continue;
1078
1079 var x = ctr.timestamps[i];
1080 for (var seriesIndex = ctr.numSeries - 1;
1081 seriesIndex >= 0; seriesIndex--) {
1082 var y = ctr.totals[i * numSeries + seriesIndex];
1083 var yView = canvasH - (yScale * y);
1084 ctx.fillRect(x - pixWidth, yView - 1, 3 * pixWidth, 3);
1085 }
1086 }
1049 ctx.restore(); 1087 ctx.restore();
1050 }, 1088 },
1051 1089
1052 /** 1090 /**
1053 * Picks a slice, if any, at a given location. 1091 * Adds items intersecting a point to a selection.
1054 * @param {number} wX X location to search at, in worldspace. 1092 * @param {number} wX X location to search at, in worldspace.
1055 * @param {number} wY Y location to search at, in offset space. 1093 * @param {number} wY Y location to search at, in offset space.
1056 * offset space. 1094 * offset space.
1057 * @param {function():*} onHitCallback Callback to call with the slice, 1095 * @param {TimelineSelection} selection Selection to which to add hits.
1058 * if one is found.
1059 * @return {boolean} true if a slice was found, otherwise false. 1096 * @return {boolean} true if a slice was found, otherwise false.
1060 */ 1097 */
1061 pick: function(wX, wY, onHitCallback) { 1098 addIntersectingItemsToSelection: function(wX, wY, selection) {
1099 var clientRect = this.getBoundingClientRect();
1100 if (wY < clientRect.top || wY >= clientRect.bottom)
1101 return false;
1102 var ctr = this.counter_;
1103 if (wX < this.counter_.timestamps[0])
1104 return false;
1105 var i = tracing.findLowIndexInSortedArray(ctr.timestamps,
1106 function(x) { return x; },
1107 wX);
1108 if (i < 0 || i >= ctr.timestamps.length)
1109 return false;
1110
1111 // Sample i is going to either be exactly at wX or slightly above it,
1112 // E.g. asking for 7.5 in [7,8] gives i=1. So bump i back by 1 if needed.
1113 if (i > 0 && wX > this.counter_.timestamps[i - 1])
1114 i--;
1115
1116 // Some preliminaries.
1117 var canvasH = this.getBoundingClientRect().height;
1118 var yScale = canvasH / ctr.maxTotal;
1119
1120 /*
1121 // Figure out which sample we hit
1122 var seriesIndexHit;
1123 for (var seriesIndex = 0; seriesIndex < ctr.numSeries; seriesIndex++) {
1124 var y = ctr.totals[i * ctr.numSeries + seriesIndex];
1125 var yView = canvasH - (yScale * y) + clientRect.top;
1126 if (wY >= yView) {
1127 seriesIndexHit = seriesIndex;
1128 break;
1129 }
1130 }
1131 if (seriesIndexHit === undefined)
1132 return false;
1133 */
1134 var hit = selection.addCounterSample(this, this.counter, i);
1135 this.decorateHit(hit);
1136 return true;
1062 }, 1137 },
1063 1138
1064 /** 1139 /**
1065 * Finds slices intersecting the given interval. 1140 * Adds items intersecting the given range to a selection.
1066 * @param {number} loWX Lower X bound of the interval to search, in 1141 * @param {number} loWX Lower X bound of the interval to search, in
1067 * worldspace. 1142 * worldspace.
1068 * @param {number} hiWX Upper X bound of the interval to search, in 1143 * @param {number} hiWX Upper X bound of the interval to search, in
1069 * worldspace. 1144 * worldspace.
1070 * @param {number} loY Lower Y bound of the interval to search, in 1145 * @param {number} loY Lower Y bound of the interval to search, in
1071 * offset space. 1146 * offset space.
1072 * @param {number} hiY Upper Y bound of the interval to search, in 1147 * @param {number} hiY Upper Y bound of the interval to search, in
1073 * offset space. 1148 * offset space.
1074 * @param {function():*} onHitCallback Function to call for each slice 1149 * @param {TimelineSelection} selection Selection to which to add hits.
1075 * intersecting the interval.
1076 */ 1150 */
1077 pickRange: function(loWX, hiWX, loY, hiY, onHitCallback) { 1151 addIntersectingItemsInRangeToSelection: function(
1152 loWX, hiWX, loY, hiY, selection) {
1153
1154 var clientRect = this.getBoundingClientRect();
1155 var a = Math.max(loY, clientRect.top);
1156 var b = Math.min(hiY, clientRect.bottom);
1157 if (a > b)
1158 return;
1159
1160 var ctr = this.counter_;
1161
1162 var iLo = tracing.findLowIndexInSortedArray(ctr.timestamps,
1163 function(x) { return x; },
1164 loWX);
1165 var iHi = tracing.findLowIndexInSortedArray(ctr.timestamps,
1166 function(x) { return x; },
1167 hiWX);
1168
1169 // Sample i is going to either be exactly at wX or slightly above it,
1170 // E.g. asking for 7.5 in [7,8] gives i=1. So bump i back by 1 if needed.
1171 if (iLo > 0 && loWX > ctr.timestamps[iLo - 1])
1172 iLo--;
1173 if (iHi > 0 && hiWX > ctr.timestamps[iHi - 1])
1174 iHi--;
1175
1176 // Iterate over every sample intersecting..
1177 for (var i = iLo; i <= iHi; i++) {
1178 if (i >= ctr.timestamps.length)
1179 continue;
1180
1181 // TODO(nduca): Pick the seriesIndexHit based on the loY - hiY values.
1182 var hit = selection.addCounterSample(this, this.counter, i);
1183 this.decorateHit(hit);
1184 }
1078 }, 1185 },
1079 1186
1080 findAllObjectsMatchingFilter: function(filter) { 1187 addAllObjectsMatchingFilterToSelection: function(filter, selection) {
1081 return [];
1082 } 1188 }
1083 1189
1084 }; 1190 };
1085 1191
1086 return { 1192 return {
1087 TimelineCounterTrack: TimelineCounterTrack, 1193 TimelineCounterTrack: TimelineCounterTrack,
1088 TimelineSliceTrack: TimelineSliceTrack, 1194 TimelineSliceTrack: TimelineSliceTrack,
1089 TimelineThreadTrack: TimelineThreadTrack, 1195 TimelineThreadTrack: TimelineThreadTrack,
1090 TimelineViewportTrack: TimelineViewportTrack, 1196 TimelineViewportTrack: TimelineViewportTrack,
1091 TimelineCpuTrack: TimelineCpuTrack 1197 TimelineCpuTrack: TimelineCpuTrack
1092 }; 1198 };
1093 }); 1199 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/tracing/timeline_test.html ('k') | chrome/browser/resources/tracing/timeline_track_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698