Title: [117969] trunk/Source/WebCore
Revision
117969
Author
[email protected]
Date
2012-05-22 07:06:47 -0700 (Tue, 22 May 2012)

Log Message

Web Inspector: use canvas to render timeline category strips in overview pane
https://bugs.webkit.org/show_bug.cgi?id=87109

Reviewed by Pavel Feldman.

- use canvas, not DOM to represent timeline category strips in the default overview mode

* inspector/front-end/TimelineOverviewPane.js:
(WebInspector.TimelineOverviewPane):
(WebInspector.TimelineOverviewPane.prototype._setVerticalOverview): propagate to TimelineCategoryStrips;
(WebInspector.TimelineOverviewPane.prototype._onCategoryVisibilityChanged): force update of category strips;
(WebInspector.TimelineOverviewPane.prototype._update):
(WebInspector.TimelineOverviewPane.prototype.setShowShortEvents):
(WebInspector.TimelineCategoryStrips):
(WebInspector.TimelineCategoryStrips.prototype.update.appendRecord): process one record;
(WebInspector.TimelineCategoryStrips.prototype.update): re-draw everything;
(WebInspector.TimelineCategoryStrips.prototype.setShowShortEvents):
(WebInspector.TimelineCategoryStrips.prototype._renderBar): render single bar;
(WebInspector.TimelineVerticalOverview):
(WebInspector.TimelineVerticalOverview.prototype._renderBar):
* inspector/front-end/TimelinePresentationModel.js:
(WebInspector.TimelinePresentationModel.categories):
(WebInspector.TimelinePresentationModel.createFillStyle): utility methods to create gradients for category bars;
(WebInspector.TimelinePresentationModel.createFillStyleForCategory):
(WebInspector.TimelineCategory):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117968 => 117969)


--- trunk/Source/WebCore/ChangeLog	2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/ChangeLog	2012-05-22 14:06:47 UTC (rev 117969)
@@ -1,3 +1,31 @@
+2012-05-22  Andrey Kosyakov  <[email protected]>
+
+        Web Inspector: use canvas to render timeline category strips in overview pane
+        https://bugs.webkit.org/show_bug.cgi?id=87109
+
+        Reviewed by Pavel Feldman.
+
+        - use canvas, not DOM to represent timeline category strips in the default overview mode
+
+        * inspector/front-end/TimelineOverviewPane.js:
+        (WebInspector.TimelineOverviewPane):
+        (WebInspector.TimelineOverviewPane.prototype._setVerticalOverview): propagate to TimelineCategoryStrips;
+        (WebInspector.TimelineOverviewPane.prototype._onCategoryVisibilityChanged): force update of category strips;
+        (WebInspector.TimelineOverviewPane.prototype._update):
+        (WebInspector.TimelineOverviewPane.prototype.setShowShortEvents):
+        (WebInspector.TimelineCategoryStrips):
+        (WebInspector.TimelineCategoryStrips.prototype.update.appendRecord): process one record;
+        (WebInspector.TimelineCategoryStrips.prototype.update): re-draw everything;
+        (WebInspector.TimelineCategoryStrips.prototype.setShowShortEvents):
+        (WebInspector.TimelineCategoryStrips.prototype._renderBar): render single bar;
+        (WebInspector.TimelineVerticalOverview):
+        (WebInspector.TimelineVerticalOverview.prototype._renderBar):
+        * inspector/front-end/TimelinePresentationModel.js:
+        (WebInspector.TimelinePresentationModel.categories):
+        (WebInspector.TimelinePresentationModel.createFillStyle): utility methods to create gradients for category bars;
+        (WebInspector.TimelinePresentationModel.createFillStyleForCategory):
+        (WebInspector.TimelineCategory):
+
 2012-05-22  Pavel Feldman  <[email protected]>
 
         Web Inspector: [regression] dynamically created script tab is bound to the document resource.

Modified: trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js (117968 => 117969)


--- trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js	2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/inspector/front-end/TimelineOverviewPane.js	2012-05-22 14:06:47 UTC (rev 117969)
@@ -88,21 +88,16 @@
     this._overviewWindow = new WebInspector.TimelineOverviewWindow(this._overviewContainer);
     this._overviewWindow.addEventListener(WebInspector.TimelineOverviewWindow.Events.WindowChanged, this._onWindowChanged, this);
 
