       good_formats = []
       for i in [0...widths.length]
         if widths[i] * ticks.length < fill_ratio * char_width
-          # FIXME I think "@formats" should be "formats".  (Perhaps they
-          # should have more distinct names.)
-          good_formats.push(@formats[i])
+          good_formats.push(@_width_formats[i])
       if good_formats.length > 0
         format = _.last(good_formats)
 

  # to the nearest microsecond should round to a nice
  # microsecond / millisecond tick.
  return Math.round(((t / 1000) % 1) * 1000000)

_two_digit_year = (t) ->
  # Round to the nearest Jan 1, roughly.
  dt = new Date(t)
  year = dt.getFullYear()
  if dt.getMonth() >= 7
      year += 1
  return SPrintf.sprintf("'%02d", (year % 100))

_four_digit_year = (t) ->
  # Round to the nearest Jan 1, roughly.
  dt = new Date(t)
  year = dt.getFullYear()
  if dt.getMonth() >= 7
      year += 1
  return SPrintf.sprintf("%d", year)

_array = (t) ->
  return tz(t, "%Y %m %d %H %M %S").split(/\s+/).map( (e) -> return parseInt(e, 10) );


  initialize: (attrs, options) ->
    super(attrs, options)
    @formats = _.extend({}, @_formats, @get("formats"))
    @_update_width_formats()
    # TODO (bev) trigger update on format change

  _update_width_formats: () ->
    now = tz(new Date())
    @_width_formats = {}

    for fmt_name, fmt_strings of @formats
      sizes = (_strftime(now, fmt_string).length for fmt_string in fmt_strings)
      sorted = _.sortBy(_.zip(sizes, fmt_strings), ([size, fmt]) -> size)
      @_width_formats[fmt_name] = _.zip.apply(_, sorted)

  # FIXME There is some unfortunate flicker when panning/zooming near the
  # span boundaries.
