New perf dashboard should have the ability to overlay moving average with an envelope
[WebKit-https.git] / Websites / perf.webkit.org / public / v2 / index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4     <meta charset="utf-8">
5     <title>WebKit Performance Monitor (Beta)</title>
6
7     <link rel="prefetch" href="../data/manifest.json">
8     <script type="application/json" src="../data/manifest.json"></script>
9
10     <link rel="stylesheet" href="app.css">
11     <link rel="stylesheet" href="chart-pane.css">
12
13     <script src="js/jquery.min.js" defer></script>
14     <script src="js/jquery.min.js" defer></script>
15     <script src="js/handlebars.js" defer></script>
16     <script src="js/ember.js" defer></script>
17     <script src="js/ember-data.js" defer></script>
18     <script src="js/d3/d3.min.js" defer></script>
19     <script src="js/statistics.js" defer></script>
20     <script src="data.js" defer></script>
21     <script src="app.js" defer></script>
22     <script src="manifest.js" defer></script>
23     <script src="analysis.js" defer></script>
24     <script src="popup.js" defer></script>
25     <script src="interactive-chart.js" defer></script>
26     <script src="commits-viewer.js" defer></script>
27
28     <script type="text/x-handlebars" data-template-name="dashboard">
29         <header id="header">
30             {{partial "navbar"}}
31             {{view App.NumberOfDaysControlView tagName="ul" numberOfDays=numberOfDays}}
32             <ul class="controls">
33                 <li>
34                     <a href="#" class="control-button" {{action toggleEditMode}}>
35                         {{#if controller.editMode}}
36                             Finish editing
37                         {{else}}
38                             Edit
39                         {{/if}}
40                     </a>
41                 </li>
42             </ul>
43         </header>
44
45         <table {{bind-attr class=":dashboard editMode:editMode:readonly"}}>
46         <thead>
47             <tr>
48                 <td></td>
49                 {{#each headerColumns}}
50                     {{#if controller.editMode}}
51                         <th>
52                             <a href="#" title="Remove column" {{action "removeColumn" index}}>
53                                 {{partial "close-button"}}
54                             </a>
55                             {{input value=label}}
56                         </th>
57                     {{else}}
58                         <th>{{label}}</th>
59                     {{/if}}
60                 {{/each}}
61                 {{#if controller.editMode}}
62                     <td>{{input value=newColumnHeader action="addColumn" placeholder="Add a column"}}</td>
63                 {{/if}}
64             </tr>
65         </thead>
66         <tbody>
67             {{#each rows}}
68                 <tr>
69                     {{#if controller.editMode}}
70                         <th>
71                             <a href="#" title="Remove row" {{action "removeRow" this}}>
72                                 {{partial "close-button"}}
73                             </a>
74                             {{input value=header}}
75                         </th>
76                     {{else}}
77                         <th><span class="label">{{header}}</span></th>
78                     {{/if}}
79                     {{#each cells}}
80                         <td>
81                             {{#if empty}}
82                                 {{#if controller.editMode}}
83                                     {{view App.PopupView list=pickerData label='Choose'}}
84                                 {{/if}}
85                             {{else}}
86                                 {{#if chartData}}
87                                     <div class="dashboard-status">
88                                         {{#if latestStatus}}
89                                             {{latestStatus.currentValue}} {{chartData.unit}}
90                                             {{#if latestStatus.label}}
91                                                 <span {{bind-attr class=":status-label latestStatus.className"}}>{{latestStatus.label}}</span>
92                                             {{/if}}
93                                         {{/if}}
94                                     </div>
95                                     {{#link-to 'charts' (query-params paneList=paneList since=controller.since)}}
96                                         {{interactive-chart
97                                             chartData=chartData
98                                             domain=controller.sharedDomain
99                                             enableSelection=false}}
100                                     {{/link-to}}
101                                 {{else}}
102                                     {{#if failure}}
103                                         <div class="failure">{{failure}}</div>
104                                     {{else}}
105                                         <div class="progress">{{partial "spinner"}}</div>
106                                     {{/if}}
107                                 {{/if}}
108                                 {{#if controller.editMode}}
109                                     <a href="#" title="Reset pane" class="reset" {{action "resetPane" this}}>
110                                         {{partial "close-button"}}
111                                     </a>
112                                 {{/if}}
113                             {{/if}}
114                         </td>
115                     {{/each}}
116                     {{#if controller.editMode}}
117                         <td></td>
118                     {{/if}}
119                 </tr>
120             {{/each}}
121             {{#if controller.editMode}}
122                 <tr>
123                     <td>{{input value=newRowHeader action="addRow" placeholder="Add a row"}}</td>
124                     {{#each emptyRow}}
125                         <td></td>
126                     {{/each}}
127                     <td></td>
128                 </tr>
129             {{/if}}
130         </tbody>
131         </table>
132     </script>
133
134     <script type="text/x-handlebars" data-template-name="charts">
135         <header id="header">
136             {{partial "navbar"}}
137             <ul class="controls">
138                 <li>{{view App.PopupView list=platforms label='Add pane'}}</li>
139             </ul>
140             <ul class="controls">
141                 <li>{{view App.StartTimeSliderView startTime=startTime oldestStartTime=oldestStartTime}}</li>
142             </ul>
143         </header>
144
145         {{#each panes itemController="pane"}}
146             <section class="chart-pane" tabindex="0">
147                 <header>
148                     <h1 {{action "toggleDetails"}}>{{metric.fullName}} - {{ platform.name}}</h1>
149                     <a href="#" title="Close" class="close-button" {{action "close"}}>{{partial "close-button"}}</a>
150                     {{#if movingAverageStrategies}}
151                         <a href="#" title="Statistical Tools" class="stat-button" {{action "toggleStatPane"}}>{{partial "stat-button"}}</a>
152                     {{/if}}
153                     {{#if App.Manifest.bugTrackers}}
154                         <a href="#" title="Analysis" class="bugs-button" {{action "toggleBugsPane"}}>
155                             {{partial "analysis-button"}}
156                         </a>
157                     {{/if}}
158                     {{#if App.Manifest.repositoriesWithReportedCommits}}
159                         <a href="#" title="Search" class="search-button" {{action "toggleSearchPane"}}>{{partial "search-button"}}</a>
160                     {{/if}}
161                 </header>
162
163                 <div class="body">
164                     <div class="svg-container">
165                     {{#if chartData}}
166                         {{interactive-chart
167                             chartData=chartData
168                             ranges=analyticRanges
169                             domain=mainPlotDomain
170                             interactive=true
171                             chartPointRadius=2
172                             currentItem=currentItem
173                             currentTime=sharedTime
174                             selectedItem=selectedItem
175                             highlightedItems=highlightedItems
176                             rangeRoute="analysisTask"
177                             selection=timeRange
178                             selectedPoints=selectedPoints
179                             markedPoints=markedPoints
180                             zoom="zoomed"}}
181                     {{else}}
182                         {{#if failure}}
183                             <div class="failure">{{failure}}</div>
184                         {{else}}
185                             <div class="progress">{{partial "spinner"}}</div>
186                         {{/if}}
187                     {{/if}}
188                     </div>
189                     <div class="details">
190                         <div class="overview">
191                         {{#if chartData}}
192                             {{interactive-chart
193                                 chartData=chartData
194                                 showYAxis=false
195                                 domain=overviewDomain
196                                 selection=overviewSelection}}
197                         {{/if}}
198                         </div>
199                         {{#if details}}
200                             {{partial "chart-details"}}
201                         {{/if}}
202                     </div>
203                 </div>
204
205                 <div {{bind-attr class=":popup-pane :analysis-pane showingAnalysisPane::hidden"}}>
206                     <label>Name: {{input type=text value=newAnalysisTaskName}}</label>
207                     <button {{action "createAnalysisTask"}} {{bind-attr disabled=cannotAnalyze}}>Analyze</button>
208                 </div>
209
210                 <form {{bind-attr class=":popup-pane :search-pane showingSearchPane::hidden"}}>
211                     <span class="repositories">
212                         {{view Ember.Select
213                             content=App.Manifest.repositoriesWithReportedCommits
214                             optionValuePath='content.id'
215                             optionLabelPath='content.name'
216                             selection=commitSearchRepository}}
217                     </span>
218                     {{input action="searchCommit" placeholder="Name or email" value=commitSearchKeyword}}
219                 </form>
220
221                 {{partial "stat-pane"}}
222             </section>
223         {{/each}}
224     </script>
225
226     <script type="text/x-handlebars" data-template-name="components/interactive-chart">
227         {{#if interactive}}
228             <div class="selection-toolbar" style="display: none;">
229                 <a href="#" class="button" {{action "zoom"}}>
230                     <svg class="zoom" viewBox="0 0 100 100">
231                         <g stroke-width="0" stroke="none">
232                             <polygon points="25,25 5,50 25,75"/>
233                             <polygon points="75,25 95,50 75,75"/>
234                         </g>
235                         <line x1="20" y1="50" x2="80" y2="50" stroke-width="10"></line>
236                     </svg>
237                 </a>
238             </div>
239         {{/if}}
240         <div class="rangeBarsContainerInlineStyle">
241             {{#each rangeBars}}
242                 {{#link-to linkRoute linkId title=label}}
243                     <span class="rangeBar" {{bind-attr style=inlineStyle}}></span>
244                 {{/link-to}}
245             {{/each}}
246         </div>
247     </script>
248
249     <script type="text/x-handlebars" data-template-name="chart-details">
250     <div class="details-table-container">
251         <table class="details-table">
252             <tbody class="bugs">
253             {{#each details.bugTrackers}}
254                 {{#if bugs}}
255                     <tr>
256                         <th>{{label}}</th>
257                         <td>
258                             {{#each bugs}}
259                                 <a {{bind-attr href=bugUrl}} target="_blank">{{bugNumber}}</a>
260                             {{/each}}
261                         </td>
262                     </tr>
263                 {{/if}}
264             {{/each}}
265             </tbody>
266             <tbody class="status">
267                 <tr>
268                     <th>Current</th>
269                     <td>
270                         {{details.status.currentValue}} {{chartData.unit}}
271                         {{#if details.status.valueDelta}}
272                             ({{details.status.valueDelta}} {{chartData.unit}})
273                         {{/if}}
274                         {{#if details.status.label}}
275                             <br>
276                             <span {{bind-attr class=details.status.className}}>{{details.status.label}}</span>
277                         {{/if}}
278                     </td>
279                 </tr>
280             </tbody>
281             <tbody>
282             {{#if details.buildNumber}}
283                 <tr>
284                     <th>Build</th>
285                     <td>
286                         {{#if details.buildURL}}
287                             <a {{bind-attr href=details.buildURL}} target="_blank">{{details.buildNumber}}</a>
288                         {{else}}
289                             {{details.buildNumber}}
290                         {{/if}}
291                         ({{details.buildTime}})
292                     </td>
293                 </tr>
294             {{/if}}
295             {{#each details.revisions}}
296                 <tr>
297                     <th>{{name}}</th>
298                     <td>
299                         {{#if url}}
300                             <a {{bind-attr href=url}} target="_blank">{{label}}</a>
301                         {{else}}
302                             {{label}}
303                         {{/if}}
304                     </td>
305                 </tr>
306             {{/each}}
307             </tbody>
308         </table>
309         <div class="commits">
310             {{#each details.revisions}}
311                 {{commits-viewer repository=repository revisionInfo=this caption=name}}
312             {{/each}}
313         </div>
314     </div>
315     </script>
316
317     <script type="text/x-handlebars" data-template-name="components/commits-viewer">
318     {{#if commits}}
319         <table {{bind-attr class=":commits-viewer visible::hidden"}}>
320             {{#if caption}}
321                 <caption {{action toggleVisibility}}>{{caption}} commits</caption>
322             {{/if}}
323             {{#if visible}}
324                 <tbody>
325                     {{#each commits}}
326                         <tr>
327                             <th>
328                                 {{#if url}}
329                                     <a {{bind-attr href=url}} target="_blank">{{revision}}</a>
330                                 {{else}}
331                                     {{revision}}
332                                 {{/if}}
333                             </th>
334                             <th>{{author}}</th>
335                             <td>{{message}}</td>
336                         </tr>
337                     {{/each}}
338                 </tbody>
339             {{/if}}
340         </table>
341     {{/if}}
342     </script>
343
344     <script type="text/x-handlebars" data-template-name="close-button">
345         <svg class="close-button icon-button" viewBox="0 0 100 100">
346             <g stroke="black" stroke-width="10">
347                 <circle cx="50" cy="50" r="45" fill="transparent"/>
348                 <polygon points="30,30 70,70" />
349                 <polygon points="30,70 70,30" />
350             </g>
351         </svg>
352     </script>
353
354     <script type="text/x-handlebars" data-template-name="stat-button">
355         <svg class="stat-button icon-button" viewBox="10 0 110 100">
356             <g stroke="none" stroke-width="0" fill="black">
357                 <path id="upper-sigma" d="M 5 5 H 95 V 40 h -10 c -5 -20 -5 -20 -25 -20 H 35 L 60 50 l -20 0" />
358                 <use xlink:href="#upper-sigma" transform="translate(0, 100) scale(1, -1)" />
359             </g>
360         </svg>
361     </script>
362
363     <script type="text/x-handlebars" data-template-name="stat-pane">
364         <section {{bind-attr class=":popup-pane :stat-pane showingStatPane::hidden"}}>
365             <section class="stat-option">
366                 <h1>Moving average</h1>
367                 <label>Type: {{view Ember.Select
368                     content=movingAverageStrategies
369                     optionValuePath='content'
370                     optionLabelPath='content.label'
371                     selection=chosenMovingAverageStrategy}}</label>
372                 {{#each chosenMovingAverageStrategy.parameterList}}
373                     <label>{{label}}: {{input type="number" value=value min=min max=max step=step}}</label>
374                 {{/each}}
375             </section>
376             {{#if chosenMovingAverageStrategy.execute}}
377                 <section class="stat-option">
378                     <h1>Envelope</h1>
379                     <label>Type: {{view Ember.Select
380                         content=envelopingStrategies
381                         optionValuePath='content'
382                         optionLabelPath='content.label'
383                         selection=chosenEnvelopingStrategy}}</label>
384                     {{#if chosenEnvelopingStrategy.description}}
385                         <p class="description">{{chosenEnvelopingStrategy.description}}</p>
386                     {{/if}}
387                     {{#each chosenEnvelopingStrategy.parameterList}}
388                         <label>{{label}}: <input type="number" {{bind-attr value=value min=min max=max step=step}}></label>
389                     {{/each}}
390                 </section>
391             {{/if}}
392         </section>
393     </script>
394
395     <script type="text/x-handlebars" data-template-name="analysis-button">
396         <svg class="analysis-button icon-button" viewBox="0 0 100 100">
397             <g stroke="black" fill="black" stroke-width="15">
398                 <circle cx="50" cy="50" r="40" fill="transparent"/>
399                 <line x1="50" y1="25" x2="50" y2="55"/>
400                 <circle cx="50" cy="67.5" r="10" stroke="none"/>
401             </g>
402         </svg>
403     </script>
404
405     <script type="text/x-handlebars" data-template-name="search-button">
406         <svg class="search-button icon-button" viewBox="0 0 100 100">
407             <g stroke="black" stroke-width="15">
408                 <circle cx="60" cy="40" r="30" fill="transparent"/>
409                 <line x1="10" y1="90" x2="40" y2="60"/>
410             </g>
411         </svg>
412     </script>
413
414     <script type="text/x-handlebars" data-template-name="spinner">
415         <svg class="spinner" viewBox="0 0 100 100">
416             <line x1="10" y1="50" x2="30" y2="50" stroke="black" stroke-width="10" stroke-linecap="round"/>
417             <line x1="21.72" y1="21.72" x2="35.86" y2="35.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
418             <line x1="50" y1="10" x2="50" y2="30" stroke="black" stroke-width="10" stroke-linecap="round"/>
419             <line x1="78.28" y1="21.72" x2="64.14" y2="35.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
420             <line x1="70" y1="50" x2="90" y2="50" stroke="black" stroke-width="10" stroke-linecap="round"/>
421             <line x1="65.86" y1="65.86" x2="78.28" y2="78.28" stroke="black" stroke-width="10" stroke-linecap="round"/>
422             <line x1="50" y1="70" x2="50" y2="90" stroke="black" stroke-width="10" stroke-linecap="round"/>
423             <line x1="21.72" y1="78.28" x2="35.86" y2="65.86" stroke="black" stroke-width="10" stroke-linecap="round"/>
424         </svg>
425     </script>
426
427     <script type="text/x-handlebars" data-template-name="navbar">
428         <nav id="navigation" role="navigation">
429             <h1><a href="#">WebKit Perf Monitor</a></h1>
430             <ul>
431                 {{#each App.Manifest.dashboards}}
432                     {{#if name}}
433                         {{#link-to 'dashboard' name tagName='li'}}
434                             {{#link-to 'dashboard' name}}{{label}}{{/link-to}}
435                         {{/link-to}}
436                     {{/if}}
437                 {{/each}}
438                 {{#link-to 'charts' tagName='li'}}
439                     {{#link-to 'charts'}}Charts{{/link-to}}
440                 {{/link-to}}
441                 {{#link-to 'analysis' tagName='li'}}
442                     {{#link-to 'analysis'}}Analysis{{/link-to}}
443                 {{/link-to}}
444             </ul>
445         </nav>
446     </script>
447
448     <script type="text/x-handlebars" data-template-name="number-of-days-controls">
449         <li class="numberOfDaysIs1">
450             <a href="#" class="control-button" {{action "setNumberOfDays" 1}}>1D</a>
451         </li>
452         <li class="numberOfDaysIs7">
453             <a href="#" class="control-button" {{action "setNumberOfDays" 7}}>1W</a>
454         </li>
455         <li class="numberOfDaysIs30">
456             <a href="#" class="control-button" {{action "setNumberOfDays" 30}}>1M</a>
457         </li>
458         <li class="numberOfDaysIs90">
459             <a href="#" class="control-button" {{action "setNumberOfDays" 90}}>3M</a>
460         </li>
461         <li class="numberOfDaysIs183">
462             <a href="#" class="control-button" {{action "setNumberOfDays" 183}}>6M</a>
463         </li>
464         <li class="numberOfDaysIs365">
465             <a href="#" class="control-button" {{action "setNumberOfDays" 365}}>1Y</a>
466         </li>
467     </script>
468
469     <script type="text/x-handlebars" data-template-name="start-time-slider">
470         <label><input type="range"> <span class="numberOfDays">X</span> days</label>
471     </script>
472
473     <script type="text/x-handlebars" data-template-name="popup">
474         <span class="label">{{view App.PopupButtonView tagName="a" label=view.label }}</span>
475         {{view view.popupListContainerView viewName="popupListContainerViewInstance"}}
476     </script>
477
478     <script type="text/x-handlebars" data-template-name="popup-list">
479         {{#each view.list}}
480             {{#if isSeparator}}
481                 <li><hr></li>
482             {{else }} {{#if children}}
483                 <li>{{view App.PopupView list=children label=label}}</li>
484             {{else}}
485                 <li>
486                     {{#if actionName}}
487                         <a href="#" class="label" {{action actionName actionArgument}}>{{label}}</a>
488                     {{else}}
489                         <a class="label">{{label}}</a>
490                     {{/if}}
491                 </li>
492             {{/if}} {{/if}}
493         {{/each}}
494     </script>
495
496     <script type="text/x-handlebars" data-template-name="analysis">
497         <header id="header">
498             {{partial "navbar"}}
499         </header>
500
501         <table id="analysis-tasks">
502             <thead>
503                 <tr>
504                     <td>ID</td>
505                     <td>Name</td>
506                     <td>Created at</td>
507                 </tr>
508             </thead>
509             <tbody>
510                 {{#each model.tasks}}
511                     <tr>
512                         <td>{{#link-to 'analysisTask' id}}{{id}}{{/link-to}}</td>
513                         <td>{{name}}</td>
514                         <td>{{createdAt}}</td>
515                     </tr>
516                 {{/each}}
517             </tbody>
518         </table>
519     </script>
520
521     <script type="text/x-handlebars" data-template-name="analysisTask">
522         <header id="header">
523             {{partial "navbar"}}
524         </header>
525
526         <h2 id="analysis-task-title">{{label}}</h2>
527         {{#if platform.label}}
528             <h3 id="analysis-task-testname">{{metric.fullName}} - {{platform.label}}</h3>
529         {{/if}}
530
531         {{#if chartData}}
532             <section class="analysis-chart-pane chart-pane">
533                 <div class="svg-container">
534                     {{interactive-chart
535                         chartData=chartData
536                         enableSelection=false
537                         chartPointRadius=2
538                         domain=chartDomain
539                         highlightedItems=highlightedItems}}
540                 </div>
541                 <div class="details">
542                     <table class="analysis-bugs">
543                         <tbody>
544                             {{#each bugTrackers}}
545                                 <tr>
546                                     <th>{{label}}</th>
547                                     <td>
548                                         <form {{action "associateBug" this editedBugNumber on="submit"}}>
549                                             {{input type=text value=editedBugNumber}}
550                                         </form>
551                                     </td>
552                                 </tr>
553                             {{/each}}
554                         </tbody>
555                     </table>
556                     <table>
557                         <tbody>
558                             {{#each analysisPoints}}
559                                 <tr><td>{{label}}</td><td>{{value}}</td></tr>
560                             {{/each}}
561                         </tbody>
562                     </table>
563                 </div>
564             </section>
565             {{#each testGroups}}
566                 <section class="analysis-group">
567                     <table>
568                         <caption>{{name}}</caption>
569                         <thead>
570                             <tr>
571                                 <td>Order</td>
572                                 <td>Configuration</td>
573                                 <td>Status</td>
574                                 <td>Build</td>
575                                 <td>{{../metric.fullName}}</td>
576                             </tr>
577                         </thead>
578                         <tbody>
579                             {{#each buildRequests}}
580                                 <tr>
581                                     <td>{{orderLabel}}</td>
582                                     <td>{{config}}</td>
583                                     <td>{{#if url}}{{#link-to url}}{{statusLabel}}{{/link-to}}{{else}}{{statusLabel}}{{/if}}</td>
584                                     <td>{{build}}</td>
585                                     <td>{{mean}}</td>
586                                 </tr>
587                             {{/each}}
588                         </tbody>
589                     </table>
590                 </section>
591             {{/each}}
592
593             {{#if roots}}
594             <form method="POST" {{action "createTestGroup" newTestGroupName repetitionCount on="submit"}} class="analysis-group">
595                 <table>
596                     <caption>{{input name="name" value=newTestGroupName placeholder="Test group name" required=true type="text"}}</caption>
597                     <thead>
598                         <tr>
599                             <th>Root</th>
600                             {{#each testSets}}
601                                 <th>
602                                     {{name}}
603                                     {{view Ember.Select
604                                         content=options
605                                         optionValuePath="content.value"
606                                         optionLabelPath="content.label"
607                                         selection=selection}}
608                                 </th>
609                             {{/each}}
610                         </tr>
611                     </thead>
612                     <tbody>
613                         {{#each roots}}
614                             <tr>
615                                 <th>{{name}}</th>
616                                 {{#each sets}}
617                                     <td>{{view Ember.Select name=name content=revisions disabled=true
618                                         optionValuePath="content.value" optionLabelPath="content.label"
619                                         selection=selection}}</td>
620                                 {{/each}}
621                             </tr>
622                         {{/each}}
623                     </tbody>
624                     <tbody>
625                         <tr>
626                             <th>Number of runs</th>
627                             <td colspan=2>
628                                 {{view Ember.Select content=possibleRepetitionCounts value=repetitionCount}}
629                             </td>
630                         </tr>
631                     </tbody>
632                 </table>
633
634                 <button type="submit">Start A/B testing</button>
635             </form>
636             {{/if}}
637         {{/if}}
638     </script>
639
640 </head>
641 <body>
642 </body>
643 </html>