-    this._overviewContainer.appendChild(this._overviewGrid.element);
-
     var separatorElement = document.createElement("div");
     separatorElement.id = "timeline-overview-separator";
     this.element.appendChild(separatorElement);
+
+    this._categoryStrips = new WebInspector.TimelineCategoryStrips(this._model);
+    this._overviewGrid.itemsGraphsElement.appendChild(this._categoryStrips.element);
  
-    this._categoryGraphs = {};
-    var i = 0;
     var categories = WebInspector.TimelinePresentationModel.categories();
-    for (var category in categories) {
-        var categoryGraph = new WebInspector.TimelineCategoryGraph(categories[category], i++ % 2);
-        this._categoryGraphs[category] = categoryGraph;
-        this._overviewGrid.itemsGraphsElement.appendChild(categoryGraph.graphElement);
+    for (var category in categories)
         categories[category].addEventListener(WebInspector.TimelineCategory.Events.VisibilityChanged, this._onCategoryVisibilityChanged, this);
-    }
 
     this._overviewGrid.setScrollAndDividerTop(0, 0);
     this._overviewCalculator = new WebInspector.TimelineOverviewCalculator();
@@ -134,6 +129,11 @@
         this._update();
     },
 
+    onResize: function()
+    {
+        this._update();
+    },
+
     _showEvents: function()
     {
         if (this._currentMode === WebInspector.TimelineOverviewPane.Mode.EventsHorizontal)
@@ -182,15 +182,14 @@
             this._verticalOverview.detach();
             this._verticalOverview = null;
             this._overviewGrid.itemsGraphsElement.removeStyleClass("hidden");
-            this._updateCategoryStrips();
+            this._categoryStrips.update();
         }
     },
 
     _onCategoryVisibilityChanged: function(event)
     {
-        var category = event.data;
-        this._categoryGraphs[category.name].dimmed = category.hidden;
-        this._update();
+        if (this._currentMode === WebInspector.TimelineOverviewPane.Mode.EventsHorizontal)
+            this._categoryStrips.update();
     },
 
     _update: function()
@@ -205,61 +204,12 @@
         else if (this._verticalOverview)
             this._verticalOverview.update();
         else
-            this._updateCategoryStrips();
+            this._categoryStrips.update();
 
         this._overviewGrid.updateDividers(this._overviewCalculator);
         this._updateEventDividers();
     },
 
-    _updateCategoryStrips: function()
-    {
-        // Clear summary bars.
-        var timelines = {};
-        var categories = WebInspector.TimelinePresentationModel.categories();
-        for (var category in categories) {
-            timelines[category] = [];
-            this._categoryGraphs[category].clearChunks();
-        }
-
-        // Create sparse arrays with 101 cells each to fill with chunks for a given category.
-        function markPercentagesForRecord(record)
-        {
-            var isLong = WebInspector.TimelineModel.durationInSeconds(record) > WebInspector.TimelinePresentationModel.shortRecordThreshold;
-            if (!(this._showShortEvents || isLong))
-                return;
-            var percentages = this._overviewCalculator.computeBarGraphPercentages(record);
-
-            var end = Math.round(percentages.end);
-            var categoryName = WebInspector.TimelinePresentationModel.categoryForRecord(record).name;
-            for (var j = Math.round(percentages.start); j <= end; ++j)
-                timelines[categoryName][j] = true;
-        }
-        var records = this._model.records;
-        WebInspector.TimelinePresentationModel.forAllRecords(records, markPercentagesForRecord.bind(this));
-
-        // Convert sparse arrays to continuous segments, render graphs for each.
-        for (var category in categories) {
-            var timeline = timelines[category];
-            window.timelineSaved = timeline;
-            var chunkStart = -1;
-            for (var j = 0; j < 101; ++j) {
-                if (timeline[j]) {
-                    if (chunkStart === -1)
-                        chunkStart = j;
-                } else {
-                    if (chunkStart !== -1) {
-                        this._categoryGraphs[category].addChunk(chunkStart, j);
-                        chunkStart = -1;
-                    }
-                }
-            }
-            if (chunkStart !== -1) {
-                this._categoryGraphs[category].addChunk(chunkStart, 100);
-                chunkStart = -1;
-            }
-        }
-    },
-
     _updateEventDividers: function()
     {
         var records = this._eventDividers;
@@ -374,10 +324,12 @@
         this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.WindowChanged);
     },
 
