Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: runtime/observatory/lib/src/elements/metrics.dart

Issue 2303173002: Converted Observatory metrics-page element (Closed)
Patch Set: Added sampling buffer size select Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library metrics; 5 library metrics;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:html'; 8 import 'dart:html';
9 import 'observatory_element.dart'; 9 import 'package:observatory/models.dart' as M;
10 import 'package:charted/charted.dart'; 10 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
11 import 'package:observatory/app.dart'; 11 import 'package:observatory/src/elements/helpers/tag.dart';
12 import 'package:observatory/service.dart'; 12 import 'package:observatory/src/elements/metric/details.dart';
13 import 'package:polymer/polymer.dart'; 13 import 'package:observatory/src/elements/metric/graph.dart';
14 import 'package:observatory/src/elements/nav/bar.dart';
15 import 'package:observatory/src/elements/nav/isolate_menu.dart';
16 import 'package:observatory/src/elements/nav/menu.dart';
17 import 'package:observatory/src/elements/nav/notify.dart';
18 import 'package:observatory/src/elements/nav/refresh.dart';
19 import 'package:observatory/src/elements/nav/top_menu.dart';
20 import 'package:observatory/src/elements/nav/vm_menu.dart';
14 21
15 @CustomTag('metrics-page') 22 class MetricsPageElement extends HtmlElement implements Renderable {
16 class MetricsPageElement extends ObservatoryElement { 23 static const tag = const Tag<MetricsPageElement>('metrics-page',
24 dependencies: const [
25 MetricDetailsElement.tag,
26 MetricGraphElement.tag,
27 NavBarElement.tag,
28 NavTopMenuElement.tag,
29 NavVMMenuElement.tag,
30 NavIsolateMenuElement.tag,
31 NavMenuElement.tag,
32 NavRefreshElement.tag,
33 NavNotifyElement.tag,
34 ]);
35
36 RenderingScheduler<MetricsPageElement> _r;
37
38 Stream<RenderedEvent<MetricsPageElement>> get onRendered => _r.onRendered;
39
40 M.VM _vm;
41 M.IsolateRef _isolate;
42 M.EventRepository _events;
43 M.NotificationRepository _notifications;
44 M.MetricRepository _metrics;
45 List<M.Metric> _available;
46 M.Metric _selected;
47
48
49 M.VMRef get vm => _vm;
50 M.IsolateRef get isolate => _isolate;
51 M.NotificationRepository get notifications => _notifications;
52
53 factory MetricsPageElement(M.VM vm, M.IsolateRef isolate,
54 M.EventRepository events,
55 M.NotificationRepository notifications,
56 M.MetricRepository metrics,
57 {RenderingQueue queue}) {
58 assert(vm != null);
59 assert(isolate != null);
60 assert(events != null);
61 assert(notifications != null);
62 MetricsPageElement e = document.createElement(tag.name);
63 e._r = new RenderingScheduler(e, queue: queue);
64 e._vm = vm;
65 e._isolate = isolate;
66 e._events = events;
67 e._notifications = notifications;
68 e._metrics = metrics;
69 return e;
70 }
71
17 MetricsPageElement.created() : super.created(); 72 MetricsPageElement.created() : super.created();
18 73
19 @observable MetricsPage page; 74 @override
20 @observable Isolate isolate; 75 attached() {
21 @observable ServiceMetric selectedMetric; 76 super.attached();
22 77 _r.enable();
23 void _autoPickSelectedMetric() { 78 _refresh();
24 if (selectedMetric != null) {
25 return;
26 }
27 // Attempt to pick the last selected metric.
28 if ((isolate != null) && (page != null) &&
29 (page.selectedMetricId != null)) {
30 selectedMetric = isolate.dartMetrics[page.selectedMetricId];
31 if (selectedMetric != null) {
32 return;
33 }
34 selectedMetric = isolate.nativeMetrics[page.selectedMetricId];
35 }
36 if ((selectedMetric == null) && (isolate != null)) {
37 var values = isolate.dartMetrics.values.toList();
38 if ((values != null) && (values.length > 0)) {
39 // Fall back and pick the first isolate metric.
40 selectedMetric = values.first;
41 }
42 if (selectedMetric != null) {
43 return;
44 }
45 values = isolate.nativeMetrics.values.toList();
46 if ((values != null) && (values.length > 0)) {
47 // Fall back and pick the first isolate metric.
48 selectedMetric = values.first;
49 }
50 }
51 } 79 }
52 80
53 void attached() { 81 @override
54 _autoPickSelectedMetric(); 82 detached() {
83 super.detached();
84 _r.disable(notify: true);
85 children = [];
55 } 86 }
56 87
57 void isolateChanged(oldValue) { 88 void render() {
58 if (isolate != null) { 89 children = [
59 isolate.refreshMetrics().then((_) { 90 new NavBarElement(queue: _r.queue)
60 _autoPickSelectedMetric(); 91 ..children = [
61 }); 92 new NavTopMenuElement(queue: _r.queue),
62 } 93 new NavVMMenuElement(_vm, _events, queue: _r.queue),
94 new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
95 new NavMenuElement('metrics', last: true, queue: _r.queue),
96 new NavRefreshElement(queue: _r.queue)
97 ..onRefresh.listen((e) {
98 e.element.disabled = true;
99 _refresh();
100 }),
101 new NavNotifyElement(_notifications, queue: _r.queue)
102 ],
103 new DivElement()..classes = ['content-centered-big']
104 ..children = [
105 new HeadingElement.h2()..text = 'Metrics',
106 new HRElement(),
107 new DivElement()..classes = ['memberList']
108 ..children = [
109 new DivElement()..classes = ['memberItem']
110 ..children = [
111 new DivElement()..classes = ['memberName']
112 ..text = 'Metric',
113 new DivElement()..classes = ['memberValue']
114 ..children = _available == null
115 ? [new SpanElement()..text = 'Loading..']
116 : _createMetricSelect()
117 ]
118 ],
119 new HRElement(),
120 new DivElement()
121 ..children = _selected == null ? const []
122 : [
123 new MetricDetailsElement(_isolate, _selected, _metrics,
124 queue: _r.queue)
125 ],
126 new HRElement(),
127 new DivElement()..classes = ['graph']
128 ..children = _selected == null ? const []
129 : [
130 new MetricGraphElement(_isolate, _selected, _metrics,
131 queue: _r.queue)
132 ]
133 ],
134 ];
63 } 135 }
64 136
65 Future refresh() { 137 Future _refresh() async {
66 return isolate.refreshMetrics(); 138 _available = (await _metrics.list(_isolate)).toList();
139 if (!_available.contains(_selected)) {
140 _selected = _available.first;
141 }
142 _r.dirty();
67 } 143 }
68 144
69 void selectMetric(Event e, var detail, Element target) { 145 List<Element> _createMetricSelect() {
70 String id = target.attributes['data-id']; 146 var s;
71 selectedMetric = isolate.dartMetrics[id]; 147 return [
72 if (selectedMetric == null) { 148 s = new SelectElement()
73 // Check VM metrics. 149 ..value = _selected.name
74 selectedMetric = isolate.nativeMetrics[id]; 150 ..children = _available.map((metric) {
75 } 151 return new OptionElement(value: metric.name,
76 if (selectedMetric != null) { 152 selected: _selected == metric)
77 page.selectedMetricId = id; 153 ..text = metric.name;
78 } else { 154 }).toList(growable: false)
79 page.selectedMetricId = null; 155 ..onChange.listen((_) {
80 } 156 _selected = _available[s.selectedIndex];
157 _r.dirty();
158 })
159 ];
81 } 160 }
82 } 161 }
83
84 @CustomTag('metric-details')
85 class MetricDetailsElement extends ObservatoryElement {
86 MetricDetailsElement.created() : super.created();
87 @published MetricsPage page;
88 @published ServiceMetric metric;
89
90 int _findIndex(SelectElement element, int value) {
91 if (element == null) {
92 return null;
93 }
94 for (var i = 0; i < element.options.length; i++) {
95 var optionElement = element.options[i];
96 int optionValue = int.parse(optionElement.value);
97 if (optionValue == value) {
98 return i;
99 }
100 }
101 return null;
102 }
103
104 void attached() {
105 super.attached();
106 _updateSelectedIndexes();
107 }
108
109 void _updateSelectedIndexes() {
110 if (metric == null) {
111 return;
112 }
113 SelectElement refreshRateElement = shadowRoot.querySelector('#refreshrate');
114 if (refreshRateElement == null) {
115 // Race between shadowRoot setup and events.
116 return;
117 }
118 int period = 0;
119 if (metric.poller != null) {
120 period = metric.poller.pollPeriod.inMilliseconds;
121 }
122 var index = _findIndex(refreshRateElement, period);
123 assert(index != null);
124 refreshRateElement.selectedIndex = index;
125 SelectElement bufferSizeElement = shadowRoot.querySelector('#buffersize');
126 index = _findIndex(bufferSizeElement, metric.sampleBufferSize);
127 assert(index != null);
128 bufferSizeElement.selectedIndex = index;
129 }
130
131 metricChanged(oldValue) {
132 _updateSelectedIndexes();
133 }
134
135 void refreshRateChange(Event e, var detail, Element target) {
136 var value = int.parse((target as SelectElement).value);
137 if (metric == null) {
138 return;
139 }
140 page.setRefreshPeriod(value, metric);
141 }
142
143 void sampleBufferSizeChange(Event e, var detail, Element target) {
144 var value = int.parse((target as SelectElement).value);
145 if (metric == null) {
146 return;
147 }
148 metric.sampleBufferSize = value;
149 }
150 }
151
152 @CustomTag('metrics-graph')
153 class MetricsGraphElement extends ObservatoryElement {
154 MetricsGraphElement.created() : super.created();
155
156 HtmlElement _wrapper;
157 HtmlElement _areaHost;
158 CartesianArea _area;
159 ChartData _data;
160 final _columns = [
161 new ChartColumnSpec(label: 'Time', type: ChartColumnSpec.TYPE_TIMESTAMP),
162 new ChartColumnSpec(label: 'Value', formatter: (v) => v.toString())
163 ];
164 final _rows = [[0, 1000000.0]];
165
166 @published ServiceMetric metric;
167 @observable Isolate isolate;
168
169 void attached() {
170 super.attached();
171 // Redraw once a second.
172 pollPeriod = new Duration(seconds: 1);
173 _reset();
174 }
175
176 void onPoll() {
177 if (metric == null) {
178 return;
179 }
180 _update();
181 _draw();
182 }
183
184 void _reset() {
185 _rows.clear();
186 _wrapper = shadowRoot.querySelector('#metric-chart');
187 assert(_wrapper != null);
188 _areaHost = _wrapper.querySelector('.chart-host');
189 assert(_areaHost != null);
190 _areaHost.children.clear();
191 var series = new ChartSeries("one", [1], new LineChartRenderer());
192 var config = new ChartConfig([series], [0]);
193 config.minimumSize = new Rect(800, 600);
194 _data = new ChartData(_columns, _rows);
195 _area = new CartesianArea(_areaHost,
196 _data,
197 config,
198 state: new ChartState());
199 }
200
201 void _update() {
202 _rows.clear();
203 for (var i = 0; i < metric.samples.length; i++) {
204 var sample = metric.samples[i];
205 _rows.add([sample.time.millisecondsSinceEpoch, sample.value]);
206 }
207 }
208
209 void _draw() {
210 if (_rows.length < 2) {
211 return;
212 }
213 _area.data = new ChartData(_columns, _rows);
214 _area.draw();
215 }
216
217 metricChanged(oldValue) {
218 if (oldValue != metric) {
219 _reset();
220 }
221 }
222 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698