anchor.diff:        _rowHeight,
       );
   
  -    // Draw the first grid item since it will have a different width than the
  -    // rest.
  -    final gridItem = TimelineGridNode(
  -      0,
  -      _flameChartInset,
  -      const Duration(microseconds: 0),
  -    );
  -
  -    gridItem.paint(canvas, viewport, visible);
  -
       num left =
           (visible.left - _flameChartInset) ~/ currentInterval * currentInterval +
               _flameChartInset;
   
  +    final firstGridNodeText = msText(
  +      const Duration(microseconds: 0),
  +      fractionDigits: 1,
  +    );
  +
  +    canvas
  +      ..font = fontStyleToCss(const TextStyle(fontSize: _fontSize))
  +      ..fillStyle = colorToCss(timestampColor)
  +      ..strokeStyle = colorToCss(gridLineColor)
  +      ..lineWidth = gridLineWidth
  +      ..beginPath()
  +      // Handle the first grid node since it will have a different width than
  +      // the rest.
  +      ..fillText(
  +        firstGridNodeText,
  +        _getTimestampLeft(firstGridNodeText, 0, _flameChartInset, canvas),
  +        viewport.top + _textOffsetY,
  +      )
  +      ..moveTo(_flameChartInset, visible.top)
  +      ..lineTo(_flameChartInset, visible.bottom);
  +
       while (left < visible.right) {
  +      if (left + currentInterval < visible.left || left > visible.right) {
  +        // We do not need to draw the grid node because it is out of view.
  +        return;
  +      }
  +
         // TODO(kenzie): Instead of calculating timestamp based on position, track
         // timestamp var and increment it by time interval represented by each
         // grid item. See comment on https://github.com/flutter/devtools/pull/325.
  -      final Duration timestamp = Duration(
  +      final timestamp = Duration(
             microseconds: getTimestampForPosition(left + currentInterval));
  -      final gridItem = TimelineGridNode(left, currentInterval, timestamp);
  -
  -      gridItem.paint(canvas, viewport, visible);
  +
  +      final timestampText = msText(
  +        timestamp,
  +        fractionDigits: timestamp.inMicroseconds == 0 ? 1 : 3,
  +      );
  +
  +      final timestampX = _getTimestampLeft(
  +        timestampText,
  +        left,
  +        currentInterval,
  +        canvas,
  +      );
  +
  +      // Paint the timestamps and compute the line to stroke for the grid lines.
  +      canvas
  +        ..fillText(timestampText, timestampX, viewport.top + _textOffsetY)
  +        ..moveTo(left + currentInterval, visible.top)
  +        ..lineTo(left + currentInterval, visible.bottom);
   
         left += currentInterval;
       }
  +
  +    // Paint the grid lines.
  +    canvas
  +      ..closePath()
  +      ..stroke();
  +  }
  +
  +  num _getTimestampLeft(
  +    String timestampText,
  +    num left,
  +    num width,
  +    CanvasRenderingContext2D canvas,
  +  ) {
  +    return left +
  +        width -
  +        canvas.measureText(timestampText).width -
  +        timestampOffsetX;
     }
   
     /// Returns the timestamp rounded to the nearest microsecond for the
  
positive.code:   TimelineGrid(this._duration, this._flameChartWidth);
  
    static const baseGridIntervalPx = 150;
  
    /// Frame duration in micros.
    final num _duration;
  
negative.code:     _zoomLevel = newZoomLevel;
    }
  }
  