+    /**
+     * @param {boolean} value
+     */
     setShowShortEvents: function(value)
     {
-        this._showShortEvents = value;
-        this._update();
+        this._categoryStrips.setShowShortEvents(value);
     },
 
     _scheduleRefresh: function()
@@ -675,50 +627,6 @@
 /**
  * @constructor
  */
-WebInspector.TimelineCategoryGraph = function(category, isEven)
-{
-    this._category = category;
-
-    this._graphElement = document.createElement("div");
-    this._graphElement.className = "timeline-graph-side timeline-overview-graph-side" + (isEven ? " even" : "");
-
-    this._barAreaElement = document.createElement("div");
-    this._barAreaElement.className = "timeline-graph-bar-area timeline-category-" + category.name;
-    this._graphElement.appendChild(this._barAreaElement);
-}
-
-WebInspector.TimelineCategoryGraph.prototype = {
-    get graphElement()
-    {
-        return this._graphElement;
-    },
-
-    addChunk: function(start, end)
-    {
-        var chunk = document.createElement("div");
-        chunk.className = "timeline-graph-bar";
-        this._barAreaElement.appendChild(chunk);
-        chunk.style.setProperty("left", start + "%");
-        chunk.style.setProperty("width", (end - start) + "%");
-    },
-
-    clearChunks: function()
-    {
-        this._barAreaElement.removeChildren();
-    },
-
-    set dimmed(dimmed)
-    {
-        if (dimmed)
-            this._barAreaElement.removeStyleClass("timeline-category-" + this._category.name);
-        else
-            this._barAreaElement.addStyleClass("timeline-category-" + this._category.name);
-    }
-}
-
-/**
- * @constructor
- */
 WebInspector.TimelineOverviewPane.WindowSelector = function(parent, position)
 {
     this._startPosition = position;
@@ -892,10 +800,104 @@
     },
 }
 
+/**
+ * @constructor
+ * @param {WebInspector.TimelineModel} model
+ */
 WebInspector.TimelineCategoryStrips = function(model)
 {
+    this._model = model;
+    this.element = document.createElement("canvas");
+    this._context = this.element.getContext("2d");
+
+    this._fillStyles = {};
+    var categories = WebInspector.TimelinePresentationModel.categories();
+    for (var category in categories)
+        this._fillStyles[category] = WebInspector.TimelinePresentationModel.createFillStyleForCategory(this._context, 0, WebInspector.TimelineCategoryStrips._innerStripHeight, categories[category]);
+
+    this._disabledCategoryFillStyle = WebInspector.TimelinePresentationModel.createFillStyle(this._context, 0, WebInspector.TimelineCategoryStrips._innerStripHeight,
+        "rgb(218, 218, 218)", "rgb(170, 170, 170)", "rgb(143, 143, 143)");
+
+    this._disabledCategoryBorderStyle = "rgb(143, 143, 143)";
 }
 
