OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:html'; | 5 import 'dart:html'; |
6 import 'dart:async'; | 6 import 'dart:async'; |
7 import 'package:observatory/models.dart' as M; | 7 import 'package:observatory/models.dart' as M; |
8 import 'package:charted/charted.dart'; | 8 import 'package:charted/charted.dart'; |
9 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | 9 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
10 import 'package:observatory/src/elements/helpers/tag.dart'; | 10 import 'package:observatory/src/elements/helpers/tag.dart'; |
11 | 11 |
12 class MetricGraphElement extends HtmlElement implements Renderable { | 12 class MetricGraphElement extends HtmlElement implements Renderable { |
13 static const tag = const Tag<MetricGraphElement>('metric-graph'); | 13 static const tag = const Tag<MetricGraphElement>('metric-graph'); |
14 | 14 |
15 RenderingScheduler<MetricGraphElement> _r; | 15 RenderingScheduler<MetricGraphElement> _r; |
16 | 16 |
17 Stream<RenderedEvent<MetricGraphElement>> get onRendered => _r.onRendered; | 17 Stream<RenderedEvent<MetricGraphElement>> get onRendered => _r.onRendered; |
18 | 18 |
19 M.IsolateRef _isolate; | 19 M.IsolateRef _isolate; |
20 M.Metric _metric; | 20 M.Metric _metric; |
21 M.MetricRepository _metrics; | 21 M.MetricRepository _metrics; |
22 Timer _timer; | 22 Timer _timer; |
23 | 23 |
24 M.IsolateRef get isolate => _isolate; | 24 M.IsolateRef get isolate => _isolate; |
25 M.Metric get metric => _metric; | 25 M.Metric get metric => _metric; |
26 | 26 |
27 factory MetricGraphElement(M.IsolateRef isolate, M.Metric metric, | 27 factory MetricGraphElement( |
28 M.MetricRepository metrics, | 28 M.IsolateRef isolate, M.Metric metric, M.MetricRepository metrics, |
29 {RenderingQueue queue}) { | 29 {RenderingQueue queue}) { |
30 assert(isolate != null); | 30 assert(isolate != null); |
31 assert(metric != null); | 31 assert(metric != null); |
32 assert(metrics != null); | 32 assert(metrics != null); |
33 MetricGraphElement e = document.createElement(tag.name); | 33 MetricGraphElement e = document.createElement(tag.name); |
34 e._r = new RenderingScheduler(e, queue: queue); | 34 e._r = new RenderingScheduler(e, queue: queue); |
35 e._isolate = isolate; | 35 e._isolate = isolate; |
36 e._metric = metric; | 36 e._metric = metric; |
37 e._metrics = metrics; | 37 e._metrics = metrics; |
38 return e; | 38 return e; |
39 } | 39 } |
40 | 40 |
41 MetricGraphElement.created() : super.created(); | 41 MetricGraphElement.created() : super.created(); |
42 | 42 |
43 @override | 43 @override |
44 void attached() { | 44 void attached() { |
45 super.attached(); | 45 super.attached(); |
46 _r.enable(); | 46 _r.enable(); |
47 _timer = new Timer.periodic(const Duration(seconds: 1), (_) => _r.dirty()); | 47 _timer = new Timer.periodic(const Duration(seconds: 1), (_) => _r.dirty()); |
48 } | 48 } |
49 | 49 |
50 @override | 50 @override |
51 void detached() { | 51 void detached() { |
52 super.detached(); | 52 super.detached(); |
53 _r.disable(notify: true); | 53 _r.disable(notify: true); |
54 children = []; | 54 children = []; |
55 _timer.cancel(); | 55 _timer.cancel(); |
56 } | 56 } |
57 | 57 |
58 final _columns = [ | 58 final _columns = [ |
59 new ChartColumnSpec(label: 'Time', type: ChartColumnSpec.TYPE_TIMESTAMP), | 59 new ChartColumnSpec(label: 'Time', type: ChartColumnSpec.TYPE_TIMESTAMP), |
60 new ChartColumnSpec(label: 'Value', formatter: (v) => v.toString()) | 60 new ChartColumnSpec(label: 'Value', formatter: (v) => v.toString()) |
61 ]; | 61 ]; |
62 | 62 |
63 void render() { | 63 void render() { |
64 final min = _metrics.getMinValue(_isolate, _metric); | 64 final min = _metrics.getMinValue(_isolate, _metric); |
65 final max = _metrics.getMaxValue(_isolate, _metric); | 65 final max = _metrics.getMaxValue(_isolate, _metric); |
66 final rows = _metrics.getSamples(_isolate, _metric).map((s) => | 66 final rows = _metrics |
67 [s.time.millisecondsSinceEpoch, s.value]).toList(); | 67 .getSamples(_isolate, _metric) |
| 68 .map((s) => [s.time.millisecondsSinceEpoch, s.value]) |
| 69 .toList(); |
68 final current = rows.last.last; | 70 final current = rows.last.last; |
69 | 71 |
70 var message = 'current: $current'; | 72 var message = 'current: $current'; |
71 if (min != null) { | 73 if (min != null) { |
72 message = 'min: $min, ' + message; | 74 message = 'min: $min, ' + message; |
73 } | 75 } |
74 if (max != null) { | 76 if (max != null) { |
75 message = message + ', max: $max'; | 77 message = message + ', max: $max'; |
76 } | 78 } |
77 | 79 |
78 final host = new DivElement(); | 80 final host = new DivElement(); |
79 children = [ | 81 children = [ |
80 new DivElement()..classes = ['memberList'] | 82 new DivElement() |
| 83 ..classes = ['memberList'] |
81 ..children = [ | 84 ..children = [ |
82 new DivElement()..classes = ['memberItem'] | 85 new DivElement() |
83 ..children = min == null ? const [] : [ | 86 ..classes = ['memberItem'] |
84 new DivElement()..classes = ['memberName'] | 87 ..children = min == null |
85 ..text = 'min', | 88 ? const [] |
86 new DivElement()..classes = ['memberValue'] | 89 : [ |
87 ..text = '$min' | 90 new DivElement() |
88 ], | 91 ..classes = ['memberName'] |
89 new DivElement()..classes = ['memberItem'] | 92 ..text = 'min', |
| 93 new DivElement() |
| 94 ..classes = ['memberValue'] |
| 95 ..text = '$min' |
| 96 ], |
| 97 new DivElement() |
| 98 ..classes = ['memberItem'] |
90 ..children = [ | 99 ..children = [ |
91 new DivElement()..classes = ['memberName'] | 100 new DivElement() |
| 101 ..classes = ['memberName'] |
92 ..text = 'current', | 102 ..text = 'current', |
93 new DivElement()..classes = ['memberValue'] | 103 new DivElement() |
| 104 ..classes = ['memberValue'] |
94 ..text = '$current' | 105 ..text = '$current' |
95 ], | 106 ], |
96 new DivElement()..classes = ['memberItem'] | 107 new DivElement() |
97 ..children = max == null ? const [] : [ | 108 ..classes = ['memberItem'] |
98 new DivElement()..classes = ['memberName'] | 109 ..children = max == null |
99 ..text = 'max', | 110 ? const [] |
100 new DivElement()..classes = ['memberValue'] | 111 : [ |
101 ..text = '$max' | 112 new DivElement() |
102 ] | 113 ..classes = ['memberName'] |
| 114 ..text = 'max', |
| 115 new DivElement() |
| 116 ..classes = ['memberValue'] |
| 117 ..text = '$max' |
| 118 ] |
103 ], | 119 ], |
104 new DivElement()..classes = ['graph'] | 120 new DivElement() |
105 ..children = [ | 121 ..classes = ['graph'] |
106 host | 122 ..children = [host] |
107 ] | |
108 ]; | 123 ]; |
109 if (rows.length <= 1) { | 124 if (rows.length <= 1) { |
110 return; | 125 return; |
111 } | 126 } |
112 final rect = host.getBoundingClientRect(); | 127 final rect = host.getBoundingClientRect(); |
113 var series = new ChartSeries("one", [1], new LineChartRenderer()); | 128 var series = new ChartSeries("one", [1], new LineChartRenderer()); |
114 var config = new ChartConfig([series], [0]); | 129 var config = new ChartConfig([series], [0]); |
115 config.minimumSize = new Rect(rect.width, rect.height); | 130 config.minimumSize = new Rect(rect.width, rect.height); |
116 final data = new ChartData(_columns, rows); | 131 final data = new ChartData(_columns, rows); |
117 new CartesianArea(host, data, config, state: new ChartState()).draw(); | 132 new CartesianArea(host, data, config, state: new ChartState()).draw(); |
118 } | 133 } |
119 } | 134 } |
OLD | NEW |