diff --git a/packages/devtools_app/lib/src/charts/treemap.dart b/packages/devtools_app/lib/src/charts/treemap.dart
new file mode 100644
index 0000000..a093093
--- /dev/null
+++ b/packages/devtools_app/lib/src/charts/treemap.dart
@@ -0,0 +1,546 @@
+import 'package:flutter/material.dart';
+
+import '../common_widgets.dart';
+import '../trees.dart';
+import '../ui/colors.dart';
+import '../utils.dart';
+
+enum PivotType { pivotByMiddle, pivotBySize }
+
+class Treemap extends StatelessWidget {
+  const Treemap.fromRoot({
+    @required this.rootNode,
+    this.nodes,
+    @required this.levelsVisible,
+    @required this.isOutermostLevel,
+    @required this.height,
+    @required this.onRootChangedCallback,
+  });
+
+  const Treemap.fromNodes({
+    this.rootNode,
+    @required this.nodes,
+    @required this.levelsVisible,
+    @required this.isOutermostLevel,
+    @required this.height,
+    @required this.onRootChangedCallback,
+  });
+
+  final TreemapNode rootNode;
+
+  final List<TreemapNode> nodes;
+
+  /// The depth of children visible from this Treemap widget.
+  ///
+  /// A decremented level should be passed in when constructing [Treemap.fromRoot],
+  /// but not when constructing [Treemap.fromNodes]. This is because
+  /// when constructing from a root, [Treemap] either builds a nested [Treemap] to
+  /// show its node's children, or it shows its node. When constructing from a list
+  /// of nodes, however, [Treemap] is built to become part of a bigger treemap,
+  /// which means the level should not change.
+  ///
+  /// For example, levelsVisible = 2:
+  /// ```
+  /// _______________
+  /// |     Root    |
+  /// ---------------
+  /// |      1      |
+  /// |  ---------  |
+  /// |  |   2   |  |
+  /// |  |       |  |
+  /// |  |       |  |
+  /// |  ---------  |
+  /// ---------------
+  /// ```
+  final int levelsVisible;
+
+  /// Whether current levelsVisible matches the outermost level.
+  final bool isOutermostLevel;
+
+  final double height;
+
+  final void Function(TreemapNode node) onRootChangedCallback;
+
+  static const PivotType pivotType = PivotType.pivotBySize;
+
+  static const treeMapHeaderHeight = 20.0;
+
+  static const minHeightToDisplayTitleText = 20.0;
+
+  static const minHeightToDisplayCellText = 40.0;
+
+  /// Computes the total size of a given list of treemap nodes.
+  /// [endIndex] defaults to nodes.length - 1.
+  int computeByteSizeForNodes({
+    @required List<TreemapNode> nodes,
+    int startIndex = 0,
+    int endIndex,
+  }) {
+    endIndex ??= nodes.length - 1;
+    int sum = 0;
+    for (int i = startIndex; i <= endIndex; i++) {
+      sum += nodes[i].byteSize;
+    }
+    return sum;
+  }
+
+  int computePivot(List<TreemapNode> children) {
+    switch (pivotType) {
+      case PivotType.pivotByMiddle:
+        return (children.length / 2).floor();
+      case PivotType.pivotBySize:
+        int pivotIndex = -1;
+        double maxSize = double.negativeInfinity;
+        for (int i = 0; i < children.length; i++) {
+          if (children[i].byteSize > maxSize) {
+            maxSize = children[i].byteSize.toDouble();
+            pivotIndex = i;
+          }
+        }
+        return pivotIndex;
+      default:
+        return -1;
+    }
+  }
+
+  /// Implements the ordered treemap algorithm studied in [this research paper](https://www.cs.umd.edu/~ben/papers/Shneiderman2001Ordered.pdf).
+  ///
+  /// **Algorithm**
+  ///
+  /// Divides a given list of treemap nodes into four parts:
+  /// L1, P, L2, L3.
+  ///
+  /// P (pivot) is the treemap node chosen to be the pivot based on the pivot type.
+  /// L1 includes all treemap nodes before the pivot treemap node.
+  /// L2 and L3 combined include all treemap nodes after the pivot treemap node.
+  /// A combination of elements are put into L2 and L3 so that
+  /// the aspect ratio of the pivot cell (P) is as close to 1 as it can be.
+  ///
+  /// **Layout**
+  /// ```
+  /// ----------------------
+  /// |      |  P   |      |
+  /// |      |      |      |
+  /// |  L1  |------|  L3  |
+  /// |      |  L2  |      |
+  /// |      |      |      |
+  /// ----------------------
+  /// ```
+  List<Positioned> buildTreemaps({
+    @required List<TreemapNode> children,
+    @required double width,
+    @required double height,
+  }) {
+    final isHorizontalRectangle = width > height;
+
+    final totalByteSize = computeByteSizeForNodes(nodes: children);
+    if (children.isEmpty) {
+      return [];
+    }
+
+    // Sort the list of treemap nodes, descending in size.
+    children.sort((a, b) => b.byteSize.compareTo(a.byteSize));
+    if (children.length <= 2) {
+      final positionedChildren = <Positioned>[];
+      double offset = 0;
+
+      for (final child in children) {
+        final ratio = child.byteSize / totalByteSize;
+
+        positionedChildren.add(
+          Positioned(
+            left: isHorizontalRectangle ? offset : 0.0,
+            top: isHorizontalRectangle ? 0.0 : offset,
+            width: isHorizontalRectangle ? ratio * width : width,
+            height: isHorizontalRectangle ? height : ratio * height,
+            child: Treemap.fromRoot(
+              rootNode: child,
+              levelsVisible: levelsVisible - 1,
+              isOutermostLevel: false,
+              onRootChangedCallback: onRootChangedCallback,
+              height: height,
+            ),
+          ),
+        );
+        offset += isHorizontalRectangle ? ratio * width : ratio * height;
+      }
+
+      return positionedChildren;
+    }
+
+    final pivotIndex = computePivot(children);
+
+    final pivotNode = children[pivotIndex];
+    final pivotByteSize = pivotNode.byteSize;
+
+    final list1 = children.sublist(0, pivotIndex);
+    final list1ByteSize = computeByteSizeForNodes(nodes: list1);
+
+    var list2 = <TreemapNode>[];
+    int list2ByteSize = 0;
+    var list3 = <TreemapNode>[];
+    int list3ByteSize = 0;
+
+    // The maximum amount of data we can put in [list3].
+    final l3MaxLength = children.length - pivotIndex - 1;
+    int bestIndex = 0;
+    double pivotBestWidth = 0;
+    double pivotBestHeight = 0;
+
+    // We need to be able to put at least 3 elements in [list3] for this algorithm.
+    if (l3MaxLength >= 3) {
+      double pivotBestAspectRatio = double.infinity;
+      // Iterate through different combinations of [list2] and [list3] to find
+      // the combination where the aspect ratio of pivot is the lowest.
+      for (int i = pivotIndex + 1; i < children.length; i++) {
+        final list2Size = computeByteSizeForNodes(
+          nodes: children,
+          startIndex: pivotIndex + 1,
+          endIndex: i,
+        );
+
+        // Calculate the aspect ratio for the pivot treemap node.
+        final pivotAndList2Ratio = (pivotByteSize + list2Size) / totalByteSize;
+        final pivotRatio = pivotByteSize / (pivotByteSize + list2Size);
+
+        final pivotWidth = isHorizontalRectangle
+            ? pivotAndList2Ratio * width
+            : pivotRatio * width;
+
+        final pivotHeight = isHorizontalRectangle
+            ? pivotRatio * height
+            : pivotAndList2Ratio * height;
+
+        final pivotAspectRatio = pivotWidth / pivotHeight;
+
+        // Best aspect ratio that is the closest to 1.
+        if ((1 - pivotAspectRatio).abs() < (1 - pivotBestAspectRatio).abs()) {
+          pivotBestAspectRatio = pivotAspectRatio;
+          bestIndex = i;
+          // Kept track of width and height to construct the pivot cell.
+          pivotBestWidth = pivotWidth;
+          pivotBestHeight = pivotHeight;
+        }
+      }
+      // Split the rest of the data into [list2] and [list3].
+      list2 = children.sublist(pivotIndex + 1, bestIndex + 1);
+      list2ByteSize = computeByteSizeForNodes(nodes: list2);
+
+      list3 = children.sublist(bestIndex + 1);
+      list3ByteSize = computeByteSizeForNodes(nodes: list3);
+    } else {
+      // Put all data in [list2] and none in [list3].
+      list2 = children.sublist(pivotIndex + 1);
+      list2ByteSize = computeByteSizeForNodes(nodes: list2);
+
+      final pivotAndList2Ratio =
+          (pivotByteSize + list2ByteSize) / totalByteSize;
+      final pivotRatio = pivotByteSize / (pivotByteSize + list2ByteSize);
+      pivotBestWidth = isHorizontalRectangle
+          ? pivotAndList2Ratio * width
+          : pivotRatio * width;
+      pivotBestHeight = isHorizontalRectangle
+          ? pivotRatio * height
+          : pivotAndList2Ratio * height;
+    }
+
+    final positionedTreemaps = <Positioned>[];
+
+    // Contruct list 1 sub-treemap.
+    final list1SizeRatio = list1ByteSize / totalByteSize;
+    final list1Width = isHorizontalRectangle ? width * list1SizeRatio : width;
+    final list1Height =
+        isHorizontalRectangle ? height : height * list1SizeRatio;
+    if (list1.isNotEmpty) {
+      positionedTreemaps.add(
+        Positioned(
+          left: 0.0,
+          right: 0.0,
+          width: list1Width,
+          height: list1Height,
+          child: Treemap.fromNodes(
+            nodes: list1,
+            levelsVisible: levelsVisible,
+            isOutermostLevel: isOutermostLevel,
+            onRootChangedCallback: onRootChangedCallback,
+            height: height,
+          ),
+        ),
+      );
+    }
+
+    // Construct list 2 sub-treemap.
+    final list2Width =
+        isHorizontalRectangle ? pivotBestWidth : width - pivotBestWidth;
+    final list2Height =
+        isHorizontalRectangle ? height - pivotBestHeight : pivotBestHeight;
+    final list2XCoord = isHorizontalRectangle ? list1Width : 0.0;
+    final list2YCoord = isHorizontalRectangle ? pivotBestHeight : list1Height;
+    if (list2.isNotEmpty) {
+      positionedTreemaps.add(
+        Positioned(
+          left: list2XCoord,
+          top: list2YCoord,
+          width: list2Width,
+          height: list2Height,
+          child: Treemap.fromNodes(
+            nodes: list2,
+            levelsVisible: levelsVisible,
+            isOutermostLevel: isOutermostLevel,
+            onRootChangedCallback: onRootChangedCallback,
+            height: height,
+          ),
+        ),
+      );
+    }
+
+    // Construct pivot cell.
+    final pivotXCoord = isHorizontalRectangle ? list1Width : list2Width;
+    final pivotYCoord = isHorizontalRectangle ? 0.0 : list1Height;
+
+    positionedTreemaps.add(
+      Positioned(
+        left: pivotXCoord,
+        top: pivotYCoord,
+        width: pivotBestWidth,
+        height: pivotBestHeight,
+        child: Treemap.fromRoot(
+          rootNode: pivotNode,
+          levelsVisible: levelsVisible - 1,
+          isOutermostLevel: false,
+          onRootChangedCallback: onRootChangedCallback,
+          height: height,
+        ),
+      ),
+    );
+
+    // Construct list 3 sub-treemap.
+    final list3Ratio = list3ByteSize / totalByteSize;
+    final list3Width = isHorizontalRectangle ? list3Ratio * width : width;
+    final list3Height = isHorizontalRectangle ? height : list3Ratio * height;
+    final list3XCoord =
+        isHorizontalRectangle ? list1Width + pivotBestWidth : 0.0;
+    final list3YCoord =
+        isHorizontalRectangle ? 0.0 : list1Height + pivotBestHeight;
+
+    if (list3.isNotEmpty) {
+      positionedTreemaps.add(
+        Positioned(
+          left: list3XCoord,
+          top: list3YCoord,
+          width: list3Width,
+          height: list3Height,
+          child: Treemap.fromNodes(
+            nodes: list3,
+            levelsVisible: levelsVisible,
+            isOutermostLevel: isOutermostLevel,
+            onRootChangedCallback: onRootChangedCallback,
+            height: height,
+          ),
+        ),
+      );
+    }
+
+    return positionedTreemaps;
+  }
+
+  Text buildNameAndSizeText({
+    @required Color fontColor,
+    @required bool oneLine,
+  }) {
+    return Text(
+      rootNode.displayText(oneLine: oneLine),
+      style: TextStyle(color: fontColor),
+      textAlign: TextAlign.center,
+      overflow: TextOverflow.ellipsis,
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    if (rootNode == null && nodes.isNotEmpty) {
+      return buildSubTreemaps();
+    } else {
+      return buildTreemap(context);
+    }
+  }
+
+  /// **Treemap widget layout**
+  /// ```
+  /// ----------------------------
+  /// |        Title Text        |
+  /// |--------------------------|
+  /// |                          |
+  /// |           Cell           |
+  /// |                          |
+  /// |                          |
+  /// ----------------------------
+  /// ```
+  Widget buildTreemap(BuildContext context) {
+    if (levelsVisible > 0 && rootNode.children.isNotEmpty) {
+      return Padding(
+        padding: const EdgeInsets.all(1.0),
+        child: Column(
+          children: [
+            if (height > minHeightToDisplayTitleText) buildTitleText(context),
+            Expanded(
+              child: Treemap.fromNodes(
+                nodes: rootNode.children,
+                levelsVisible: levelsVisible,
+                isOutermostLevel: isOutermostLevel,
+                onRootChangedCallback: onRootChangedCallback,
+                height: height,
+              ),
+            ),
+          ],
+        ),
+      );
+    } else {
+      return Column(
+        children: [
+          Expanded(
+            child: buildSelectable(
+              child: Container(
+                decoration: BoxDecoration(
+                  color: mainUiColor,
+                  border: Border.all(color: Colors.black87),
+                ),
+                child: Center(
+                  child: height > minHeightToDisplayCellText
+                      ? buildNameAndSizeText(
+                          fontColor: Colors.black,
+                          oneLine: false,
+                        )
+                      : const SizedBox(),
+                ),
+              ),
+            ),
+          ),
+        ],
+      );
+    }
+  }
+
+  Widget buildTitleText(BuildContext context) {
+    if (isOutermostLevel) {
+      final pathFromRoot = rootNode.pathFromRoot();
+      // Build breadcrumbs navigator.
+      return Container(
+        height: treeMapHeaderHeight,
+        child: ListView.separated(
+          shrinkWrap: true,
+          scrollDirection: Axis.horizontal,
+          separatorBuilder: (context, index) {
+            return const Text(' > ');
+          },
+          itemCount: pathFromRoot.length,
+          itemBuilder: (BuildContext context, int index) {
+            return buildSelectable(
+              child: Text(
+                index < pathFromRoot.length - 1
+                    ? pathFromRoot[index].name
+                    : pathFromRoot[index].displayText(),
+              ),
+              newRoot: pathFromRoot[index],
+            );
+          },
+        ),
+      );
+    } else {
+      return buildSelectable(
+        child: Container(
+          height: treeMapHeaderHeight,
+          width: double.infinity,
+          decoration: BoxDecoration(
+            border: Border.all(color: Colors.black87),
+          ),
+          child: buildNameAndSizeText(
+            fontColor: Theme.of(context).textTheme.bodyText2.color,
+            oneLine: true,
+          ),
+        ),
+      );
+    }
+  }
+
+  /// Builds a selectable container with [child] as its child.
+  ///
+  /// Selecting this widget will trigger a re-root of the tree
+  /// to the associated [TreemapNode].
+  ///
+  /// The default value for newRoot is [rootNode].
+  Tooltip buildSelectable({@required Widget child, TreemapNode newRoot}) {
+    newRoot ??= rootNode;
+    return Tooltip(
+      message: rootNode.displayText(),
+      waitDuration: tooltipWait,
+      preferBelow: false,
+      child: InkWell(
+        onTap: () {
+          if (rootNode.children.isNotEmpty) onRootChangedCallback(newRoot);
+        },
+        child: child,
+      ),
+    );
+  }
+
+  Widget buildSubTreemaps() {
+    return LayoutBuilder(
+      builder: (context, constraints) {
+        return Stack(
+          children: buildTreemaps(
+            children: nodes,
+            width: constraints.maxWidth,
+            height: constraints.maxHeight,
+          ),
+        );
+      },
+    );
+  }
+}
+
+class TreemapNode extends TreeNode<TreemapNode> {
+  TreemapNode({
+    @required this.name,
+    this.byteSize = 0,
+    this.childrenMap = const <String, TreemapNode>{},
+  })  : assert(name != null),
+        assert(byteSize != null),
+        assert(childrenMap != null);
+
+  final String name;
+  final Map<String, TreemapNode> childrenMap;
+  int byteSize;
+
+  String displayText({bool oneLine = true}) {
+    final separator = oneLine ? ' ' : '\n';
+    return '$name$separator[${prettyPrintBytes(byteSize, includeUnit: true)}]';
+  }
+
+  /// Returns a list of [TreemapNode] in the path from root node to [this].
+  List<TreemapNode> pathFromRoot() {
+    TreemapNode node = this;
+    final path = <TreemapNode>[];
+    while (node != null) {
+      path.add(node);
+      node = node.parent;
+    }
+    return path.reversed.toList();
+  }
+
+  void printTree() {
+    printTreeHelper(this, '');
+  }
+
+  void printTreeHelper(TreemapNode root, String tabs) {
+    print(tabs + '$root');
+    for (final child in root.children) {
+      printTreeHelper(child, tabs + '\t');
+    }
+  }
+
+  @override
+  String toString() {
+    return '{name: $name, size: $byteSize}';
+  }
+}
diff --git a/packages/devtools_app/lib/src/logging/logging_controller.dart b/packages/devtools_app/lib/src/logging/logging_controller.dart
index 8960c04..eb01c98 100644
--- a/packages/devtools_app/lib/src/logging/logging_controller.dart
+++ b/packages/devtools_app/lib/src/logging/logging_controller.dart
@@ -386,7 +386,7 @@
 
     final String summary = '${isolateRef['name']} • '
         '${e.json['reason']} collection in $time ms • '
-        '${printMb(usedBytes)} MB used of ${printMb(capacityBytes)} MB';
+        '${printMB(usedBytes, includeUnit: true)} used of ${printMB(capacityBytes, includeUnit: true)}';
 
     final Map<String, dynamic> event = <String, dynamic>{
       'reason': e.json['reason'],
diff --git a/packages/devtools_app/lib/src/memory/memory_controller.dart b/packages/devtools_app/lib/src/memory/memory_controller.dart
index 5687d7f..77081ff 100644
--- a/packages/devtools_app/lib/src/memory/memory_controller.dart
+++ b/packages/devtools_app/lib/src/memory/memory_controller.dart
@@ -52,12 +52,12 @@
 
   static const logFilenamePrefix = 'memory_log_';
 
-  final _showHeatMap = ValueNotifier<bool>(false);
+  final _showTreemap = ValueNotifier<bool>(false);
 
-  ValueListenable<bool> get showHeatMap => _showHeatMap;
+  ValueListenable<bool> get showTreemap => _showTreemap;
 
-  void toggleShowHeatMap(bool value) {
-    _showHeatMap.value = value;
+  void toggleShowTreeMap(bool value) {
+    _showTreemap.value = value;
   }
 
   final snapshots = <Snapshot>[];
diff --git a/packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart b/packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart
index 70cf4f7..28f40a3 100644
--- a/packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart
+++ b/packages/devtools_app/lib/src/memory/memory_heap_tree_view.dart
@@ -23,8 +23,8 @@
 import 'memory_controller.dart';
 import 'memory_filter.dart';
 import 'memory_graph_model.dart';
-import 'memory_heatmap.dart';
 import 'memory_snapshot_models.dart';
+import 'memory_treemap.dart';
 import 'memory_utils.dart';
 
 class HeapTree extends StatefulWidget {
@@ -227,12 +227,8 @@
                     : _isSnapshotComplete ? 'Done' : '...'),
       ]);
     } else if (controller.snapshotByLibraryData != null) {
-      if (controller.showHeatMap.value) {
-        snapshotDisplay = HeatMapSizeAnalyzer(
-          child: SizedBox.expand(
-            child: FlameChart(controller),
-          ),
-        );
+      if (controller.showTreemap.value) {
+        snapshotDisplay = MemoryTreemap(controller);
       } else {
         snapshotDisplay = MemorySnapshotTable();
       }
@@ -268,7 +264,7 @@
       mainAxisAlignment: MainAxisAlignment.end,
       children: [
         Expanded(child: snapshotDisplay),
-        if (hasDetails) const SizedBox(width: defaultSpacing),
+        hasDetails ? const SizedBox(width: defaultSpacing) : const SizedBox(),
         // TODO(terry): Need better focus handling between 2 tables & up/down
         //              arrows in the right-side field instance view table.
         controller.isLeafSelected
@@ -343,13 +339,13 @@
         const SizedBox(width: defaultSpacing),
         Row(
           children: [
-            const Text('Heat Map'),
+            const Text('Treemap'),
             Switch(
-              value: controller.showHeatMap.value,
+              value: controller.showTreemap.value,
               onChanged: (value) {
                 setState(() {
                   closeAutoCompleteOverlay();
-                  controller.toggleShowHeatMap(value);
+                  controller.toggleShowTreeMap(value);
                   controller.search = '';
                   controller.selectedLeaf = null;
                 });
@@ -358,13 +354,13 @@
           ],
         ),
         const SizedBox(width: defaultSpacing),
-        controller.showHeatMap.value
+        controller.showTreemap.value
             ? const SizedBox()
             : _groupByDropdown(textTheme),
         const SizedBox(width: defaultSpacing),
         // TODO(terry): Mechanism to handle expand/collapse on both
         // tables objects/fields. Maybe notion in table?
-        controller.showHeatMap.value
+        controller.showTreemap.value
             ? const SizedBox()
             : OutlineButton(
                 key: collapseAllButtonKey,
@@ -386,7 +382,7 @@
                     : null,
                 child: const Text('Collapse All'),
               ),
-        controller.showHeatMap.value
+        controller.showTreemap.value
             ? const SizedBox()
             : OutlineButton(
                 key: expandAllButtonKey,
@@ -463,7 +459,7 @@
       ),
     );
 
-    if (controller.showHeatMap.value && controller.snapshots.isNotEmpty) {
+    if (controller.showTreemap.value && controller.snapshots.isNotEmpty) {
       searchFieldFocusNode.requestFocus();
     }
 
diff --git a/packages/devtools_app/lib/src/memory/memory_heatmap.dart b/packages/devtools_app/lib/src/memory/memory_heatmap.dart
deleted file mode 100644
index 5d18241..0000000
--- a/packages/devtools_app/lib/src/memory/memory_heatmap.dart
+++ /dev/null
@@ -1,684 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'dart:math' as math;
-import 'dart:math';
-import 'dart:ui';
-
-import 'package:flutter/gestures.dart';
-import 'package:flutter/material.dart' hide TextStyle;
-import 'package:flutter/rendering.dart' hide TextStyle;
-import 'package:flutter/widgets.dart' hide TextStyle;
-import 'package:intl/intl.dart';
-import 'package:provider/provider.dart';
-
-import '../auto_dispose_mixin.dart';
-import '../ui/colors.dart';
-
-import 'memory_controller.dart';
-import 'memory_graph_model.dart';
-import 'memory_utils.dart';
-
-/// UX navigation in a heat map e.g.,
-///     ------------------------------------------------------------
-///     | ||| || |||| |       | new String | | || Foundation (38M) |
-///     ------------------------------------------------------------
-///     || |  |     | |  List | String | |  ||      src (42M)      |
-///     ------------------------------------------------------------
-///     | src (36.4M) |    dart:core (58M)   |package:flutter (42M)|
-///     ------------------------------------------------------------
-///     |                       Root (136M)                        |
-///     ------------------------------------------------------------
-/// Mouse action (click or mouse scroll wheel) over a rectangle for example
-/// package:flutter will to expand its contained children to more rectangles
-/// upwards. The sizes of the contained children (if an aggregated parent).
-/// Mouse action over, upward, children will further expand its children in
-/// a upward fashion too. To collapse a rectangle move the mouse below a child
-/// rectangle (its parent) and click or mouse scroll.
-
-class HeatMapSizeAnalyzer extends SingleChildRenderObjectWidget {
-  const HeatMapSizeAnalyzer({
-    Key key,
-    Widget child,
-  }) : super(key: key, child: child);
-
-  @override
-  RenderFlameChart createRenderObject(BuildContext context) {
-    return RenderFlameChart();
-  }
-}
-
-class RenderFlameChart extends RenderProxyBox {
-  @override
-  void paint(PaintingContext context, Offset offset) {
-    if (child != null) {
-      context.paintChild(child, offset);
-    }
-  }
-}
-
-class FlameChart extends StatefulWidget {
-  const FlameChart(
-    this.controller,
-  );
-
-  final MemoryController controller;
-
-  @override
-  FlameChartState createState() => FlameChartState(controller);
-}
-
-class FlameChartState extends State<FlameChart> with AutoDisposeMixin {
-  FlameChartState(this.controller);
-
-  InstructionsSize sizes;
-
-  Map<String, Function> callbacks = {};
-
-  MemoryController controller;
-
-  Widget snapshotDisplay;
-
-  _FlameChart _flameChart;
-
-  @override
-  void initState() {
-    super.initState();
-  }
-
-  @override
-  void didChangeDependencies() {
-    super.didChangeDependencies();
-
-    // TODO(terry): Unable to short-circuit need to investigate why?
-    controller = Provider.of<MemoryController>(context);
-
-    cancel();
-
-    addAutoDisposeListener(controller.selectedSnapshotNotifier, () {
-      setState(() {
-        controller.computeAllLibraries(true, true);
-
-        sizes = InstructionsSize.fromSnapshop(controller);
-      });
-    });
-
-    addAutoDisposeListener(controller.filterNotifier, () {
-      setState(() {
-        controller.computeAllLibraries(true, true);
-      });
-    });
-
-    addAutoDisposeListener(controller.selectTheSearchNotifier, () {
-      setState(() {
-        if (_trySelectItem()) {
-          closeAutoCompleteOverlay();
-        }
-      });
-    });
-
-    addAutoDisposeListener(controller.searchNotifier, () {
-      setState(() {
-        if (_trySelectItem()) {
-          closeAutoCompleteOverlay();
-        }
-      });
-    });
-
-    addAutoDisposeListener(controller.searchAutoCompleteNotifier, () {
-      setState(autoCompleteOverlaySetState(controller, context));
-    });
-  }
-
-  /// Returns true if node found and node selected.
-  bool _trySelectItem() {
-    if (controller.search.isNotEmpty) {
-      if (controller.selectTheSearch) {
-        // Select the node.
-        final node = findNode(controller.search);
-        selectNode(node);
-
-        closeAutoCompleteOverlay();
-
-        controller.selectTheSearch = false;
-        controller.search = '';
-        return true;
-      } else {
-        var matches = matchNames(controller.search)..sort();
-        // No exact match, return top matches.
-        matches = matches.sublist(0, min(topMatchesLimit, matches.length));
-        controller.searchAutoComplete.value = matches;
-      }
-    } else if (controller.selectTheSearch) {
-      // Escape hit, on empty search.
-      selectNode(null);
-      controller.selectTheSearch = false;
-    }
-
-    return false;
-  }
-
-  @override
-  void dispose() {
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    sizes = InstructionsSize.fromSnapshop(controller);
-
-    if (sizes != null) {
-      _flameChart = _FlameChart(
-        sizes,
-        // TODO(terry): Can the color range match flame chart? Review with UX.
-        memoryHeatMapLightColor,
-        memoryHeatMapDarkColor,
-        callbacks,
-      );
-      return _flameChart;
-    } else {
-      return const SizedBox();
-    }
-  }
-
-  List<String> matchNames(String searchValue) {
-    final MatchNamesFunction callback = _flameChart.callbacks[matchNamesKey];
-    return callback(searchValue);
-  }
-
-  Node findNode(String searchValue) {
-    final FindNodeFunction callback = _flameChart.callbacks[findNodeKey];
-    return callback(searchValue);
-  }
-
-  void selectNode(Node nodeValue) {
-    final SelectNodeFunction callback = _flameChart.callbacks[selectNodeKey];
-    callback(nodeValue);
-  }
-}
-
-/// Definitions of exposed callback methods stored in callback Map the key
-/// is the function name (String) and the value a callback function signature.
-
-/// matchNames callback name.
-const matchNamesKey = 'matchNames';
-
-/// matchNames callback signature.
-typedef MatchNamesFunction = List<String> Function(String);
-
-/// findNode callback name.
-const findNodeKey = 'findNode';
-
-/// findNode callback signature.
-typedef FindNodeFunction = Node Function(String);
-
-/// selectNode callback name.
-const selectNodeKey = 'selectNode';
-
-/// selectNode callback signature.
-typedef SelectNodeFunction = void Function(Node);
-
-class _FlameChart extends LeafRenderObjectWidget {
-  const _FlameChart(
-      this.sizes, this.lightColor, this.darkColor, this.callbacks);
-
-  final InstructionsSize sizes;
-
-  final Color lightColor;
-
-  final Color darkColor;
-
-  final Map<String, Function> callbacks;
-
-  @override
-  FlameChartRenderObject createRenderObject(BuildContext context) {
-    return FlameChartRenderObject()
-      // callbacks must be before sizes as hookup is done in sizes setter.
-      ..callbacks = callbacks
-      ..sizes = sizes
-      ..lightColor = lightColor
-      ..darkColor = darkColor;
-  }
-
-  @override
-  void updateRenderObject(
-    BuildContext context,
-    FlameChartRenderObject renderObject,
-  ) {
-    renderObject
-      ..sizes = sizes
-      ..lightColor = lightColor
-      ..darkColor = darkColor;
-  }
-}
-
-class FlameChartRenderObject extends RenderBox {
-  FlameChartRenderObject();
-
-  InstructionsSize _sizes;
-
-  Offset paintOffset;
-
-  Map<String, Function> callbacks;
-
-  set sizes(InstructionsSize value) {
-    callbacks[matchNamesKey] = _exposeMatchNames;
-    callbacks[findNodeKey] = _exposeFindNode;
-    callbacks[selectNodeKey] = _exposeSelectNode;
-
-    if (value == _sizes) {
-      return;
-    }
-    _sizes = value;
-    _selectedNode ??= value.root;
-    markNeedsPaint();
-  }
-
-  Color _lightColor;
-
-  set lightColor(Color value) {
-    if (value == _lightColor) {
-      return;
-    }
-    _lightColor = value;
-    markNeedsPaint();
-  }
-
-  Color _darkColor;
-
-  set darkColor(Color value) {
-    if (value == _lightColor) {
-      return;
-    }
-    _darkColor = value;
-    markNeedsPaint();
-  }
-
-  List<String> _exposeMatchNames(String searchName) {
-    return matchNodeNames(_sizes.root.children, searchName);
-  }
-
-  /// Look for the node with a particular name (depth first traversal).
-  List<String> matchNodeNames(Map<String, Node> children, String searchName) {
-    final matches = <String>[];
-    final matchName = searchName.toLowerCase();
-    for (var child in children.entries) {
-      final node = child.value;
-
-      final lcNodeName = node.name.toLowerCase();
-      if (!lcNodeName.endsWith('.dart') && lcNodeName.startsWith(matchName)) {
-        matches.add(node.name);
-      }
-      if (node.children.isNotEmpty) {
-        final childMatches = matchNodeNames(node.children, searchName);
-        if (childMatches.isNotEmpty) {
-          matches.addAll(childMatches);
-        }
-      }
-    }
-
-    return matches;
-  }
-
-  Node _exposeFindNode(String searchName) {
-    return findNode(_sizes.root.children, searchName);
-  }
-
-  /// Look for the node with a particular name (depth first traversal).
-  Node findNode(Map<String, Node> children, String searchName) {
-    final matchName = searchName.toLowerCase();
-    for (var child in children.entries) {
-      final node = child.value;
-      if (node.children.isEmpty) {
-        return node.name.toLowerCase() == matchName ? node : null;
-      } else {
-        if (node.name.toLowerCase() == matchName) return node;
-        final foundNode = findNode(node.children, matchName);
-        if (foundNode != null) return foundNode;
-      }
-    }
-
-    return null;
-  }
-
-  void _exposeSelectNode(Node value) {
-    selectedNode = value;
-  }
-
-  Node _selectedNode;
-
-  set selectedNode(Node value) {
-    value ??= _sizes.root;
-    if (value == _selectedNode) {
-      return;
-    }
-    _selectedNode = value;
-
-    markNeedsPaint();
-  }
-
-  @override
-  bool get sizedByParent => true;
-
-  @override
-  bool hitTest(BoxHitTestResult result, {Offset position}) {
-    final computedPosition =
-        Offset(position.dx + paintOffset.dx, position.dy + paintOffset.dy);
-
-    final node = _selectedNode.findRect(computedPosition);
-    if (node != null) {
-      selectedNode = node;
-    }
-
-    return super.hitTest(result, position: position);
-  }
-
-  @override
-  void paint(PaintingContext context, Offset offset) {
-    paintOffset = offset;
-
-    final rootWidth = size.width;
-    final top = _paintAncestors(context, _selectedNode.ancestors);
-
-    _paintNode(
-        context, _selectedNode, 0 + paintOffset.dx, rootWidth, top - offset.dy);
-
-    _paintChildren(
-      context: context,
-      currentLeft: 1 + offset.dx,
-      parentSize: _selectedNode.byteSize,
-      children: _selectedNode.children.values,
-      topFactor: top + Node.nodeHeight + 1 - offset.dy,
-      maxWidth: rootWidth - 1,
-    );
-  }
-
-  final _logs = <int, double>{};
-  final _inverseColors = <Color, Color>{};
-
-  void _paintNode(
-    PaintingContext context,
-    Node node,
-    double left,
-    double width,
-    double top,
-  ) {
-    node.rect = Rect.fromLTWH(left, size.height - top, width, Node.nodeHeight);
-    final double t =
-        _logs.putIfAbsent(node.byteSize, () => math.log(node.byteSize)) /
-            _logs.putIfAbsent(
-                _sizes.root.byteSize, () => math.log(_sizes.root.byteSize));
-    final Color backgroundColor = Color.lerp(
-      _lightColor,
-      _darkColor,
-      t,
-    );
-
-    context.canvas.drawRRect(
-      RRect.fromRectAndRadius(node.rect, const Radius.circular(2.0)),
-      Paint()..color = backgroundColor,
-    );
-    // Don't bother figuring out the text length if the box is too small.
-    if (width < 100) {
-      return;
-    }
-
-    final formattedByteSize = NumberFormat.compact().format(node.byteSize);
-
-    final builder = ParagraphBuilder(
-      ParagraphStyle(
-        textAlign: TextAlign.center,
-        maxLines: 2,
-        ellipsis: '...',
-      ),
-    )
-      ..pushStyle(
-        TextStyle(
-          color: _inverseColors.putIfAbsent(backgroundColor, () {
-            return HSLColor.fromColor(backgroundColor).lightness > .7
-                ? const Color(0xFF000000)
-                : const Color(0xFFFFFFFF);
-          }),
-          fontFamily: 'Courier New',
-        ),
-      )
-      ..addText('${node.name}\n($formattedByteSize)');
-    final Paragraph paragraph = builder.build()
-      ..layout(ParagraphConstraints(width: width - 5));
-    context.canvas.drawParagraph(
-      paragraph,
-      Offset(10 + left, size.height - top + 10),
-    );
-  }
-
-  double _paintAncestors(PaintingContext context, List<Node> nodes) {
-    double top = Node.nodeHeight;
-    for (var node in nodes.reversed) {
-      _paintNode(
-          context, node, 0 + paintOffset.dx, size.width, top - paintOffset.dy);
-      top += Node.nodeHeight;
-    }
-    return top;
-  }
-
-  void _paintChildren({
-    PaintingContext context,
-    double currentLeft,
-    int parentSize,
-    Iterable<Node> children,
-    double topFactor,
-    double maxWidth,
-  }) {
-    double left = currentLeft;
-
-    for (var child in children) {
-      final double width = child.byteSize / parentSize * maxWidth;
-      _paintNode(context, child, left, width, topFactor);
-
-      if (!child.isLeaf) {
-        final double factor = math.max(
-          0.0001,
-          math.min(
-            math.log(maxWidth * .01),
-            math.log(width * .1),
-          ),
-        );
-        // Very minor chunk of memory, just skip display for now.  Smaller than 1 pixel in width.
-        if (factor < width) {
-          _paintChildren(
-            context: context,
-            currentLeft: left + factor,
-            parentSize: child.byteSize,
-            children: child.children.values,
-            topFactor: topFactor + Node.nodeHeight + 1,
-            maxWidth: width - (2 * factor),
-          );
-        }
-      }
-      left += width;
-    }
-  }
-}
-
-class InstructionsSize {
-  const InstructionsSize(this.root);
-
-  factory InstructionsSize.fromSnapshop(MemoryController controller) {
-    final Map<String, Node> rootChildren = <String, Node>{};
-    final Node root = Node(
-      'root',
-      children: rootChildren,
-    );
-    Node currentParent = root;
-
-    // TODO(terry): Should heat map be all memory or just the filtered group?
-    //              Using rawGroup not graph.groupByLibrary.
-    controller.heapGraph.rawGroupByLibrary.forEach(
-      (libraryGroup, value) {
-        final classes = value;
-        for (final theClass in classes) {
-          final shallowSize = theClass.instancesTotalShallowSizes;
-          var className = theClass.name;
-          if (shallowSize == 0 ||
-              libraryGroup == null ||
-              className == null ||
-              className == '::') {
-            continue;
-          }
-
-          // Ensure the empty library name is our group name e.g., '' -> 'src'.
-          String libraryName = theClass.libraryUri.toString();
-          if (libraryName.isEmpty) {
-            libraryName = libraryGroup;
-          }
-
-          // Map class names to familar user names.
-          final predefined =
-              predefinedClasses[LibraryClass(libraryName, className)];
-          if (predefined != null) {
-            className = predefined.prettyName;
-          }
-
-          final symbol = Symbol(
-            name: 'new $className',
-            size: shallowSize,
-            libraryUri: libraryName,
-            className: className,
-          );
-
-          Map<String, Node> currentChildren = rootChildren;
-          final Node parentReset = currentParent;
-          for (String pathPart in symbol.parts) {
-            currentChildren.putIfAbsent(
-              pathPart,
-              () => Node(pathPart,
-                  parent: currentParent, children: <String, Node>{}),
-            );
-            currentChildren[pathPart].byteSize += symbol.size;
-            currentParent = currentChildren[pathPart];
-            currentChildren = currentChildren[pathPart].children;
-          }
-          currentParent = parentReset;
-        }
-      },
-    );
-
-    root.byteSize = root.children.values
-        .fold(0, (int current, Node node) => current + node.byteSize);
-
-    final snapshotGraph = controller.snapshots.last.snapshotGraph;
-
-    // Add the external heap to the heat map.
-    root.children.putIfAbsent('External Heap', () {
-      final node = Node(
-        'External Heap',
-        parent: root,
-        children: <String, Node>{},
-      );
-      node.byteSize = snapshotGraph.externalSize;
-      return node;
-    });
-
-    // Add the filtered libraries/classes to the heat map.
-    root.children.putIfAbsent('All Filtered Libraries', () {
-      final node = Node(
-        'All Filtered Libraries',
-        parent: root,
-        children: <String, Node>{},
-      );
-      node.byteSize = snapshotGraph.shallowSize - root.byteSize;
-      return node;
-    });
-
-    root.byteSize = snapshotGraph.shallowSize + snapshotGraph.externalSize;
-
-    return InstructionsSize(root);
-  }
-
-  final Node root;
-}
-
-class Node {
-  Node(
-    this.name, {
-    this.byteSize = 0,
-    this.parent,
-    this.children = const <String, Node>{},
-  })  : assert(name != null),
-        assert(byteSize != null),
-        assert(children != null);
-
-  static const double nodeHeight = 50.0;
-
-  final String name;
-  int byteSize;
-  Rect rect = Rect.zero;
-  final Node parent;
-  final Map<String, Node> children;
-
-  Iterable<Node> get ancestors {
-    final nodes = <Node>[];
-    Node current = this;
-    while (current.parent != null) {
-      nodes.add(current.parent);
-      current = current.parent;
-    }
-    return nodes;
-  }
-
-  bool get isLeaf => children.isEmpty;
-
-  Node findRect(Offset offset) {
-    if (rect.contains(offset)) {
-      return this;
-    }
-    for (var ancestor in ancestors) {
-      if (ancestor.rect.contains(offset)) {
-        return ancestor;
-      }
-    }
-    for (var child in children.values) {
-      final value = child.findRect(offset);
-      if (value != null) {
-        return value;
-      }
-    }
-    return null;
-  }
-
-  @override
-  String toString() => 'Node($name, $byteSize, $rect)';
-}
-
-class Symbol {
-  const Symbol({
-    @required this.name,
-    @required this.size,
-    this.libraryUri,
-    this.className,
-  })  : assert(name != null),
-        assert(size != null);
-
-  static Symbol fromMap(Map<String, dynamic> json) {
-    return Symbol(
-      name: json['n'] as String,
-      size: json['s'] as int,
-      className: json['c'] as String,
-      libraryUri: json['l'] as String,
-    );
-  }
-
-  final String name;
-  final int size;
-  final String libraryUri;
-  final String className;
-
-  List<String> get parts {
-    return <String>[
-      if (libraryUri != null) ...libraryUri.split('/') else '@stubs',
-      if (className != null && className.isNotEmpty) className,
-      name,
-    ];
-  }
-}
diff --git a/packages/devtools_app/lib/src/memory/memory_treemap.dart b/packages/devtools_app/lib/src/memory/memory_treemap.dart
new file mode 100644
index 0000000..a810167
--- /dev/null
+++ b/packages/devtools_app/lib/src/memory/memory_treemap.dart
@@ -0,0 +1,266 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/material.dart' hide TextStyle;
+import 'package:flutter/widgets.dart' hide TextStyle;
+import 'package:provider/provider.dart';
+
+import '../auto_dispose_mixin.dart';
+import '../charts/treemap.dart';
+
+import 'memory_controller.dart';
+import 'memory_graph_model.dart';
+import 'memory_utils.dart';
+
+class MemoryTreemap extends StatefulWidget {
+  const MemoryTreemap(this.controller);
+
+  final MemoryController controller;
+
+  @override
+  MemoryTreemapState createState() => MemoryTreemapState(controller);
+}
+
+class MemoryTreemapState extends State<MemoryTreemap> with AutoDisposeMixin {
+  MemoryTreemapState(this.controller);
+
+  InstructionsSize sizes;
+
+  Map<String, Function> callbacks = {};
+
+  MemoryController controller;
+
+  Widget snapshotDisplay;
+
+  TreemapNode root;
+
+  @override
+  void didChangeDependencies() {
+    super.didChangeDependencies();
+
+    // TODO(terry): Unable to short-circuit need to investigate why?
+    controller = Provider.of<MemoryController>(context);
+
+    sizes = InstructionsSize.fromSnapshot(controller);
+
+    root = sizes.root;
+
+    cancel();
+
+    addAutoDisposeListener(controller.selectedSnapshotNotifier, () {
+      setState(() {
+        controller.computeAllLibraries(true, true);
+
+        sizes = InstructionsSize.fromSnapshot(controller);
+      });
+    });
+
+    addAutoDisposeListener(controller.filterNotifier, () {
+      setState(() {
+        controller.computeAllLibraries(true, true);
+      });
+    });
+    // TODO(peterdjlee): Need to check if applicable to treemap.
+    // addAutoDisposeListener(controller.selectTheSearchNotifier, () {
+    //   setState(() {
+    //     if (_trySelectItem()) {
+    //       closeAutoCompleteOverlay();
+    //     }
+    //   });
+    // });
+
+    // addAutoDisposeListener(controller.searchNotifier, () {
+    //   setState(() {
+    //     if (_trySelectItem()) {
+    //       closeAutoCompleteOverlay();
+    //     }
+    //   });
+    // });
+
+    addAutoDisposeListener(controller.searchAutoCompleteNotifier, () {
+      setState(autoCompleteOverlaySetState(controller, context));
+    });
+  }
+
+  void _onRootChanged(TreemapNode newRoot) {
+    setState(() {
+      root = newRoot;
+    });
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    if (sizes != null) {
+      return LayoutBuilder(
+        builder: (context, constraints) {
+          return Treemap.fromRoot(
+            rootNode: root,
+            levelsVisible: 2,
+            isOutermostLevel: true,
+            height: constraints.maxHeight,
+            onRootChangedCallback: _onRootChanged,
+          );
+        },
+      );
+    } else {
+      return const SizedBox();
+    }
+  }
+}
+
+/// Definitions of exposed callback methods stored in callback Map the key
+/// is the function name (String) and the value a callback function signature.
+
+/// matchNames callback name.
+const matchNamesKey = 'matchNames';
+
+/// matchNames callback signature.
+typedef MatchNamesFunction = List<String> Function(String);
+
+/// findNode callback name.
+const findNodeKey = 'findNode';
+
+/// findNode callback signature.
+typedef FindNodeFunction = TreemapNode Function(String);
+
+/// selectNode callback name.
+const selectNodeKey = 'selectNode';
+
+/// selectNode callback signature.
+typedef SelectNodeFunction = void Function(TreemapNode);
+
+class InstructionsSize {
+  const InstructionsSize(this.root);
+
+  factory InstructionsSize.fromSnapshot(MemoryController controller) {
+    final rootChildren = <String, TreemapNode>{};
+    final root = TreemapNode(
+      name: 'root',
+      childrenMap: rootChildren,
+    );
+    TreemapNode currentParent = root;
+
+    // TODO(terry): Should treemap be all memory or just the filtered group?
+    //              Using rawGroup not graph.groupByLibrary.
+
+    controller.heapGraph.rawGroupByLibrary.forEach(
+      (libraryGroup, value) {
+        final classes = value;
+        for (final theClass in classes) {
+          final shallowSize = theClass.instancesTotalShallowSizes;
+          var className = theClass.name;
+          if (shallowSize == 0 ||
+              libraryGroup == null ||
+              className == null ||
+              className == '::') {
+            continue;
+          }
+
+          // Ensure the empty library name is our group name e.g., '' -> 'src'.
+          String libraryName = theClass.libraryUri.toString();
+          if (libraryName.isEmpty) {
+            libraryName = libraryGroup;
+          }
+
+          // Map class names to familar user names.
+          final predefined =
+              predefinedClasses[LibraryClass(libraryName, className)];
+          if (predefined != null) {
+            className = predefined.prettyName;
+          }
+
+          final symbol = Symbol(
+            name: 'new $className',
+            size: shallowSize,
+            libraryUri: libraryName,
+            className: className,
+          );
+
+          Map<String, TreemapNode> currentChildren = rootChildren;
+          final parentReset = currentParent;
+          for (String pathPart in symbol.parts) {
+            currentChildren.putIfAbsent(
+              pathPart,
+              () {
+                final node = TreemapNode(
+                  name: pathPart,
+                  childrenMap: <String, TreemapNode>{},
+                );
+                currentParent.addChild(node);
+                return node;
+              },
+            );
+            currentChildren[pathPart].byteSize += symbol.size;
+            currentParent = currentChildren[pathPart];
+            currentChildren = currentChildren[pathPart].childrenMap;
+          }
+          currentParent = parentReset;
+        }
+      },
+    );
+
+    // Get sum of children's sizes.
+    root.byteSize = root.childrenMap.values
+        .fold(0, (int current, TreemapNode node) => current + node.byteSize);
+
+    final snapshotGraph = controller.snapshots.last.snapshotGraph;
+    // Add the external heap to the treemap.
+    root.childrenMap.putIfAbsent('External Heap', () {
+      final node = TreemapNode(
+        name: 'External Heap',
+        childrenMap: <String, TreemapNode>{},
+      )..byteSize = snapshotGraph.externalSize;
+      root.addChild(node);
+      return node;
+    });
+
+    // Add the filtered libraries/classes to the treemap.
+    root.childrenMap.putIfAbsent('All Filtered Libraries', () {
+      final node = TreemapNode(
+        name: 'All Filtered Libraries',
+        childrenMap: <String, TreemapNode>{},
+      )..byteSize = snapshotGraph.shallowSize - root.byteSize;
+      root.addChild(node);
+      return node;
+    });
+
+    root.byteSize = snapshotGraph.shallowSize + snapshotGraph.externalSize;
+
+    return InstructionsSize(root);
+  }
+
+  final TreemapNode root;
+}
+
+class Symbol {
+  const Symbol({
+    @required this.name,
+    @required this.size,
+    this.libraryUri,
+    this.className,
+  })  : assert(name != null),
+        assert(size != null);
+
+  static Symbol fromMap(Map<String, dynamic> json) {
+    return Symbol(
+      name: json['n'] as String,
+      size: json['s'] as int,
+      className: json['c'] as String,
+      libraryUri: json['l'] as String,
+    );
+  }
+
+  final String name;
+  final int size;
+  final String libraryUri;
+  final String className;
+
+  List<String> get parts {
+    return <String>[
+      if (libraryUri != null) ...libraryUri.split('/') else '@stubs',
+      if (className != null && className.isNotEmpty) className,
+      name,
+    ];
+  }
+}
diff --git a/packages/devtools_app/lib/src/ui/colors.dart b/packages/devtools_app/lib/src/ui/colors.dart
index 3096989..3a7e00b 100644
--- a/packages/devtools_app/lib/src/ui/colors.dart
+++ b/packages/devtools_app/lib/src/ui/colors.dart
@@ -13,6 +13,7 @@
 Color memoryHeatMapLightColor = const Color(0xFFBBDEFB); // Material BLUE 100
 Color memoryHeatMapDarkColor = const Color(0xFF0D47A1); // Material BLUE 900
 
+// TODO(peterdjlee): Rename mainUiColor to something that more broadly matches where the color is used.
 const mainUiColor = Color(0xFF88B1DE);
 const mainRasterColor = Color(0xFF2C5DAA);
 const mainUnknownColor = Color(0xFFCAB8E9);
diff --git a/packages/devtools_app/lib/src/utils.dart b/packages/devtools_app/lib/src/utils.dart
index 51d86e8..ed39357 100644
--- a/packages/devtools_app/lib/src/utils.dart
+++ b/packages/devtools_app/lib/src/utils.dart
@@ -64,17 +64,34 @@
 
 String percent2(double d) => '${(d * 100).toStringAsFixed(2)}%';
 
+String prettyPrintBytes(int size, {bool includeUnit = false}) {
+  final sizeInKB = size / 1024.0;
+  if (sizeInKB < 1024.0) {
+    return '${printKB(size, includeUnit: includeUnit)}';
+  } else {
+    return '${printMB(size, fractionDigits: 2, includeUnit: includeUnit)}';
+  }
+}
+
 final NumberFormat _kbPattern = NumberFormat.decimalPattern()
   ..maximumFractionDigits = 0;
 
-String printKb(num bytes) {
+String printKB(num bytes, {bool includeUnit = false}) {
   // We add ((1024/2)-1) to the value before formatting so that a non-zero byte
   // value doesn't round down to 0.
-  return _kbPattern.format((bytes + 511) / 1024);
+  var output = _kbPattern.format((bytes + 511) / 1024);
+  if (includeUnit) {
+    output += ' KB';
+  }
+  return output;
 }
 
-String printMb(num bytes, [int fractionDigits = 1]) {
-  return (bytes / (1024 * 1024.0)).toStringAsFixed(fractionDigits);
+String printMB(num bytes, {int fractionDigits = 1, bool includeUnit = false}) {
+  var output = (bytes / (1024 * 1024.0)).toStringAsFixed(fractionDigits);
+  if (includeUnit) {
+    output += ' MB';
+  }
+  return output;
 }
 
 String msText(
diff --git a/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift
index 8236f57..4618f38 100644
--- a/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -5,8 +5,10 @@
 import FlutterMacOS
 import Foundation
 
+import path_provider_macos
 import url_launcher_macos
 
 func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
+  PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
   UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
 }
diff --git a/packages/devtools_app/test/timeline_flame_chart_test.dart b/packages/devtools_app/test/timeline_flame_chart_test.dart
index 4052631..5a43356 100644
--- a/packages/devtools_app/test/timeline_flame_chart_test.dart
+++ b/packages/devtools_app/test/timeline_flame_chart_test.dart
@@ -69,10 +69,7 @@
       await pumpTimelineBody(tester, TimelineController());
       await tester.pumpAndSettle();
       expect(find.byType(TimelineFlameChart), findsNothing);
-      expect(
-        find.byKey(TimelineScreen.emptyTimelineKey),
-        findsOneWidget,
-      );
+      expect(find.byKey(TimelineScreen.emptyTimelineKey), findsOneWidget);
     });
 
     testWidgetsWithWindowSize(
@@ -85,6 +82,7 @@
       await tester.pumpAndSettle();
 
       expect(find.byType(TimelineFlameChart), findsOneWidget);
+<<<<<<< HEAD
       await expectLater(
           find.byType(TimelineFlameChart),
           matchesGoldenFile(
@@ -93,5 +91,12 @@
       // Await delay for golden comparison.
       await tester.pumpAndSettle(const Duration(seconds: 2));
     }, skip: kIsWeb || !Platform.isMacOS);
+=======
+      expect(
+          find.byType(TimelineFlameChart),
+          matchesGoldenFile(
+              'goldens/timeline_flame_chart_with_selected_frame.png'));
+    });
+>>>>>>> 4191e172... Fix merge conflict
   });
 }
diff --git a/packages/devtools_app/test/utils_test.dart b/packages/devtools_app/test/utils_test.dart
index daaf198..91dd59a 100644
--- a/packages/devtools_app/test/utils_test.dart
+++ b/packages/devtools_app/test/utils_test.dart
@@ -11,27 +11,40 @@
 
 void main() {
   group('utils', () {
+    test('prettyPrintBytes', () {
+      const int kb = 1024;
+      const int mb = 1024 * kb;
+
+      expect(prettyPrintBytes(kb), '1');
+      expect(prettyPrintBytes(kb, includeUnit: true), '1 KB');
+      expect(prettyPrintBytes(kb * 1000, includeUnit: true), '1,000 KB');
+
+      expect(prettyPrintBytes(mb), '1.00');
+      expect(prettyPrintBytes(mb, includeUnit: true), '1.00 MB');
+      expect(prettyPrintBytes(mb - kb, includeUnit: true), '1,023 KB');
+    });
+
     test('printKb', () {
       const int kb = 1024;
 
-      expect(printKb(0), '0');
-      expect(printKb(1), '1');
-      expect(printKb(kb - 1), '1');
-      expect(printKb(kb), '1');
-      expect(printKb(kb + 1), '2');
-      expect(printKb(2000), '2');
+      expect(printKB(0), '0');
+      expect(printKB(1), '1');
+      expect(printKB(kb - 1), '1');
+      expect(printKB(kb), '1');
+      expect(printKB(kb + 1), '2');
+      expect(printKB(2000), '2');
     });
 
     test('printMb', () {
-      const int MB = 1024 * 1024;
+      const int mb = 1024 * 1024;
 
-      expect(printMb(10 * MB, 0), '10');
-      expect(printMb(10 * MB), '10.0');
-      expect(printMb(10 * MB, 2), '10.00');
+      expect(printMB(10 * mb, fractionDigits: 0), '10');
+      expect(printMB(10 * mb), '10.0');
+      expect(printMB(10 * mb, fractionDigits: 2), '10.00');
 
-      expect(printMb(1000 * MB, 0), '1000');
-      expect(printMb(1000 * MB), '1000.0');
-      expect(printMb(1000 * MB, 2), '1000.00');
+      expect(printMB(1000 * mb, fractionDigits: 0), '1000');
+      expect(printMB(1000 * mb), '1000.0');
+      expect(printMB(1000 * mb, fractionDigits: 2), '1000.00');
     });
 
     test('msAsText', () {
