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

Side by Side Diff: Source/devtools/front_end/components/FlameChart.js

Issue 402113002: Draw marker events on Timeline flame chart (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 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 /** 1 /**
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), fal se); 61 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), fal se);
62 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse); 62 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse);
63 this._canvas.addEventListener("click", this._onClick.bind(this), false); 63 this._canvas.addEventListener("click", this._onClick.bind(this), false);
64 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null); 64 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null);
65 65
66 this._vScrollElement = this.element.createChild("div", "flame-chart-v-scroll "); 66 this._vScrollElement = this.element.createChild("div", "flame-chart-v-scroll ");
67 this._vScrollContent = this._vScrollElement.createChild("div"); 67 this._vScrollContent = this._vScrollElement.createChild("div");
68 this._vScrollElement.addEventListener("scroll", this.scheduleUpdate.bind(thi s), false); 68 this._vScrollElement.addEventListener("scroll", this.scheduleUpdate.bind(thi s), false);
69 69
70 this._entryInfo = this.element.createChild("div", "profile-entry-info"); 70 this._entryInfo = this.element.createChild("div", "profile-entry-info");
71 this._markerHighlighElement = this.element.createChild("div", "flame-chart-m arker-highlight-element");
71 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element"); 72 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element");
72 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element"); 73 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element");
73 74
74 this._dataProvider = dataProvider; 75 this._dataProvider = dataProvider;
75 76
76 this._windowLeft = 0.0; 77 this._windowLeft = 0.0;
77 this._windowRight = 1.0; 78 this._windowRight = 1.0;
78 this._windowWidth = 1.0; 79 this._windowWidth = 1.0;
79 this._timeWindowLeft = 0; 80 this._timeWindowLeft = 0;
80 this._timeWindowRight = Infinity; 81 this._timeWindowRight = Infinity;
81 this._barHeight = dataProvider.barHeight(); 82 this._barHeight = dataProvider.barHeight();
82 this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight; 83 this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight;
83 this._minWidth = 1; 84 this._minWidth = 1;
84 this._paddingLeft = this._dataProvider.paddingLeft(); 85 this._paddingLeft = this._dataProvider.paddingLeft();
85 this._markerPadding = 2; 86 this._markerPadding = 2;
86 this._markerRadius = this._barHeight / 2 - this._markerPadding; 87 this._markerRadius = this._barHeight / 2 - this._markerPadding;
88 this._highlightedMarkerIndex = -1;
87 this._highlightedEntryIndex = -1; 89 this._highlightedEntryIndex = -1;
88 this._selectedEntryIndex = -1; 90 this._selectedEntryIndex = -1;
89 this._textWidth = {}; 91 this._textWidth = {};
90 } 92 }
91 93
92 WebInspector.FlameChart.DividersBarHeight = 20; 94 WebInspector.FlameChart.DividersBarHeight = 20;
93 95
94 /** 96 /**
95 * @interface 97 * @interface
96 */ 98 */
97 WebInspector.FlameChartDataProvider = function() 99 WebInspector.FlameChartDataProvider = function()
98 { 100 {
99 } 101 }
100 102
101 /** @typedef {!{ 103 /**
102 entryLevels: (!Array.<number>|!Uint8Array), 104 * @constructor
103 entryTotalTimes: (!Array.<number>|!Float32Array), 105 * @param {!Array.<number>|!Uint8Array} entryLevels
104 entryStartTimes: (!Array.<number>|!Float64Array) 106 * @param {!Array.<number>|!Float32Array} entryTotalTimes
105 }} 107 * @param {!Array.<number>|!Float64Array} entryStartTimes
106 */ 108 */
107 WebInspector.FlameChart.TimelineData; 109 WebInspector.FlameChart.TimelineData = function(entryLevels, entryTotalTimes, en tryStartTimes)
110 {
111 this.entryLevels = entryLevels;
112 this.entryTotalTimes = entryTotalTimes;
113 this.entryStartTimes = entryStartTimes;
114 /** @type {!Array.<number>} */
115 this.markerTimestamps = [];
116 }
108 117
109 WebInspector.FlameChartDataProvider.prototype = { 118 WebInspector.FlameChartDataProvider.prototype = {
110 /** 119 /**
111 * @return {number} 120 * @return {number}
112 */ 121 */
113 barHeight: function() { }, 122 barHeight: function() { },
114 123
115 /** 124 /**
116 * @param {number} startTime 125 * @param {number} startTime
117 * @param {number} endTime 126 * @param {number} endTime
118 * @return {?Array.<number>} 127 * @return {?Array.<number>}
119 */ 128 */
120 dividerOffsets: function(startTime, endTime) { }, 129 dividerOffsets: function(startTime, endTime) { },
121 130
122 /** 131 /**
132 * @param {number} index
133 * @return {string}
134 */
135 markerColor: function(index) { },
136
137 /**
138 * @param {number} index
139 * @return {string}
140 */
141 markerTitle: function(index) { },
142
143 /**
123 * @return {number} 144 * @return {number}
124 */ 145 */
125 minimumBoundary: function() { }, 146 minimumBoundary: function() { },
126 147
127 /** 148 /**
128 * @return {number} 149 * @return {number}
129 */ 150 */
130 totalTime: function() { }, 151 totalTime: function() { },
131 152
132 /** 153 /**
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 this._isDragging = false; 469 this._isDragging = false;
449 }, 470 },
450 471
451 /** 472 /**
452 * @param {!Event} event 473 * @param {!Event} event
453 */ 474 */
454 _onMouseMove: function(event) 475 _onMouseMove: function(event)
455 { 476 {
456 if (this._isDragging) 477 if (this._isDragging)
457 return; 478 return;
479
480 var inDividersBar = event.offsetY < WebInspector.FlameChart.DividersBarH eight;
481 this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPositi on(event.offsetX) : -1;
482 this._updateMarkerHighlight();
483 if (inDividersBar)
484 return;
485
458 var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offs etY); 486 var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offs etY);
459 487
460 if (this._highlightedEntryIndex === entryIndex) 488 if (this._highlightedEntryIndex === entryIndex)
461 return; 489 return;
462 490
463 if (entryIndex === -1 || !this._dataProvider.canJumpToEntry(entryIndex)) 491 if (entryIndex === -1 || !this._dataProvider.canJumpToEntry(entryIndex))
464 this._canvas.style.cursor = "default"; 492 this._canvas.style.cursor = "default";
465 else 493 else
466 this._canvas.style.cursor = "pointer"; 494 this._canvas.style.cursor = "pointer";
467 495
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } else { 583 } else {
556 cursorLevel = Math.floor((this._canvas.height / window.devicePixelRa tio - y) / this._barHeight); 584 cursorLevel = Math.floor((this._canvas.height / window.devicePixelRa tio - y) / this._barHeight);
557 offsetFromLevel = this._canvas.height / window.devicePixelRatio - cu rsorLevel * this._barHeight; 585 offsetFromLevel = this._canvas.height / window.devicePixelRatio - cu rsorLevel * this._barHeight;
558 } 586 }
559 var entryStartTimes = timelineData.entryStartTimes; 587 var entryStartTimes = timelineData.entryStartTimes;
560 var entryTotalTimes = timelineData.entryTotalTimes; 588 var entryTotalTimes = timelineData.entryTotalTimes;
561 var entryIndexes = this._timelineLevels[cursorLevel]; 589 var entryIndexes = this._timelineLevels[cursorLevel];
562 if (!entryIndexes || !entryIndexes.length) 590 if (!entryIndexes || !entryIndexes.length)
563 return -1; 591 return -1;
564 592
593 /**
594 * @param {number} time
595 * @param {number} entryIndex
596 * @return {number}
597 */
565 function comparator(time, entryIndex) 598 function comparator(time, entryIndex)
566 { 599 {
567 return time - entryStartTimes[entryIndex]; 600 return time - entryStartTimes[entryIndex];
568 } 601 }
569 var indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparat or) - 1, 0); 602 var indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparat or) - 1, 0);
570 603
571 /** 604 /**
572 * @this {WebInspector.FlameChart} 605 * @this {WebInspector.FlameChart}
573 * @param {number} entryIndex 606 * @param {number} entryIndex
574 * @return {boolean} 607 * @return {boolean}
(...skipping 17 matching lines...) Expand all
592 var entryIndex = entryIndexes[indexOnLevel]; 625 var entryIndex = entryIndexes[indexOnLevel];
593 if (checkEntryHit.call(this, entryIndex)) 626 if (checkEntryHit.call(this, entryIndex))
594 return entryIndex; 627 return entryIndex;
595 entryIndex = entryIndexes[indexOnLevel + 1]; 628 entryIndex = entryIndexes[indexOnLevel + 1];
596 if (checkEntryHit.call(this, entryIndex)) 629 if (checkEntryHit.call(this, entryIndex))
597 return entryIndex; 630 return entryIndex;
598 return -1; 631 return -1;
599 }, 632 },
600 633
601 /** 634 /**
635 * @param {number} x
636 * @return {number}
637 */
638 _markerIndexAtPosition: function(x)
639 {
640 var markers = this._timelineData().markerTimestamps;
641 if (!markers)
642 return -1;
643 var accurracyOffsetPx = 1;
644 var time = this._cursorTime(x);
645 var leftTime = this._cursorTime(x - accurracyOffsetPx);
646 var rightTime = this._cursorTime(x + accurracyOffsetPx);
647
648 /**
649 * @param {number} time
650 * @param {number} markerTimestamp
651 * @return {number}
652 */
653 function comparator(time, markerTimestamp)
654 {
655 return time - markerTimestamp;
656 }
657 var left = markers.lowerBound(leftTime, comparator);
658 var markerIndex = -1;
659 var distance = Infinity;
660 for (var i = left; i < markers.length; i++) {
661 if (markers[i] > rightTime)
alph 2014/07/21 14:21:07 nit: you can move the check into the for condition
yurys 2014/07/21 14:30:00 Done.
662 break;
663 var nextDistance = Math.abs(markers[i] - time);
664 if (nextDistance < distance) {
665 markerIndex = i;
666 distance = nextDistance;
667 }
668 }
669 return markerIndex;
670 },
671
672 /**
602 * @param {number} height 673 * @param {number} height
603 * @param {number} width 674 * @param {number} width
604 */ 675 */
605 _draw: function(width, height) 676 _draw: function(width, height)
606 { 677 {
607 var timelineData = this._timelineData(); 678 var timelineData = this._timelineData();
608 if (!timelineData) 679 if (!timelineData)
609 return; 680 return;
610 681
611 var context = this._canvas.getContext("2d"); 682 var context = this._canvas.getContext("2d");
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 if (!text || !text.length) 810 if (!text || !text.length)
740 continue; 811 continue;
741 812
742 context.fillStyle = this._dataProvider.textColor(entryIndex); 813 context.fillStyle = this._dataProvider.textColor(entryIndex);
743 context.fillText(text, barX + textPadding, textBaseHeight - barLevel * this._barHeightDelta); 814 context.fillText(text, barX + textPadding, textBaseHeight - barLevel * this._barHeightDelta);
744 } 815 }
745 context.restore(); 816 context.restore();
746 817
747 var offsets = this._dataProvider.dividerOffsets(this._calculator.minimum Boundary(), this._calculator.maximumBoundary()); 818 var offsets = this._dataProvider.dividerOffsets(this._calculator.minimum Boundary(), this._calculator.maximumBoundary());
748 WebInspector.TimelineGrid.drawCanvasGrid(this._canvas, this._calculator, offsets); 819 WebInspector.TimelineGrid.drawCanvasGrid(this._canvas, this._calculator, offsets);
820 this._drawMarkers();
749 821
750 this._updateElementPosition(this._highlightElement, this._highlightedEnt ryIndex); 822 this._updateElementPosition(this._highlightElement, this._highlightedEnt ryIndex);
751 this._updateElementPosition(this._selectedElement, this._selectedEntryIn dex); 823 this._updateElementPosition(this._selectedElement, this._selectedEntryIn dex);
824 this._updateMarkerHighlight();
825 },
826
827 _drawMarkers: function()
828 {
829 var markerTimestamps = this._timelineData().markerTimestamps;
830 /**
831 * @param {number} time
832 * @param {number} markerTimestamp
833 * @return {number}
834 */
835 function compare(time, markerTimestamp)
836 {
837 return time - markerTimestamp;
838 }
839 var left = markerTimestamps.lowerBound(this._calculator.minimumBoundary( ), compare);
840 var right = markerTimestamps.upperBound(this._calculator.maximumBoundary (), compare);
alph 2014/07/21 14:21:07 nit: you don't really need to calculate it. you ca
yurys 2014/07/21 14:30:00 Done.
841
842 var context = this._canvas.getContext("2d");
843 context.save();
844 var ratio = window.devicePixelRatio;
845 context.scale(ratio, ratio);
846 var height = WebInspector.FlameChart.DividersBarHeight - 1;
847 context.lineWidth = 2;
848 for (var i = left; i < right; i++) {
849 var timestamp = markerTimestamps[i];
850 var position = this._calculator.computePosition(timestamp);
851 context.strokeStyle = this._dataProvider.markerColor(i);
852 context.beginPath();
853 context.moveTo(position, 0);
854 context.lineTo(position, height);
855 context.stroke();
856 }
857 context.restore();
858 },
859
860 _updateMarkerHighlight: function()
861 {
862 var element = this._markerHighlighElement;
863 if (element.parentElement)
864 element.remove();
865 var markerIndex = this._highlightedMarkerIndex;
866 if (markerIndex === -1)
867 return;
868 var barX = this._timeToPosition(this._timelineData().markerTimestamps[ma rkerIndex]);
869 element.title = this._dataProvider.markerTitle(markerIndex);
870 var style = element.style;
871 style.left = barX + "px";
872 style.backgroundColor = this._dataProvider.markerColor(markerIndex);
873 this.element.appendChild(element);
752 }, 874 },
753 875
754 /** 876 /**
755 * @param {?WebInspector.FlameChart.TimelineData} timelineData 877 * @param {?WebInspector.FlameChart.TimelineData} timelineData
756 */ 878 */
757 _processTimelineData: function(timelineData) 879 _processTimelineData: function(timelineData)
758 { 880 {
759 if (!timelineData) { 881 if (!timelineData) {
760 this._timelineLevels = null; 882 this._timelineLevels = null;
761 this._rawTimelineData = null; 883 this._rawTimelineData = null;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 if (!this._timelineData()) 1068 if (!this._timelineData())
947 return; 1069 return;
948 this._resetCanvas(); 1070 this._resetCanvas();
949 this._updateBoundaries(); 1071 this._updateBoundaries();
950 this._calculator._updateBoundaries(this); 1072 this._calculator._updateBoundaries(this);
951 this._draw(this._offsetWidth, this._offsetHeight); 1073 this._draw(this._offsetWidth, this._offsetHeight);
952 }, 1074 },
953 1075
954 reset: function() 1076 reset: function()
955 { 1077 {
1078 this._highlightedMarkerIndex = -1;
956 this._highlightedEntryIndex = -1; 1079 this._highlightedEntryIndex = -1;
957 this._selectedEntryIndex = -1; 1080 this._selectedEntryIndex = -1;
958 this._textWidth = {}; 1081 this._textWidth = {};
959 this.update(); 1082 this.update();
960 }, 1083 },
961 1084
962 __proto__: WebInspector.HBox.prototype 1085 __proto__: WebInspector.HBox.prototype
963 } 1086 }
OLDNEW
« no previous file with comments | « no previous file | Source/devtools/front_end/flameChart.css » ('j') | Source/devtools/front_end/flameChart.css » ('J')

Powered by Google App Engine
This is Rietveld 408576698