| 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 |