+/** @const */
+WebInspector.TimelineCategoryStrips._canvasHeight = 60;
+/** @const */
+WebInspector.TimelineCategoryStrips._numberOfStrips = 3;
+/** @const */
+WebInspector.TimelineCategoryStrips._stripHeight = Math.round(WebInspector.TimelineCategoryStrips._canvasHeight  / WebInspector.TimelineCategoryStrips._numberOfStrips);
+/** @const */
+WebInspector.TimelineCategoryStrips._stripPadding = 4;
+/** @const */
+WebInspector.TimelineCategoryStrips._innerStripHeight = WebInspector.TimelineCategoryStrips._stripHeight - 2 * WebInspector.TimelineCategoryStrips._stripPadding;
+
+WebInspector.TimelineCategoryStrips.prototype = {
+    update: function()
+    {
+        // Use real world, 1:1 coordinates in canvas. This will also take care of clearing it.
+        this.element.width = this.element.parentElement.clientWidth;
+        this.element.height = WebInspector.TimelineCategoryStrips._canvasHeight;
+
+        var timeOffset = this._model.minimumRecordTime();
+        var timeSpan = this._model.maximumRecordTime() - timeOffset;
+        var scale = this.element.width / timeSpan;
+
+        var barsByCategory = {};
+
+        this._context.fillStyle = "rgba(0, 0, 0, 0.05)";
+        for (var i = 1; i < WebInspector.TimelineCategoryStrips._numberOfStrips; i += 2)
+            this._context.fillRect(0.5, i * WebInspector.TimelineCategoryStrips._stripHeight + 0.5, this.element.width, WebInspector.TimelineCategoryStrips._stripHeight);
+
+        function appendRecord(record)
+        {
+            var isLong = WebInspector.TimelineModel.durationInSeconds(record) > WebInspector.TimelinePresentationModel.shortRecordThreshold;
+            if (!(this._showShortEvents || isLong))
+                return;
+            var recordStart = Math.floor((WebInspector.TimelineModel.startTimeInSeconds(record) - timeOffset)* scale);
+            var recordEnd = Math.ceil((WebInspector.TimelineModel.endTimeInSeconds(record) - timeOffset) * scale);
+            var category = WebInspector.TimelinePresentationModel.categoryForRecord(record);
+            var bar = barsByCategory[category.name];
+            // This bar may be merged with previous -- so just adjust the previous bar.
+            const barsMergeThreshold = 2;
+            if (bar && bar.end + barsMergeThreshold >= recordStart) {
+                bar.end = recordEnd;
+                return;
+            }
+            if (bar)
+                this._renderBar(bar.start, bar.end, category);
+            barsByCategory[category.name] = { start: recordStart, end: recordEnd };
+        }
+        WebInspector.TimelinePresentationModel.forAllRecords(this._model.records, appendRecord.bind(this));
+        for (var category in barsByCategory)
+            this._renderBar(barsByCategory[category].start, barsByCategory[category].end, WebInspector.TimelinePresentationModel.categories()[category]);
+    },
+
+    /**
+     * @param {boolean} value
+     */
+    setShowShortEvents: function(value)
+    {
+        this._showShortEvents = value;
+        this.update();
+    },
+
+    _renderBar: function(begin, end, category)
+    {
+        var x = begin + 0.5;
+        var y = category.overviewStripGroupIndex * WebInspector.TimelineCategoryStrips._stripHeight + WebInspector.TimelineCategoryStrips._stripPadding + 0.5;
+        var width = Math.max(end - begin, 1);
+
+        this._context.save();
+        this._context.translate(x, y);
+        this._context.fillStyle = category.hidden ? this._disabledCategoryFillStyle : this._fillStyles[category.name];
+        this._context.fillRect(0, 0, width, WebInspector.TimelineCategoryStrips._innerStripHeight);
+        this._context.strokeStyle = category.hidden ? this._disabledCategoryBorderStyle : category.borderColor;
+        this._context.strokeRect(0, 0, width, WebInspector.TimelineCategoryStrips._innerStripHeight);
+        this._context.restore();
+    }
+}
+
 /**
  * @constructor
  * @extends {WebInspector.View}
@@ -920,12 +922,8 @@
 
     this._fillStyles = {};
     var categories = WebInspector.TimelinePresentationModel.categories();
-    for (var category in categories) {
-        var fillStyle = this._context.createLinearGradient(0, 0, this._maxInnerBarWidth, 0);
-        fillStyle.addColorStop(0, categories[category].fillColorStop0);
-        fillStyle.addColorStop(1, categories[category].fillColorStop1);
-        this._fillStyles[category] = fillStyle;
-    }
+    for (var category in categories)
+        this._fillStyles[category] = WebInspector.TimelinePresentationModel.createFillStyleForCategory(this._context, this._maxInnerBarWidth, 0, categories[category]);
 }
 
 WebInspector.TimelineVerticalOverview.prototype = {
@@ -1047,7 +1045,7 @@
             this._context.fillRect(0, y, this._maxInnerBarWidth, Math.floor(height));
             this._context.restore();
 
-            this._context.strokeStyle = WebInspector.TimelinePresentationModel.categories()[category];
+            this._context.strokeStyle = WebInspector.TimelinePresentationModel.categories()[category].borderColor;
             this._context.strokeRect(x, y, width, Math.floor(height));
             bottomOffset -= height - 1;
         }

Modified: trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js (117968 => 117969)


--- trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js	2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/inspector/front-end/TimelinePresentationModel.js	2012-05-22 14:06:47 UTC (rev 117969)
@@ -47,9 +47,9 @@
     if (WebInspector.TimelinePresentationModel._categories)
         return WebInspector.TimelinePresentationModel._categories;
     WebInspector.TimelinePresentationModel._categories = {
-        loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), "rgb(106, 152, 213)", "rgb(201, 220, 245)", "rgb(109, 157, 222)"),
-        scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), "rgb(223, 175, 77)", "rgb(251, 222, 168)", "rgb(234, 182, 77)"),
-        rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), "rgb(130, 59, 190)", "rgb(213, 185, 236)", "rgb(137, 62, 200)")
+        loading: new WebInspector.TimelineCategory("loading", WebInspector.UIString("Loading"), 0, "rgb(80, 135, 207)", "rgb(191, 214, 243)", "rgb(112, 162, 227)"),
+        scripting: new WebInspector.TimelineCategory("scripting", WebInspector.UIString("Scripting"), 1, "rgb(220, 163, 49)", "rgb(253, 217, 144)", "rgb(253, 191, 68)"),
+        rendering: new WebInspector.TimelineCategory("rendering", WebInspector.UIString("Rendering"), 2, "rgb(148, 88, 199)", "rgb(219, 195, 239)", "rgb(175, 120, 221)")
     };
     return WebInspector.TimelinePresentationModel._categories;
 };
@@ -754,6 +754,35 @@
 }
 
 /**
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} width
+ * @param {number} height
+ * @param {string} color0
+ * @param {string} color1
+ * @param {string} color2
+ */
+WebInspector.TimelinePresentationModel.createFillStyle = function(context, width, height, color0, color1, color2)
+{
+    var gradient = context.createLinearGradient(0, 0, width, height);
+    gradient.addColorStop(0, color0);
+    gradient.addColorStop(0.3, color1);
+    gradient.addColorStop(0.7, color1);
+    gradient.addColorStop(1, color2);
+    return gradient;
+}
+
+/**
+ * @param {CanvasRenderingContext2D} context
+ * @param {number} width
+ * @param {number} height
+ * @param {WebInspector.TimelineCategory} category
+ */
+WebInspector.TimelinePresentationModel.createFillStyleForCategory = function(context, width, height, category)
+{
+    return WebInspector.TimelinePresentationModel.createFillStyle(context, width, height, category.fillColorStop0, category.fillColorStop1, category.borderColor);
+}
+
+/**
  * @interface
  */
 WebInspector.TimelinePresentationModel.Filter = function()
