 
     ctx.restore()
 
+  ##duped
+  select : (xscreenbounds, yscreenbounds) ->
+    xscreenbounds = [@plot_view.view_state.sx_to_device(xscreenbounds[0]),
+      @plot_view.view_state.sx_to_device(xscreenbounds[1])]
+    yscreenbounds = [@plot_view.view_state.sy_to_device(yscreenbounds[0]),
+      @plot_view.view_state.sy_to_device(yscreenbounds[1])]
+    xscreenbounds = [_.min(xscreenbounds), _.max(xscreenbounds)]
+    yscreenbounds = [_.min(yscreenbounds), _.max(yscreenbounds)]
+    selected = []
+    for i in [0..@sx.length-1]
+      if xscreenbounds
+        if @sx[i] < xscreenbounds[0] or @sx[i] > xscreenbounds[1]
+          continue
+      if yscreenbounds
+        if @sy[i] < yscreenbounds[0] or @sy[i] > yscreenbounds[1]
+          continue
+      selected.push(i)
+     return selected
+
 
 class Annulus extends Glyph
   default_view: AnnulusView

class AnnulusView extends GlyphView

  initialize: (options) ->
    glyphspec = @mget('glyphspec')
    @glyph_props = new glyph_properties(
      @,
      glyphspec,
      ['x', 'y', 'inner_radius', 'outer_radius'],

        ctx.arc(@sx[i], @sy[i], @outer_radius[i], 0, 2*Math.PI*2, true)
        ctx.stroke()

  _full_path: (ctx, glyph_props, use_selection) ->
    #duped
    if not glyph_props
      glyph_props = @glyph_props
    for i in [0..@sx.length-1]
      if isNaN(@sx[i] + @sy[i] + @inner_radius[i] + @outer_radius[i])
        continue
      #duped
      if use_selection == 'selected' and not @selected_mask[i]
        continue
      if use_selection == 'unselected' and @selected_mask[i]
        continue
      ctx.beginPath()
      ctx.arc(@sx[i], @sy[i], @inner_radius[i], 0, 2*Math.PI*2, false)
      ctx.moveTo(@sx[i]+@outer_radius[i], @sy[i])
      ctx.arc(@sx[i], @sy[i], @outer_radius[i], 0, 2*Math.PI*2, true)

      if @do_fill
        glyph_props.fill_properties.set(ctx, @data[i])
        ctx.fill()

      if @do_stroke
        glyph_props.line_properties.set(ctx, @data[i])
        ctx.stroke()

  draw_legend: (ctx, x1, x2, y1, y2) ->
