Removed the duplicated definition of ChartPaneBase.
[WebKit.git] / Websites / perf.webkit.org / public / v3 / components / chart-pane-base.js
1
2 class ChartPaneBase extends ComponentBase {
3
4     constructor(name)
5     {
6         super(name);
7
8         this._errorMessage = null;
9         this._platformId = null;
10         this._metricId = null;
11         this._platform = null;
12         this._metric = null;
13
14         this._overviewChart = null;
15         this._mainChart = null;
16         this._mainChartStatus = null;
17         this._commitLogViewer = null;
18     }
19
20     configure(platformId, metricId)
21     {
22         var result = ChartStyles.createChartSourceList(platformId, metricId);
23         this._errorMessage = result.error;
24         this._platformId = platformId;
25         this._metricId = metricId;
26         this._platform = result.platform;
27         this._metric = result.metric;
28
29         this._overviewChart = null;
30         this._mainChart = null;
31         this._mainChartStatus = null;
32
33         this._commitLogViewer = this.content().querySelector('commit-log-viewer').component();
34
35         if (result.error)
36             return;
37
38         var formatter = result.metric.makeFormatter(4);
39         var self = this;
40
41         var overviewOptions = ChartStyles.overviewChartOptions(formatter);
42         overviewOptions.selection.onchange = this._overviewSelectionDidChange.bind(this);
43
44         this._overviewChart = new InteractiveTimeSeriesChart(result.sourceList, overviewOptions);
45         this.renderReplace(this.content().querySelector('.chart-pane-overview'), this._overviewChart);
46
47         var mainOptions = ChartStyles.mainChartOptions(formatter);
48         mainOptions.indicator.onchange = this._indicatorDidChange.bind(this);
49         mainOptions.selection.onchange = this._mainSelectionDidChange.bind(this);
50         mainOptions.selection.onzoom = this._mainSelectionDidZoom.bind(this);
51         mainOptions.annotations.onclick = this._openAnalysisTask.bind(this);
52         mainOptions.ondata = this._didFetchData.bind(this);
53         this._mainChart = new InteractiveTimeSeriesChart(result.sourceList, mainOptions);
54         this.renderReplace(this.content().querySelector('.chart-pane-main'), this._mainChart);
55
56         this._mainChartStatus = new ChartPaneStatusView(result.metric, this._mainChart, this._openCommitViewer.bind(this));
57         this.renderReplace(this.content().querySelector('.chart-pane-details'), this._mainChartStatus);
58
59         this.content().querySelector('.chart-pane').addEventListener('keyup', this._keyup.bind(this));
60
61         this._fetchAnalysisTasks(platformId, metricId);
62     }
63
64     _fetchAnalysisTasks(platformId, metricId)
65     {
66         var self = this;
67         AnalysisTask.fetchByPlatformAndMetric(platformId, metricId).then(function (tasks) {
68             self._mainChart.setAnnotations(tasks.map(function (task) {
69                 var fillStyle = '#fc6';
70                 switch (task.changeType()) {
71                 case 'inconclusive':
72                     fillStyle = '#fcc';
73                 case 'progression':
74                     fillStyle = '#39f';
75                     break;
76                 case 'regression':
77                     fillStyle = '#c60';
78                     break;
79                 case 'unchanged':
80                     fillStyle = '#ccc';
81                     break;
82                 }
83
84                 return {
85                     task: task,
86                     startTime: task.startTime(),
87                     endTime: task.endTime(),
88                     label: task.label(),
89                     fillStyle: fillStyle,
90                 };
91             }));
92         });
93     }
94
95     platformId() { return this._platformId; }
96     metricId() { return this._metricId; }
97
98     setOverviewDomain(startTime, endTime)
99     {
100         if (this._overviewChart)
101             this._overviewChart.setDomain(startTime, endTime);
102     }
103
104     setMainDomain(startTime, endTime)
105     {
106         if (this._mainChart)
107             this._mainChart.setDomain(startTime, endTime);
108     }
109
110     _overviewSelectionDidChange(domain, didEndDrag) { }
111
112     _mainSelectionDidChange(selection, didEndDrag)
113     {
114         this.render();
115     }
116
117     _mainSelectionDidZoom(selection)
118     {
119         this._overviewChart.setSelection(selection, this);
120         this._mainChart.setSelection(null);
121         this.render();
122     }
123
124     _indicatorDidChange(indicatorID, isLocked)
125     {
126         this._mainChartStatus.updateRevisionListWithNotification();
127         this.render();
128     }
129
130     _didFetchData()
131     {
132         this._mainChartStatus.updateRevisionListWithNotification();
133         this.render();
134     }
135
136     _openAnalysisTask()
137     { }
138
139     _openCommitViewer(repository, from, to)
140     {
141         this._mainChartStatus.setCurrentRepository(repository);
142         this._commitLogViewer.view(repository, from, to).then(this.render.bind(this));
143         this.render();
144     }
145
146     _keyup(event)
147     {
148         switch (event.keyCode) {
149         case 37: // Left
150             if (!this._mainChart.moveLockedIndicatorWithNotification(false))
151                 return;
152             break;
153         case 39: // Right
154             if (!this._mainChart.moveLockedIndicatorWithNotification(true))
155                 return;
156             break;
157         case 38: // Up
158             if (!this._mainChartStatus.moveRepositoryWithNotification(false))
159                 return;
160         case 40: // Down
161             if (!this._mainChartStatus.moveRepositoryWithNotification(true))
162                 return;
163         default:
164             return;
165         }
166
167         this.render();
168
169         event.preventDefault();
170         event.stopPropagation();
171     }
172
173     render()
174     {
175         Instrumentation.startMeasuringTime('ChartPane', 'render');
176
177         super.render();
178
179         if (this._errorMessage) {
180             this.renderReplace(this.content().querySelector('.chart-pane-main'), this._errorMessage);
181             return;
182         }
183
184         if (this._mainChartStatus)
185             this._mainChartStatus.render();
186
187         var body = this.content().querySelector('.chart-pane-body');
188         if (this._commitLogViewer && this._commitLogViewer.currentRepository()) {
189             body.classList.add('has-second-sidebar');
190             this._commitLogViewer.render();
191         } else
192             body.classList.remove('has-second-sidebar');
193
194         Instrumentation.endMeasuringTime('ChartPane', 'render');
195     }
196
197     static htmlTemplate()
198     {
199         return `
200             <section class="chart-pane" tabindex="0">
201                 ${this.paneHeaderTemplate()}
202                 <div class="chart-pane-body">
203                     <div class="chart-pane-main"></div>
204                     <div class="chart-pane-sidebar">
205                         <div class="chart-pane-overview"></div>
206                         <div class="chart-pane-details"></div>
207                     </div>
208                     <div class="chart-pane-second-sidebar">
209                         <commit-log-viewer></commit-log-viewer>
210                     </div>
211                 </div>
212             </section>
213         `;
214     }
215
216     static paneHeaderTemplate() { return ''; }
217
218     static cssTemplate()
219     {
220         return Toolbar.cssTemplate() + `
221             .chart-pane {
222                 margin: 1rem;
223                 margin-bottom: 2rem;
224                 padding: 0rem;
225                 height: 18rem;
226                 outline: none;
227             }
228
229             .chart-pane:focus .chart-pane-header {
230                 background: rgba(204, 153, 51, 0.1);
231             }
232
233             .chart-pane-body {
234                 position: relative;
235                 width: 100%;
236                 height: 100%;
237             }
238
239             .chart-pane-main {
240                 padding-right: 20rem;
241                 height: 100%;
242                 margin: 0;
243                 vertical-align: middle;
244                 text-align: center;
245             }
246
247             .has-second-sidebar .chart-pane-main {
248                 padding-right: 40rem;
249             }
250
251             .chart-pane-main > * {
252                 width: 100%;
253                 height: 100%;
254             }
255
256             .chart-pane-sidebar,
257             .chart-pane-second-sidebar {
258                 position: absolute;
259                 right: 0;
260                 top: 0;
261                 width: 0;
262                 border-left: solid 1px #ccc;
263                 height: 100%;
264             }
265
266             :not(.has-second-sidebar) > .chart-pane-second-sidebar {
267                 border-left: 0;
268             }
269
270             .chart-pane-sidebar {
271                 width: 20rem;
272             }
273
274             .has-second-sidebar .chart-pane-sidebar {
275                 right: 20rem;
276             }
277
278             .has-second-sidebar .chart-pane-second-sidebar {
279                 width: 20rem;
280             }
281
282             .chart-pane-overview {
283                 width: 100%;
284                 height: 5rem;
285                 border-bottom: solid 1px #ccc;
286             }
287
288             .chart-pane-overview > * {
289                 display: block;
290                 width: 100%;
291                 height: 100%;
292             }
293
294             .chart-pane-details {
295                 position: relative;
296                 display: block;
297                 height: calc(100% - 5.5rem - 2px);
298                 overflow-y: scroll;
299                 padding-top: 0.5rem;
300             }
301         `;
302     }
303
304 }