PHP Classes

File: vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig

Recommend this page to a friend!
  Classes of Murat Cileli   Papernic   vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig   Download  
File: vendor/symfony/symfony/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/time.html.twig
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Papernic
Manage documents colaboratively
Author: By
Last change:
Date: 7 years ago
Size: 20,813 bytes
 

Contents

Class file image Download
{% extends '@WebProfiler/Profiler/layout.html.twig' %} {% import _self as helper %} {% if colors is not defined %} {% set colors = { 'default': '#999', 'section': '#444', 'event_listener': '#00B8F5', 'event_listener_loading': '#00B8F5', 'template': '#66CC00', 'doctrine': '#FF6633', 'propel': '#FF6633', } %} {% endif %} {% block toolbar %} {% set total_time = collector.events|length ? '%.0f'|format(collector.duration) : 'n/a' %} {% set initialization_time = collector.events|length ? '%.0f'|format(collector.inittime) : 'n/a' %} {% set status_color = collector.events|length and collector.duration > 1000 ? 'yellow' : '' %} {% set icon %} {{ include('@WebProfiler/Icon/time.svg') }} <span class="sf-toolbar-value">{{ total_time }}</span> <span class="sf-toolbar-label">ms</span> {% endset %} {% set text %} <div class="sf-toolbar-info-piece"> <b>Total time</b> <span>{{ total_time }} ms</span> </div> <div class="sf-toolbar-info-piece"> <b>Initialization time</b> <span>{{ initialization_time }} ms</span> </div> {% endset %} {{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { link: profiler_url, status: status_color }) }} {% endblock %} {% block menu %} <span class="label"> <span class="icon">{{ include('@WebProfiler/Icon/time.svg') }}</span> <strong>Performance</strong> </span> {% endblock %} {% block panel %} <h2>Performance metrics</h2> <div class="metrics"> <div class="metric"> <span class="value">{{ '%.0f'|format(collector.duration) }} <span class="unit">ms</span></span> <span class="label">Total execution time</span> </div> <div class="metric"> <span class="value">{{ '%.0f'|format(collector.inittime) }} <span class="unit">ms</span></span> <span class="label">Symfony initialization</span> </div> {% if profile.children|length > 0 %} <div class="metric"> <span class="value">{{ profile.children|length }}</span> <span class="label">Sub-Requests</span> </div> {% set subrequests_time = 0 %} {% for child in profile.children %} {% set subrequests_time = subrequests_time + child.getcollector('time').events.__section__.duration %} {% endfor %} <div class="metric"> <span class="value">{{ subrequests_time }} <span class="unit">ms</span></span> <span class="label">Sub-Requests time</span> </div> {% endif %} {% if profile.collectors.memory %} <div class="metric"> <span class="value">{{ '%.2f'|format(profile.collectors.memory.memory / 1024 / 1024) }} <span class="unit">MB</span></span> <span class="label">Peak memory usage</span> </div> {% endif %} </div> <h2>Execution timeline</h2> {% if collector.events is empty %} <div class="empty"> <p>No timing events have been recorded. Are you sure that debugging is enabled in the kernel?</p> </div> {% else %} {{ block('panelContent') }} {% endif %} {% endblock %} {% block panelContent %} <form id="timeline-control" action="" method="get"> <input type="hidden" name="panel" value="time"> <label for="threshold">Threshold</label> <input type="number" size="3" name="threshold" id="threshold" value="3" min="0"> ms <span class="help">(timeline only displays events with a duration longer than this threshold)</span> </form> {% if profile.parent %} <h3> Sub-Request {{ profile.getcollector('request').requestattributes.get('_controller') }} <small> {{ collector.events.__section__.duration }} ms <a class="newline" href="{{ path('_profiler', { token: profile.parent.token, panel: 'time' }) }}">Return to parent request</a> </small> </h3> {% elseif profile.children|length > 0 %} <h3> Main Request <small>{{ collector.events.__section__.duration }} ms</small> </h3> {% endif %} {{ helper.display_timeline('timeline_' ~ token, collector.events, colors) }} {% if profile.children|length %} <p class="help">Note: sections with a striped background correspond to sub-requests.</p> <h3>Sub-requests <small>({{ profile.children|length }})</small></h3> {% for child in profile.children %} {% set events = child.getcollector('time').events %} <h4> <a href="{{ path('_profiler', { token: child.token, panel: 'time' }) }}">{{ child.getcollector('request').requestattributes.get('_controller') }}</a> <small>{{ events.__section__.duration }} ms</small> </h4> {{ helper.display_timeline('timeline_' ~ child.token, events, colors) }} {% endfor %} {% endif %} <script>{% autoescape 'js' %}//<![CDATA[ /** * In-memory key-value cache manager */ var cache = new function() { "use strict"; var dict = {}; this.get = function(key) { return dict.hasOwnProperty(key) ? dict[key] : null; }; this.set = function(key, value) { dict[key] = value; return value; }; }; /** * Query an element with a CSS selector. * * @param string selector a CSS-selector-compatible query string. * * @return DOMElement|null */ function query(selector) { "use strict"; var key = 'SELECTOR: ' + selector; return cache.get(key) || cache.set(key, document.querySelector(selector)); } /** * Canvas Manager */ function CanvasManager(requests, maxRequestTime) { "use strict"; var _drawingColors = {{ colors|json_encode|raw }}, _storagePrefix = 'timeline/', _threshold = 1, _requests = requests, _maxRequestTime = maxRequestTime; /** * Check whether this event is a child event. * * @return true if it is. */ function isChildEvent(event) { return '__section__.child' === event.name; } /** * Check whether this event is categorized in 'section'. * * @return true if it is. */ function isSectionEvent(event) { return 'section' === event.category; } /** * Get the width of the container. */ function getContainerWidth() { return query('#collector-content h2').clientWidth; } /** * Draw one canvas. * * @param request the request object * @param max <subjected for removal> * @param threshold the threshold (lower bound) of the length of the timeline (in milliseconds). * @param width the width of the canvas. */ this.drawOne = function(request, max, threshold, width) { "use strict"; var text, ms, xc, drawableEvents, mainEvents, elementId = 'timeline_' + request.id, canvasHeight = 0, gapPerEvent = 38, colors = _drawingColors, space = 10.5, ratio = (width - space * 2) / max, h = space, x = request.left * ratio + space, // position canvas = cache.get(elementId) || cache.set(elementId, document.getElementById(elementId)), ctx = canvas.getContext("2d"), scaleRatio, devicePixelRatio; // Filter events whose total time is below the threshold. drawableEvents = request.events.filter(function(event) { return event.duration >= threshold; }); canvasHeight += gapPerEvent * drawableEvents.length; // For retina displays so text and boxes will be crisp devicePixelRatio = window.devicePixelRatio == "undefined" ? 1 : window.devicePixelRatio; scaleRatio = devicePixelRatio / 1; canvas.width = width * scaleRatio; canvas.height = canvasHeight * scaleRatio; canvas.style.width = width + 'px'; canvas.style.height = canvasHeight + 'px'; ctx.scale(scaleRatio, scaleRatio); ctx.textBaseline = "middle"; ctx.lineWidth = 0; // For each event, draw a line. ctx.strokeStyle = "#CCC"; drawableEvents.forEach(function(event) { event.periods.forEach(function(period) { var timelineHeadPosition = x + period.start * ratio; if (isChildEvent(event)) { /* create a striped background dynamically */ var img = new Image(); img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKBAMAAAB/HNKOAAAAIVBMVEX////w8PDd7h7d7h7d7h7d7h7w8PDw8PDw8PDw8PDw8PAOi84XAAAAKUlEQVQImWNI71zAwMBQMYuBgY0BxExnADErGEDMTgYQE8hnAKtCZwIAlcMNSR9a1OEAAAAASUVORK5CYII='; var pattern = ctx.createPattern(img, 'repeat'); ctx.fillStyle = pattern; ctx.fillRect(timelineHeadPosition, 0, (period.end - period.start) * ratio, canvasHeight); } else if (isSectionEvent(event)) { var timelineTailPosition = x + period.end * ratio; ctx.beginPath(); ctx.moveTo(timelineHeadPosition, 0); ctx.lineTo(timelineHeadPosition, canvasHeight); ctx.moveTo(timelineTailPosition, 0); ctx.lineTo(timelineTailPosition, canvasHeight); ctx.fill(); ctx.closePath(); ctx.stroke(); } }); }); // Filter for main events. mainEvents = drawableEvents.filter(function(event) { return !isChildEvent(event) }); // For each main event, draw the visual presentation of timelines. mainEvents.forEach(function(event) { h += 8; // For each sub event, ... event.periods.forEach(function(period) { // Set the drawing style. ctx.fillStyle = colors['default']; ctx.strokeStyle = colors['default']; if (colors[event.name]) { ctx.fillStyle = colors[event.name]; ctx.strokeStyle = colors[event.name]; } else if (colors[event.category]) { ctx.fillStyle = colors[event.category]; ctx.strokeStyle = colors[event.category]; } // Draw the timeline var timelineHeadPosition = x + period.start * ratio; if (!isSectionEvent(event)) { ctx.fillRect(timelineHeadPosition, h + 3, 2, 8); ctx.fillRect(timelineHeadPosition, h, (period.end - period.start) * ratio || 2, 6); } else { var timelineTailPosition = x + period.end * ratio; ctx.beginPath(); ctx.moveTo(timelineHeadPosition, h); ctx.lineTo(timelineHeadPosition, h + 11); ctx.lineTo(timelineHeadPosition + 8, h); ctx.lineTo(timelineHeadPosition, h); ctx.fill(); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.moveTo(timelineTailPosition, h); ctx.lineTo(timelineTailPosition, h + 11); ctx.lineTo(timelineTailPosition - 8, h); ctx.lineTo(timelineTailPosition, h); ctx.fill(); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.moveTo(timelineHeadPosition, h); ctx.lineTo(timelineTailPosition, h); ctx.lineTo(timelineTailPosition, h + 2); ctx.lineTo(timelineHeadPosition, h + 2); ctx.lineTo(timelineHeadPosition, h); ctx.fill(); ctx.closePath(); ctx.stroke(); } }); h += 30; ctx.beginPath(); ctx.strokeStyle = "#E0E0E0"; ctx.moveTo(0, h - 10); ctx.lineTo(width, h - 10); ctx.closePath(); ctx.stroke(); }); h = space; // For each event, draw the label. mainEvents.forEach(function(event) { ctx.fillStyle = "#444"; ctx.font = "12px sans-serif"; text = event.name; ms = " " + (event.duration < 1 ? event.duration : parseInt(event.duration, 10)) + " ms / " + event.memory + " MB"; if (x + event.starttime * ratio + ctx.measureText(text + ms).width > width) { ctx.textAlign = "end"; ctx.font = "10px sans-serif"; ctx.fillStyle = "#777"; xc = x + event.endtime * ratio - 1; ctx.fillText(ms, xc, h); xc -= ctx.measureText(ms).width; ctx.font = "12px sans-serif"; ctx.fillStyle = "#222"; ctx.fillText(text, xc, h); } else { ctx.textAlign = "start"; ctx.font = "13px sans-serif"; ctx.fillStyle = "#222"; xc = x + event.starttime * ratio + 1; ctx.fillText(text, xc, h); xc += ctx.measureText(text).width; ctx.font = "11px sans-serif"; ctx.fillStyle = "#777"; ctx.fillText(ms, xc, h); } h += gapPerEvent; }); }; this.drawAll = function(width, threshold) { "use strict"; width = width || getContainerWidth(); threshold = threshold || this.getThreshold(); var self = this; _requests.forEach(function(request) { self.drawOne(request, _maxRequestTime, threshold, width); }); }; this.getThreshold = function() { var threshold = Sfjs.getPreference(_storagePrefix + 'threshold'); if (null === threshold) { return _threshold; } _threshold = parseInt(threshold); return _threshold; }; this.setThreshold = function(threshold) { _threshold = threshold; Sfjs.setPreference(_storagePrefix + 'threshold', threshold); return this; }; } function canvasAutoUpdateOnResizeAndSubmit(e) { e.preventDefault(); canvasManager.drawAll(); } function canvasAutoUpdateOnThresholdChange(e) { canvasManager .setThreshold(query('input[name="threshold"]').value) .drawAll(); } var requests_data = { "max": {{ "%F"|format(collector.events.__section__.endtime) }}, "requests": [ {{ helper.dump_request_data(token, profile, collector.events, collector.events.__section__.origin) }} {% if profile.children|length %} , {% for child in profile.children %} {{ helper.dump_request_data(child.token, child, child.getcollector('time').events, collector.events.__section__.origin) }}{{ loop.last ? '' : ',' }} {% endfor %} {% endif %} ] }; var canvasManager = new CanvasManager(requests_data.requests, requests_data.max); query('input[name="threshold"]').value = canvasManager.getThreshold(); canvasManager.drawAll(); // Update the colors of legends. var timelineLegends = document.querySelectorAll('.sf-profiler-timeline > .legends > span[data-color]'); for (var i = 0; i < timelineLegends.length; ++i) { var timelineLegend = timelineLegends[i]; timelineLegend.style.borderLeftColor = timelineLegend.getAttribute('data-color'); } // Bind event handlers var elementTimelineControl = query('#timeline-control'), elementThresholdControl = query('input[name="threshold"]'); window.onresize = canvasAutoUpdateOnResizeAndSubmit; elementTimelineControl.onsubmit = canvasAutoUpdateOnResizeAndSubmit; elementThresholdControl.onclick = canvasAutoUpdateOnThresholdChange; elementThresholdControl.onchange = canvasAutoUpdateOnThresholdChange; elementThresholdControl.onkeyup = canvasAutoUpdateOnThresholdChange; window.setTimeout(function() { canvasAutoUpdateOnThresholdChange(null); }, 50); //]]>{% endautoescape %}</script> {% endblock %} {% macro dump_request_data(token, profile, events, origin) %} {% autoescape 'js' %} {% from _self import dump_events %} { "id": "{{ token }}", "left": {{ "%F"|format(events.__section__.origin - origin) }}, "events": [ {{ dump_events(events) }} ] } {% endautoescape %} {% endmacro %} {% macro dump_events(events) %} {% autoescape 'js' %} {% for name, event in events %} {% if '__section__' != name %} { "name": "{{ name }}", "category": "{{ event.category }}", "origin": {{ "%F"|format(event.origin) }}, "starttime": {{ "%F"|format(event.starttime) }}, "endtime": {{ "%F"|format(event.endtime) }}, "duration": {{ "%F"|format(event.duration) }}, "memory": {{ "%.1F"|format(event.memory / 1024 / 1024) }}, "periods": [ {%- for period in event.periods -%} {"start": {{ "%F"|format(period.starttime) }}, "end": {{ "%F"|format(period.endtime) }}}{{ loop.last ? '' : ', ' }} {%- endfor -%} ] }{{ loop.last ? '' : ',' }} {% endif %} {% endfor %} {% endautoescape %} {% endmacro %} {% macro display_timeline(id, events, colors) %} <div class="sf-profiler-timeline"> <div class="legends"> {% for category, color in colors %} <span data-color="{{ color }}">{{ category }}</span> {% endfor %} </div> <canvas width="680" height="" id="{{ id }}" class="timeline"></canvas> </div> {% endmacro %}