@@ -772,14 +801,16 @@
  * @extends {WebInspector.Object}
  * @param {string} name
  * @param {string} title
+ * @param {number} overviewStripGroupIndex
  * @param {string} borderColor
  * @param {string} fillColorStop0
  * @param {string} fillColorStop1
  */
-WebInspector.TimelineCategory = function(name, title, borderColor, fillColorStop0, fillColorStop1)
+WebInspector.TimelineCategory = function(name, title, overviewStripGroupIndex, borderColor, fillColorStop0, fillColorStop1)
 {
     this.name = name;
     this.title = title;
+    this.overviewStripGroupIndex = overviewStripGroupIndex;
     this.borderColor = borderColor;
     this.fillColorStop0 = fillColorStop0;
     this.fillColorStop1 = fillColorStop1;

Modified: trunk/Source/WebCore/inspector/front-end/timelinePanel.css (117968 => 117969)


--- trunk/Source/WebCore/inspector/front-end/timelinePanel.css	2012-05-22 14:04:23 UTC (rev 117968)
+++ trunk/Source/WebCore/inspector/front-end/timelinePanel.css	2012-05-22 14:06:47 UTC (rev 117969)
@@ -307,16 +307,6 @@
     pointer-events: none;
 }
 
-.timeline-overview-graph-side {
-    height: 20px;
-    z-index: 170;
-    pointer-events: none;
-}
-
-.timeline-overview-graph-side .timeline-graph-bar {
-    height: 13px;
-}
-
 .timeline-graph-bar-area {
     position: absolute;
     top: 0;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to