Index: runtime/bin/vmservice/client/lib/src/elements/isolate_view.dart |
diff --git a/runtime/bin/vmservice/client/lib/src/elements/isolate_view.dart b/runtime/bin/vmservice/client/lib/src/elements/isolate_view.dart |
index da6779f3251e3575ceb3c7f35c8310350e9953e9..5f88a5e48ba61af427a1ba5591fdae1cadc72859 100644 |
--- a/runtime/bin/vmservice/client/lib/src/elements/isolate_view.dart |
+++ b/runtime/bin/vmservice/client/lib/src/elements/isolate_view.dart |
@@ -6,12 +6,81 @@ library isolate_view_element; |
import 'dart:async'; |
import 'observatory_element.dart'; |
+import 'package:observatory/app.dart'; |
import 'package:observatory/service.dart'; |
import 'package:polymer/polymer.dart'; |
+class TagProfileChart { |
+ var _table = new DataTable(); |
+ var _chart; |
+ |
+ void update(TagProfile tagProfile) { |
+ if (_table.columns == 0) { |
+ // Initialize. |
+ _table.addColumn('string', 'Time'); |
+ for (var tagName in tagProfile.names) { |
+ if (tagName == 'Idle') { |
+ // Skip Idle tag. |
+ continue; |
+ } |
+ _table.addColumn('number', tagName); |
+ } |
+ } |
+ _table.clearRows(); |
+ var idleIndex = tagProfile.names.indexOf('Idle'); |
+ assert(idleIndex != -1); |
+ var t = tagProfile.updatedAtSeconds; |
+ for (var i = 0; i < tagProfile.snapshots.length; i++) { |
+ var snapshotTime = tagProfile.snapshots[i].seconds; |
+ var row = []; |
+ if (snapshotTime > 0.0) { |
+ row.add('t ${(snapshotTime - t).toStringAsFixed(2)}'); |
+ } else { |
+ row.add(''); |
+ } |
+ var sum = tagProfile.snapshots[i].sum; |
+ if (sum == 0) { |
+ for (var j = 0; j < tagProfile.snapshots[i].counters.length; j++) { |
+ if (j == idleIndex) { |
+ // Skip idle. |
+ continue; |
+ } |
+ row.add(0); |
+ } |
+ } else { |
+ for (var j = 0; j < tagProfile.snapshots[i].counters.length; j++) { |
+ if (j == idleIndex) { |
+ // Skip idle. |
+ continue; |
+ } |
+ var percentage = tagProfile.snapshots[i].counters[j] / sum * 100.0; |
+ row.add(percentage.toInt()); |
+ } |
+ } |
+ _table.addRow(row); |
+ } |
+ } |
+ |
+ void draw(var element) { |
+ if (_chart == null) { |
+ assert(element != null); |
+ _chart = new Chart('SteppedAreaChart', element); |
+ _chart.options['isStacked'] = true; |
+ _chart.options['connectSteps'] = false; |
+ _chart.options['vAxis'] = { |
+ 'minValue': 0.0, |
+ 'maxValue': 100.0, |
+ }; |
+ } |
+ _chart.draw(_table); |
+ } |
+} |
+ |
@CustomTag('isolate-view') |
class IsolateViewElement extends ObservatoryElement { |
@published Isolate isolate; |
+ Timer _updateTimer; |
+ TagProfileChart tagProfileChart = new TagProfileChart(); |
IsolateViewElement.created() : super.created(); |
Future<ServiceObject> eval(String text) { |
@@ -19,16 +88,39 @@ class IsolateViewElement extends ObservatoryElement { |
isolate.rootLib.id + "/eval?expr=${Uri.encodeComponent(text)}"); |
} |
+ void enteredView() { |
+ super.enteredView(); |
+ // Start a periodic timer to update the isolate summary once a second. |
+ _updateTimer = new Timer.periodic(new Duration(seconds: 1), (_) { |
+ isolate.updateTagProfile().then((tagProfile) { |
+ tagProfileChart.update(tagProfile); |
+ _drawTagProfileChart(); |
+ }); |
+ }); |
+ } |
+ |
+ void leftView() { |
+ super.leftView(); |
+ _updateTimer.cancel(); |
+ } |
+ |
+ void _drawTagProfileChart() { |
+ var element = shadowRoot.querySelector('#tagProfileChart'); |
+ if (element != null) { |
+ tagProfileChart.draw(element); |
+ } |
+ } |
+ |
void refresh(var done) { |
isolate.reload().whenComplete(done); |
} |
void resume(var a, var b, var c) { |
isolate.get("resume").then((result) { |
- // TODO(turnidge): Instead of asserting here, handling errors |
- // properly. |
- assert(result.serviceType == 'Success'); |
- isolate.reload(); |
- }); |
+ // TODO(turnidge): Instead of asserting here, handling errors |
+ // properly. |
+ assert(result.serviceType == 'Success'); |
+ isolate.reload(); |
+ }); |
} |
} |