Changeset 27943 in webkit


Ignore:
Timestamp:
Nov 21, 2007 3:40:16 PM (16 years ago)
Author:
timothy@apple.com
Message:

Reviewed by Adam Roben.

Bug 16085: Web Inspector's Network Timeline graph code clean up and misc. fixes
http://bugs.webkit.org/show_bug.cgi?id=16085


Changes include:

  • Refactor the drawing code as nested functions instead of global functions.
  • Compute the segment percentages only once per call to drawSummaryGraph.
  • Account for percentages that rounded down to total less-than 100%.
  • Draw the pill shadow better using the canvas shadow drawing properties.
  • Removes a couple canvas context saves and restores.
  • page/inspector/NetworkPanel.js:
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r27937 r27943  
     12007-11-21  Timothy Hatcher  <timothy@apple.com>
     2
     3        Reviewed by Adam Roben.
     4
     5        Bug 16085: Web Inspector's Network Timeline graph code clean up and misc. fixes
     6        http://bugs.webkit.org/show_bug.cgi?id=16085
     7       
     8        Changes include:
     9        - Refactor the drawing code as nested functions instead of global functions.
     10        - Compute the segment percentages only once per call to drawSummaryGraph.
     11        - Account for percentages that rounded down to total less-than 100%.
     12        - Draw the pill shadow better using the canvas shadow drawing properties.
     13        - Removes a couple canvas context saves and restores.
     14
     15        * page/inspector/NetworkPanel.js:
     16
    1172007-11-21  Alexey Proskuryakov  <ap@webkit.org>
    218
  • trunk/WebCore/page/inspector/NetworkPanel.js

    r27935 r27943  
    341341    },
    342342
    343     drawSwatch: function(canvas, color) {
    344         var ctx = canvas.getContext('2d');
    345 
     343    fadeOutRect: function(ctx, x, y, w, h, a1, a2)
     344    {
    346345        ctx.save();
    347346
    348         drawSwatchSquare(ctx, color);
     347        var gradient = ctx.createLinearGradient(x, y, x, y + h);
     348        gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
     349        gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
     350        gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
     351
     352        ctx.globalCompositeOperation = "destination-out";
     353
     354        ctx.fillStyle = gradient;
     355        ctx.fillRect(x, y, w, h);
     356
     357        ctx.restore();
     358    },
     359
     360    drawSwatch: function(canvas, color)
     361    {
     362        var ctx = canvas.getContext("2d");
     363
     364        function drawSwatchSquare() {
     365            ctx.fillStyle = color;
     366            ctx.fillRect(0, 0, 13, 13);
     367
     368            var gradient = ctx.createLinearGradient(0, 0, 13, 13);
     369            gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
     370            gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
     371
     372            ctx.fillStyle = gradient;
     373            ctx.fillRect(0, 0, 13, 13);
     374
     375            gradient = ctx.createLinearGradient(13, 13, 0, 0);
     376            gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
     377            gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
     378
     379            ctx.fillStyle = gradient;
     380            ctx.fillRect(0, 0, 13, 13);
     381
     382            ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
     383            ctx.strokeRect(0.5, 0.5, 12, 12);
     384        }
     385
     386        ctx.clearRect(0, 0, 13, 24);
     387
     388        drawSwatchSquare();
    349389
    350390        ctx.save();
    351391
    352         ctx.translate(0, (13 * 2) - 1);
     392        ctx.translate(0, 25);
    353393        ctx.scale(1, -1);
    354394
    355         drawSwatchSquare(ctx, color);
     395        drawSwatchSquare();
    356396
    357397        ctx.restore();
    358398
    359         fadeOutRect(ctx, 0, 0 + 13, 13, 13, 0.5, 0.0);
    360 
    361         ctx.restore();
    362     },
    363 
    364     drawSummaryGraph: function(segments) {
     399        this.fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
     400    },
     401
     402    drawSummaryGraph: function(segments)
     403    {
    365404        if (!this.summaryGraphElement)
    366405            return;
    367406
    368         var ctx = this.summaryGraphElement.getContext('2d');
     407        if (!segments || !segments.length)
     408            segments = [{color: "white", value: 1}];
     409
     410        // Calculate the total of all segments.
     411        var total = 0;
     412        for (var i = 0; i < segments.length; ++i)
     413            total += segments[i].value;
     414
     415        // Calculate the percentage of each segment, rounded to the nearest percent.
     416        var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
     417
     418        // Calculate the total percentage.
     419        var percentTotal = 0;
     420        for (var i = 0; i < percents.length; ++i)
     421            percentTotal += percents[i];
     422
     423        // Make sure our percentage total is not greater-than 100, it can be greater
     424        // if we rounded up for a few segments.
     425        while (percentTotal > 100) {
     426            for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
     427                if (percents[i] > 1) {
     428                    --percents[i];
     429                    --percentTotal;
     430                }
     431            }
     432        }
     433
     434        // Make sure our percentage total is not less-than 100, it can be less
     435        // if we rounded down for a few segments.
     436        while (percentTotal < 100) {
     437            for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
     438                ++percents[i];
     439                ++percentTotal;
     440            }
     441        }
     442
     443        var ctx = this.summaryGraphElement.getContext("2d");
     444
    369445        var x = 0;
    370446        var y = 0;
    371         var width = 450;
    372         var height = 19;
    373 
    374         if (!segments || !segments.length)
    375             segments = [{color: "white", value: 1}];
     447        var w = 450;
     448        var h = 19;
     449        var r = (h / 2);
     450
     451        function drawPillShadow()
     452        {
     453            // This draws a line with a shadow that is offset away from the line. The line is stroked
     454            // twice with different X shadow offsets to give more feathered edges. Later we erase the
     455            // line with destination-out 100% transparent black, leaving only the shadow. This only
     456            // works if nothing has been drawn into the canvas yet.
     457
     458            ctx.beginPath();
     459            ctx.moveTo(x + 4, y + h - 3 - 0.5);
     460            ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
     461            ctx.closePath();
     462
     463            ctx.save();
     464
     465            ctx.shadowBlur = 2;
     466            ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
     467            ctx.shadowOffsetX = 3;
     468            ctx.shadowOffsetY = 5;
     469
     470            ctx.strokeStyle = "white";
     471            ctx.lineWidth = 1;
     472
     473            ctx.stroke();
     474
     475            ctx.shadowOffsetX = -3;
     476
     477            ctx.stroke();
     478
     479            ctx.restore();
     480
     481            ctx.save();
     482
     483            ctx.globalCompositeOperation = "destination-out";
     484            ctx.strokeStyle = "rgba(0, 0, 0, 1)";
     485            ctx.lineWidth = 1;
     486
     487            ctx.stroke();
     488
     489            ctx.restore();
     490        }
     491
     492        function drawPill()
     493        {
     494            // Make a rounded rect path.
     495            ctx.beginPath();
     496            ctx.moveTo(x, y + r);
     497            ctx.lineTo(x, y + h - r);
     498            ctx.quadraticCurveTo(x, y + h, x + r, y + h);
     499            ctx.lineTo(x + w - r, y + h);
     500            ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
     501            ctx.lineTo(x + w, y + r);
     502            ctx.quadraticCurveTo(x + w, y, x + w - r, y);
     503            ctx.lineTo(x + r, y);
     504            ctx.quadraticCurveTo(x, y, x, y + r);
     505            ctx.closePath();
     506
     507            // Clip to the rounded rect path.
     508            ctx.save();
     509            ctx.clip();
     510
     511            // Fill the segments with the associated color.
     512            var previousSegmentsWidth = 0;
     513            for (var i = 0; i < segments.length; ++i) {
     514                var segmentWidth = Math.round(w * percents[i] / 100);
     515                ctx.fillStyle = segments[i].color;
     516                ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
     517                previousSegmentsWidth += segmentWidth;
     518            }
     519
     520            // Draw the segment divider lines.
     521            ctx.lineWidth = 1;
     522            for (var i = 1; i < 20; ++i) {
     523                ctx.beginPath();
     524                ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
     525                ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
     526                ctx.closePath();
     527
     528                ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
     529                ctx.stroke();
     530
     531                ctx.beginPath();
     532                ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
     533                ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
     534                ctx.closePath();
     535
     536                ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
     537                ctx.stroke();
     538            }
     539
     540            // Draw the pill shading.
     541            var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
     542            lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
     543            lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
     544            lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
     545
     546            var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
     547            darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
     548            darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
     549            darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
     550
     551            ctx.fillStyle = darkGradient;
     552            ctx.fillRect(x, y, w, h);
     553
     554            ctx.fillStyle = lightGradient;
     555            ctx.fillRect(x, y, w, h);
     556
     557            ctx.restore();
     558        }
     559
     560        ctx.clearRect(x, y, w, (h * 2));
     561
     562        drawPillShadow();
     563        drawPill();
    376564
    377565        ctx.save();
    378566
    379         ctx.clearRect(x, y, width, (height * 2));
    380 
    381         drawShadowLine(ctx, x, y + height, width, 2);
    382         drawPill(ctx, x, y, width, height, height / 2, segments);
    383 
    384         ctx.save();
    385 
    386         ctx.translate(0, (height * 2) + 1);
     567        ctx.translate(0, (h * 2) + 1);
    387568        ctx.scale(1, -1);
    388569
    389         drawPill(ctx, x, y, width, height, height / 2, segments);
     570        drawPill();
    390571
    391572        ctx.restore();
    392573
    393         fadeOutRect(ctx, x, y + height + 2, width, height, 0.5, 0.0);
    394 
    395         ctx.restore();
     574        this.fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
    396575    },
    397576
     
    591770        ];
    592771
    593         function createSectionTable(section) {
     772        function createSectionTable(section)
     773        {
    594774            if (!section.info.length)
    595775                return;
     
    613793            });
    614794        }
     795
    615796        sections.forEach(createSectionTable, this);
    616797    },
     
    693874                this.tipBalloonContentElement.className = "tip-balloon-content";
    694875                this.tipBalloonElement.appendChild(this.tipBalloonContentElement);
    695                 var tipText = '';
     876                var tipText = "";
    696877                for (var id in this.resource.tips)
    697878                    tipText += this.resource.tips[id].message + "\n";
     
    8481029
    8491030WebInspector.TransferSizeCalculator.prototype.__proto__ = WebInspector.TimelineValueCalculator.prototype;
    850 
    851 function makeRoundedRectPath(ctx, x, y, w, h, r) {
    852     ctx.beginPath();
    853     ctx.moveTo(x, y + r);
    854     ctx.lineTo(x, y + h - r);
    855     ctx.quadraticCurveTo(x, y + h, x + r, y + h);
    856     ctx.lineTo(x + w - r, y + h);
    857     ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
    858     ctx.lineTo(x + w, y + r);
    859     ctx.quadraticCurveTo(x + w, y, x + w - r, y);
    860     ctx.lineTo(x + r, y);
    861     ctx.quadraticCurveTo(x, y, x, y + r);
    862     ctx.closePath();
    863 }
    864 
    865 function drawPillShading(ctx, x, y, w, h) {
    866     var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
    867     lightGradient.addColorStop(0.0, 'rgba(220, 220, 220, 0.6)');
    868     lightGradient.addColorStop(0.4, 'rgba(220, 220, 220, 0.2)');
    869     lightGradient.addColorStop(1.0, 'rgba(255, 255, 255, 0.0)');
    870 
    871     var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
    872     darkGradient.addColorStop(0.0, 'rgba(0, 0, 0, 0.0)');
    873     darkGradient.addColorStop(0.8, 'rgba(0, 0, 0, 0.2)');
    874     darkGradient.addColorStop(1.0, 'rgba(0, 0, 0, 0.5)');
    875 
    876     ctx.fillStyle = darkGradient;
    877     ctx.fillRect(x, y, w, h);
    878 
    879     ctx.fillStyle = lightGradient;
    880     ctx.fillRect(x, y, w, h);
    881 }
    882 
    883 function drawDividerLines(ctx, x, y, w, h) {
    884     ctx.save();
    885 
    886     ctx.lineWidth = 1;
    887 
    888     for (var i = 1; i < 20; ++i) {
    889         ctx.beginPath();
    890         ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
    891         ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
    892         ctx.closePath();
    893 
    894         ctx.strokeStyle = 'rgba(0, 0, 0, 0.2)';
    895         ctx.stroke();
    896 
    897         ctx.beginPath();
    898         ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
    899         ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
    900         ctx.closePath();
    901 
    902         ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
    903         ctx.stroke();
    904     }
    905 
    906     ctx.restore();
    907 }
    908 
    909 function fadeOutRect(ctx, x, y, w, h, a1, a2) {
    910     ctx.save();
    911 
    912     var gradient = ctx.createLinearGradient(x, y, x, y + h);
    913     gradient.addColorStop(0.0, 'rgba(0, 0, 0, ' + (1.0 - a1) + ')');
    914     gradient.addColorStop(0.8, 'rgba(0, 0, 0, ' + (1.0 - a2) + ')');
    915     gradient.addColorStop(1.0, 'rgba(0, 0, 0, 1.0)');
    916 
    917     ctx.globalCompositeOperation = 'destination-out';
    918 
    919     ctx.fillStyle = gradient;
    920     ctx.fillRect(x, y, w, h);
    921 
    922     ctx.restore();
    923 }
    924 
    925 function drawPillSegments(ctx, x, y, w, h, segments) {
    926     var total = 0;
    927     for (var i = 0; i < segments.length; ++i)
    928         total += segments[i].value;
    929 
    930     var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
    931     var percentTotal = 0;
    932     for (var i = 0; i < percents.length; ++i)
    933         percentTotal += percents[i];
    934 
    935     while (percentTotal > 100) {
    936         var difference = percentTotal - 100;
    937         for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
    938             if (percents[i] > 1) {
    939                 --percents[i];
    940                 --percentTotal;
    941             }
    942         }
    943     }
    944 
    945     var previousWidth = 0;
    946     for (var i = 0; i < segments.length; ++i) {
    947         var width = Math.round(w * percents[i] / 100);
    948         ctx.fillStyle = segments[i].color;
    949         ctx.fillRect(x + previousWidth, y, width, h);
    950         previousWidth += width;
    951     }
    952 }
    953 
    954 function drawPill(ctx, x, y, w, h, r, segments) {
    955     ctx.save();
    956 
    957     makeRoundedRectPath(ctx, x, y, w, h, r);
    958     ctx.clip();
    959 
    960     drawPillSegments(ctx, x, y, w, h, segments);
    961     drawDividerLines(ctx, x, y, w, h);
    962     drawPillShading(ctx, x, y, w, h);
    963 
    964     ctx.restore();
    965 }
    966 
    967 function drawShadowLine(ctx, x, y, w, h) {
    968     ctx.beginPath();
    969     ctx.moveTo(x + 1.5, y + 0.5);
    970     ctx.lineTo(x + w - 1.5, y + 0.5);
    971     ctx.closePath();
    972 
    973     ctx.strokeStyle = 'rgba(0, 0, 0, 0.2)';
    974     ctx.lineWidth = h;
    975     ctx.stroke();
    976 }
    977 
    978 function drawSwatchSquare(ctx, color) {
    979     ctx.save();
    980 
    981     ctx.fillStyle = color;
    982     ctx.fillRect(0, 0, 13, 13);
    983 
    984     var gradient = ctx.createLinearGradient(0, 0, 13, 13);
    985     gradient.addColorStop(0.0, 'rgba(255, 255, 255, 0.2)');
    986     gradient.addColorStop(1.0, 'rgba(255, 255, 255, 0.0)');
    987 
    988     ctx.fillStyle = gradient;
    989     ctx.fillRect(0, 0, 13, 13);
    990 
    991     gradient = ctx.createLinearGradient(13, 13, 0, 0);
    992     gradient.addColorStop(0.0, 'rgba(0, 0, 0, 0.2)');
    993     gradient.addColorStop(1.0, 'rgba(0, 0, 0, 0.0)');
    994 
    995     ctx.fillStyle = gradient;
    996     ctx.fillRect(0, 0, 13, 13);
    997 
    998     ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
    999     ctx.strokeRect(0.5, 0.5, 12, 12);
    1000 
    1001     ctx.restore();
    1002 }
Note: See TracChangeset for help on using the changeset viewer.