|
Lines 1-6
Websites/perf.webkit.org/public/v2/app.js_sec1
|
| 1 |
window.App = Ember.Application.create(); |
1 |
window.App = Ember.Application.create(); |
| 2 |
|
2 |
|
| 3 |
App.Router.map(function () { |
3 |
App.Router.map(function () { |
|
|
4 |
this.resource('customDashboard', {path: 'dashboard/custom'}); |
| 5 |
this.resource('dashboard', {path: 'dashboard/:name'}); |
| 4 |
this.resource('charts', {path: 'charts'}); |
6 |
this.resource('charts', {path: 'charts'}); |
| 5 |
this.resource('analysis', {path: 'analysis'}); |
7 |
this.resource('analysis', {path: 'analysis'}); |
| 6 |
this.resource('analysisTask', {path: 'analysis/task/:taskId'}); |
8 |
this.resource('analysisTask', {path: 'analysis/task/:taskId'}); |
|
Lines 54-81
App.DashboardPaneProxyForPicker = Ember.
Websites/perf.webkit.org/public/v2/app.js_sec2
|
| 54 |
}.property('platformId', 'metricId'), |
56 |
}.property('platformId', 'metricId'), |
| 55 |
}); |
57 |
}); |
| 56 |
|
58 |
|
| 57 |
App.IndexController = Ember.Controller.extend({ |
59 |
App.IndexRoute = Ember.Route.extend({ |
|
|
60 |
beforeModel: function () |
| 61 |
{ |
| 62 |
var self = this; |
| 63 |
App.Manifest.fetch(this.store).then(function () { |
| 64 |
self.transitionTo('dashboard', App.Manifest.defaultDashboardName()); |
| 65 |
}); |
| 66 |
}, |
| 67 |
}); |
| 68 |
|
| 69 |
App.DashboardRoute = Ember.Route.extend({ |
| 70 |
model: function (param) |
| 71 |
{ |
| 72 |
return App.Manifest.fetch(this.store).then(function () { |
| 73 |
return App.Manifest.dashboardByName(param.name); |
| 74 |
}); |
| 75 |
}, |
| 76 |
}); |
| 77 |
|
| 78 |
App.CustomDashboardRoute = Ember.Route.extend({ |
| 79 |
controllerName: 'dashboard', |
| 80 |
model: function (param) |
| 81 |
{ |
| 82 |
return this.store.createRecord('dashboard', {serialized: param.grid}); |
| 83 |
}, |
| 84 |
renderTemplate: function() |
| 85 |
{ |
| 86 |
this.render('dashboard'); |
| 87 |
} |
| 88 |
}); |
| 89 |
|
| 90 |
App.DashboardController = Ember.Controller.extend({ |
| 58 |
queryParams: ['grid', 'numberOfDays'], |
91 |
queryParams: ['grid', 'numberOfDays'], |
| 59 |
_previousGrid: {}, |
|
|
| 60 |
headerColumns: [], |
92 |
headerColumns: [], |
| 61 |
rows: [], |
93 |
rows: [], |
| 62 |
numberOfDays: 7, |
94 |
numberOfDays: 7, |
| 63 |
editMode: false, |
95 |
editMode: false, |
| 64 |
|
96 |
|
| 65 |
gridChanged: function () |
97 |
modelChanged: function () |
| 66 |
{ |
98 |
{ |
| 67 |
var grid = this.get('grid'); |
99 |
var dashboard = this.get('model'); |
| 68 |
if (grid === this._previousGrid) |
|
|
| 69 |
return; |
| 70 |
|
| 71 |
var dashboard = null; |
| 72 |
if (grid) { |
| 73 |
dashboard = this.store.createRecord('dashboard', {serialized: grid}); |
| 74 |
if (!dashboard.get('headerColumns').length) |
| 75 |
dashboard = null; |
| 76 |
} |
| 77 |
if (!dashboard) |
| 78 |
dashboard = App.Manifest.get('defaultDashboard'); |
| 79 |
if (!dashboard) |
100 |
if (!dashboard) |
| 80 |
return; |
101 |
return; |
| 81 |
|
102 |
|
|
Lines 95-103
App.IndexController = Ember.Controller.e
Websites/perf.webkit.org/public/v2/app.js_sec3
|
| 95 |
})); |
116 |
})); |
| 96 |
|
117 |
|
| 97 |
this.set('emptyRow', new Array(columnCount)); |
118 |
this.set('emptyRow', new Array(columnCount)); |
| 98 |
}.observes('grid', 'App.Manifest.defaultDashboard').on('init'), |
119 |
}.observes('model').on('init'), |
| 99 |
|
120 |
|
| 100 |
updateGrid: function() |
121 |
computeGrid: function() |
| 101 |
{ |
122 |
{ |
| 102 |
var headers = this.get('headerColumns').map(function (header) { return header.label; }); |
123 |
var headers = this.get('headerColumns').map(function (header) { return header.label; }); |
| 103 |
var table = [headers].concat(this.get('rows').map(function (row) { |
124 |
var table = [headers].concat(this.get('rows').map(function (row) { |
|
Lines 106-113
App.IndexController = Ember.Controller.e
Websites/perf.webkit.org/public/v2/app.js_sec4
|
| 106 |
return platformAndMetric[0] || platformAndMetric[1] ? platformAndMetric : []; |
127 |
return platformAndMetric[0] || platformAndMetric[1] ? platformAndMetric : []; |
| 107 |
})); |
128 |
})); |
| 108 |
})); |
129 |
})); |
| 109 |
this._previousGrid = JSON.stringify(table); |
130 |
return JSON.stringify(table); |
| 110 |
this.set('grid', this._previousGrid); |
|
|
| 111 |
}, |
131 |
}, |
| 112 |
|
132 |
|
| 113 |
_sharedDomainChanged: function () |
133 |
_sharedDomainChanged: function () |
|
Lines 173-180
App.IndexController = Ember.Controller.e
Websites/perf.webkit.org/public/v2/app.js_sec5
|
| 173 |
toggleEditMode: function () |
193 |
toggleEditMode: function () |
| 174 |
{ |
194 |
{ |
| 175 |
this.toggleProperty('editMode'); |
195 |
this.toggleProperty('editMode'); |
| 176 |
if (!this.get('editMode')) |
196 |
if (this.get('editMode')) |
| 177 |
this.updateGrid(); |
197 |
this.transitionToRoute('dashboard', 'custom', {name: null, queryParams: {grid: this.computeGrid()}}); |
|
|
198 |
else |
| 199 |
this.set('grid', this.computeGrid()); |
| 178 |
}, |
200 |
}, |
| 179 |
}, |
201 |
}, |
| 180 |
|
202 |
|
|
Lines 362-368
App.Pane = Ember.Object.extend({
Websites/perf.webkit.org/public/v2/app.js_sec6
|
| 362 |
if (typeof(id) == "string") |
384 |
if (typeof(id) == "string") |
| 363 |
return !!id.match(/^[A-Za-z0-9_]+$/); |
385 |
return !!id.match(/^[A-Za-z0-9_]+$/); |
| 364 |
return false; |
386 |
return false; |
| 365 |
} |
387 |
}, |
|
|
388 |
computeStatus: function (currentPoint, previousPoint) |
| 389 |
{ |
| 390 |
var chartData = this.get('chartData'); |
| 391 |
var diffFromBaseline = this._relativeDifferentToLaterPointInTimeSeries(currentPoint, chartData.baseline); |
| 392 |
var diffFromTarget = this._relativeDifferentToLaterPointInTimeSeries(currentPoint, chartData.target); |
| 393 |
|
| 394 |
var label = ''; |
| 395 |
var className = ''; |
| 396 |
var formatter = d3.format('.3p'); |
| 397 |
|
| 398 |
var smallerIsBetter = chartData.smallerIsBetter; |
| 399 |
if (diffFromBaseline !== undefined && diffFromBaseline > 0 == smallerIsBetter) { |
| 400 |
label = formatter(Math.abs(diffFromBaseline)) + ' ' + (smallerIsBetter ? 'above' : 'below') + ' baseline'; |
| 401 |
className = 'worse'; |
| 402 |
} else if (diffFromTarget !== undefined && diffFromTarget < 0 == smallerIsBetter) { |
| 403 |
label = formatter(Math.abs(diffFromTarget)) + ' ' + (smallerIsBetter ? 'below' : 'above') + ' target'; |
| 404 |
className = 'better'; |
| 405 |
} else if (diffFromTarget !== undefined) |
| 406 |
label = formatter(Math.abs(diffFromTarget)) + ' until target'; |
| 407 |
|
| 408 |
var valueDelta = previousPoint ? chartData.deltaFormatter(currentPoint.value - previousPoint.value) : null; |
| 409 |
if (valueDelta && valueDelta > 0) |
| 410 |
valueDelta = '+' + valueDelta; |
| 411 |
|
| 412 |
return {className: className, label: label, currentValue: chartData.formatter(currentPoint.value), valueDelta: valueDelta}; |
| 413 |
}, |
| 414 |
_relativeDifferentToLaterPointInTimeSeries: function (currentPoint, timeSeries) |
| 415 |
{ |
| 416 |
if (!currentPoint || !timeSeries) |
| 417 |
return undefined; |
| 418 |
|
| 419 |
var referencePoint = timeSeries.findPointAfterTime(currentPoint.time); |
| 420 |
if (!referencePoint) |
| 421 |
return undefined; |
| 422 |
|
| 423 |
return (currentPoint.value - referencePoint.value) / referencePoint.value; |
| 424 |
}, |
| 425 |
latestStatus: function () |
| 426 |
{ |
| 427 |
var chartData = this.get('chartData'); |
| 428 |
if (!chartData || !chartData.current) |
| 429 |
return null; |
| 430 |
|
| 431 |
var lastPoint = chartData.current.lastPoint(); |
| 432 |
if (!lastPoint) |
| 433 |
return null; |
| 434 |
|
| 435 |
return this.computeStatus(lastPoint, chartData.current.previousPoint(lastPoint)); |
| 436 |
}.property('chartData'), |
| 366 |
}); |
437 |
}); |
| 367 |
|
438 |
|
| 368 |
App.createChartData = function (data) |
439 |
App.createChartData = function (data) |
|
Lines 374-379
App.createChartData = function (data)
Websites/perf.webkit.org/public/v2/app.js_sec7
|
| 374 |
target: runs.target ? runs.target.timeSeriesByCommitTime() : null, |
445 |
target: runs.target ? runs.target.timeSeriesByCommitTime() : null, |
| 375 |
unit: data.unit, |
446 |
unit: data.unit, |
| 376 |
formatter: data.useSI ? d3.format('.4s') : d3.format('.4g'), |
447 |
formatter: data.useSI ? d3.format('.4s') : d3.format('.4g'), |
|
|
448 |
deltaFormatter: data.useSI ? d3.format('.2s') : d3.format('.2g'), |
| 377 |
smallerIsBetter: data.smallerIsBetter, |
449 |
smallerIsBetter: data.smallerIsBetter, |
| 378 |
}; |
450 |
}; |
| 379 |
} |
451 |
} |
|
Lines 730-744
App.PaneController = Ember.ObjectControl
Websites/perf.webkit.org/public/v2/app.js_sec8
|
| 730 |
} |
802 |
} |
| 731 |
|
803 |
|
| 732 |
var currentMeasurement; |
804 |
var currentMeasurement; |
| 733 |
var oldMeasurement; |
805 |
var previousPoint; |
| 734 |
if (currentPoint) { |
806 |
if (currentPoint) { |
| 735 |
currentMeasurement = currentPoint.measurement; |
807 |
currentMeasurement = currentPoint.measurement; |
| 736 |
var previousPoint = currentPoint.series.previousPoint(currentPoint); |
808 |
previousPoint = currentPoint.series.previousPoint(currentPoint); |
| 737 |
oldMeasurement = previousPoint ? previousPoint.measurement : null; |
|
|
| 738 |
} else { |
809 |
} else { |
| 739 |
currentMeasurement = selectedPoints[selectedPoints.length - 1].measurement; |
810 |
currentMeasurement = selectedPoints[selectedPoints.length - 1].measurement; |
| 740 |
oldMeasurement = selectedPoints[0].measurement; |
811 |
previousPoint = selectedPoints[0]; |
| 741 |
} |
812 |
} |
|
|
813 |
var oldMeasurement = previousPoint ? previousPoint.measurement : null; |
| 742 |
|
814 |
|
| 743 |
var formattedRevisions = currentMeasurement.formattedRevisions(oldMeasurement); |
815 |
var formattedRevisions = currentMeasurement.formattedRevisions(oldMeasurement); |
| 744 |
var revisions = App.Manifest.get('repositories') |
816 |
var revisions = App.Manifest.get('repositories') |
|
Lines 762-776
App.PaneController = Ember.ObjectControl
Websites/perf.webkit.org/public/v2/app.js_sec9
|
| 762 |
buildURL = builder.urlFromBuildNumber(buildNumber); |
834 |
buildURL = builder.urlFromBuildNumber(buildNumber); |
| 763 |
} |
835 |
} |
| 764 |
|
836 |
|
| 765 |
var chartData = this.get('chartData'); |
|
|
| 766 |
var valueDiff = oldMeasurement ? chartData.formatter(currentMeasurement.mean() - oldMeasurement.mean()) : null; |
| 767 |
if (valueDiff && valueDiff > 0) |
| 768 |
valueDiff = '+' + valueDiff; |
| 769 |
|
| 770 |
this.set('details', Ember.Object.create({ |
837 |
this.set('details', Ember.Object.create({ |
| 771 |
status: this._computeStatus(currentPoint), |
838 |
status: this.get('model').computeStatus(currentPoint, previousPoint), |
| 772 |
currentValue: chartData.formatter(currentMeasurement.mean()), |
|
|
| 773 |
valueDiff: valueDiff, |
| 774 |
buildNumber: buildNumber, |
839 |
buildNumber: buildNumber, |
| 775 |
buildURL: buildURL, |
840 |
buildURL: buildURL, |
| 776 |
buildTime: currentMeasurement.formattedBuildTime(), |
841 |
buildTime: currentMeasurement.formattedBuildTime(), |
|
Lines 783-822
App.PaneController = Ember.ObjectControl
Websites/perf.webkit.org/public/v2/app.js_sec10
|
| 783 |
var points = this.get('selectedPoints'); |
848 |
var points = this.get('selectedPoints'); |
| 784 |
this.set('cannotAnalyze', !this.get('newAnalysisTaskName') || !points || points.length < 2); |
849 |
this.set('cannotAnalyze', !this.get('newAnalysisTaskName') || !points || points.length < 2); |
| 785 |
}.observes('newAnalysisTaskName'), |
850 |
}.observes('newAnalysisTaskName'), |
| 786 |
_computeStatus: function (currentPoint) |
|
|
| 787 |
{ |
| 788 |
var chartData = this.get('chartData'); |
| 789 |
|
| 790 |
var diffFromBaseline = this._relativeDifferentToLaterPointInTimeSeries(currentPoint, chartData.baseline); |
| 791 |
var diffFromTarget = this._relativeDifferentToLaterPointInTimeSeries(currentPoint, chartData.target); |
| 792 |
|
| 793 |
var label = ''; |
| 794 |
var className = ''; |
| 795 |
var formatter = d3.format('.3p'); |
| 796 |
|
| 797 |
var smallerIsBetter = chartData.smallerIsBetter; |
| 798 |
if (diffFromBaseline !== undefined && diffFromBaseline > 0 == smallerIsBetter) { |
| 799 |
label = formatter(Math.abs(diffFromBaseline)) + ' ' + (smallerIsBetter ? 'above' : 'below') + ' baseline'; |
| 800 |
className = 'worse'; |
| 801 |
} else if (diffFromTarget !== undefined && diffFromTarget < 0 == smallerIsBetter) { |
| 802 |
label = formatter(Math.abs(diffFromTarget)) + ' ' + (smallerIsBetter ? 'below' : 'above') + ' target'; |
| 803 |
className = 'better'; |
| 804 |
} else if (diffFromTarget !== undefined) |
| 805 |
label = formatter(Math.abs(diffFromTarget)) + ' until target'; |
| 806 |
|
| 807 |
return {className: className, label: label}; |
| 808 |
}, |
| 809 |
_relativeDifferentToLaterPointInTimeSeries: function (currentPoint, timeSeries) |
| 810 |
{ |
| 811 |
if (!currentPoint || !timeSeries) |
| 812 |
return undefined; |
| 813 |
|
| 814 |
var referencePoint = timeSeries.findPointAfterTime(currentPoint.time); |
| 815 |
if (!referencePoint) |
| 816 |
return undefined; |
| 817 |
|
| 818 |
return (currentPoint.value - referencePoint.value) / referencePoint.value; |
| 819 |
} |
| 820 |
}); |
851 |
}); |
| 821 |
|
852 |
|
| 822 |
|
853 |
|