diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2664,6 +2664,7 @@
     'PhabricatorChartAxis' => 'applications/fact/chart/PhabricatorChartAxis.php',
     'PhabricatorChartDataQuery' => 'applications/fact/chart/PhabricatorChartDataQuery.php',
     'PhabricatorChartDataset' => 'applications/fact/chart/PhabricatorChartDataset.php',
+    'PhabricatorChartDisplayData' => 'applications/fact/chart/PhabricatorChartDisplayData.php',
     'PhabricatorChartEngine' => 'applications/fact/engine/PhabricatorChartEngine.php',
     'PhabricatorChartFunction' => 'applications/fact/chart/PhabricatorChartFunction.php',
     'PhabricatorChartFunctionArgument' => 'applications/fact/chart/PhabricatorChartFunctionArgument.php',
@@ -8681,6 +8682,7 @@
     'PhabricatorChartAxis' => 'Phobject',
     'PhabricatorChartDataQuery' => 'Phobject',
     'PhabricatorChartDataset' => 'Phobject',
+    'PhabricatorChartDisplayData' => 'Phobject',
     'PhabricatorChartEngine' => 'Phobject',
     'PhabricatorChartFunction' => 'Phobject',
     'PhabricatorChartFunctionArgument' => 'Phobject',
diff --git a/src/applications/fact/chart/PhabricatorChartDataset.php b/src/applications/fact/chart/PhabricatorChartDataset.php
--- a/src/applications/fact/chart/PhabricatorChartDataset.php
+++ b/src/applications/fact/chart/PhabricatorChartDataset.php
@@ -66,11 +66,12 @@
     );
   }
 
-  final public function getWireFormat(PhabricatorChartDataQuery $data_query) {
-    return $this->newWireFormat($data_query);
+  final public function getChartDisplayData(
+    PhabricatorChartDataQuery $data_query) {
+    return $this->newChartDisplayData($data_query);
   }
 
-  abstract protected function newWireFormat(
+  abstract protected function newChartDisplayData(
     PhabricatorChartDataQuery $data_query);
 
 
diff --git a/src/applications/fact/chart/PhabricatorChartDisplayData.php b/src/applications/fact/chart/PhabricatorChartDisplayData.php
new file mode 100644
--- /dev/null
+++ b/src/applications/fact/chart/PhabricatorChartDisplayData.php
@@ -0,0 +1,27 @@
+<?php
+
+final class PhabricatorChartDisplayData
+  extends Phobject {
+
+  private $wireData;
+  private $range;
+
+  public function setWireData(array $wire_data) {
+    $this->wireData = $wire_data;
+    return $this;
+  }
+
+  public function getWireData() {
+    return $this->wireData;
+  }
+
+  public function setRange(PhabricatorChartInterval $range) {
+    $this->range = $range;
+    return $this;
+  }
+
+  public function getRange() {
+    return $this->range;
+  }
+
+}
diff --git a/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php b/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php
--- a/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php
+++ b/src/applications/fact/chart/PhabricatorChartStackedAreaDataset.php
@@ -5,7 +5,8 @@
 
   const DATASETKEY = 'stacked-area';
 
-  protected function newWireFormat(PhabricatorChartDataQuery $data_query) {
+  protected function newChartDisplayData(
+    PhabricatorChartDataQuery $data_query) {
     $functions = $this->getFunctions();
 
     $function_points = array();
@@ -93,6 +94,9 @@
       ksort($function_points[$function_idx]);
     }
 
+    $range_min = null;
+    $range_max = null;
+
     $series = array();
     $baseline = array();
     foreach ($function_points as $function_idx => $points) {
@@ -117,6 +121,16 @@
         if (isset($raw_points[$function_idx][$x])) {
           $raw_points[$function_idx][$x]['y1'] = $y1;
         }
+
+        if ($range_min === null) {
+          $range_min = $y0;
+        }
+        $range_min = min($range_min, $y0, $y1);
+
+        if ($range_max === null) {
+          $range_max = $y1;
+        }
+        $range_max = max($range_max, $y0, $y1);
       }
 
       $series[] = $bounds;
@@ -147,7 +161,9 @@
       'labels' => $wire_labels,
     );
 
-    return $result;
+    return id(new PhabricatorChartDisplayData())
+      ->setWireData($result)
+      ->setRange(new PhabricatorChartInterval($range_min, $range_max));
   }
 
 
diff --git a/src/applications/fact/engine/PhabricatorChartRenderingEngine.php b/src/applications/fact/engine/PhabricatorChartRenderingEngine.php
--- a/src/applications/fact/engine/PhabricatorChartRenderingEngine.php
+++ b/src/applications/fact/engine/PhabricatorChartRenderingEngine.php
@@ -145,20 +145,22 @@
       ->setLimit(2000);
 
     $wire_datasets = array();
+    $ranges = array();
     foreach ($datasets as $dataset) {
-      $wire_datasets[] = $dataset->getWireFormat($data_query);
+      $display_data = $dataset->getChartDisplayData($data_query);
+
+      $ranges[] = $display_data->getRange();
+      $wire_datasets[] = $display_data->getWireData();
     }
 
-    // TODO: Figure these out from the datasets again.
-    $y_min = -2;
-    $y_max = 20;
+    $range = $this->getRange($ranges);
 
     $chart_data = array(
       'datasets' => $wire_datasets,
       'xMin' => $domain->getMin(),
       'xMax' => $domain->getMax(),
-      'yMin' => $y_min,
-      'yMax' => $y_max,
+      'yMin' => $range->getMin(),
+      'yMax' => $range->getMax(),
     );
 
     return $chart_data;
@@ -186,4 +188,22 @@
     return $domain;
   }
 
+  private function getRange(array $ranges) {
+    $range = PhabricatorChartInterval::newFromIntervalList($ranges);
+
+    // Start the Y axis at 0 unless the chart has negative values.
+    $min = $range->getMin();
+    if ($min === null || $min >= 0) {
+      $range->setMin(0);
+    }
+
+    // If there's no maximum value, just pick a plausible default.
+    $max = $range->getMax();
+    if ($max === null) {
+      $range->setMax($range->getMin() + 100);
+    }
+
+    return $range;
+  }
+
 }