     else
       @listenTo(@model, 'data_update', @plot_view.request_render)
 
+  _set_data: () ->
+    @label_div = ($("<div>").addClass('label').hide() for i in @text)
+    @width = (null for i in @text)
+    @height = (null for i in @text)
+    @x_shift = (null for i in @text)
+    @y_shift = (null for i in @text)
+
+    ctx = @plot_view.canvas_view.ctx
+    for i in [0...@text.length]
+      @visuals.text.set_vectorize(ctx, i)
+      @width[i] = ctx.measureText(@text[i]).width
+      @height[i] = ctx.measureText(@text[i]).ascent / 1.6
+      [ @x_shift[i], @y_shift[i] ] = @_calculate_offset(ctx, @height[i], @width[i])
+
+  _calculate_offset: (ctx, height, width) ->
+    if ctx.textAlign == 'left'
+      x_shift = 0
+    if ctx.textAlign == 'center'
+      x_shift = -width / 2
+    if ctx.textAlign == 'right'
+      x_shift = -width
+
+    if ctx.textBaseline == 'top'
+      y_shift = 0.2 * height
+    if ctx.textBaseline == 'middle'
+      y_shift = -height / 2
+    if ctx.textBaseline == 'bottom'
+      y_shift = -1.2 * height
+    if ctx.textBaseline == 'alphabetic'
+      y_shift = -3 * height / 4 - 0.2 * height
+    if ctx.textBaseline == 'hanging'
+      y_shift = -height / 4 + 0.2 * height
+
+    return [x_shift, y_shift]
+
   render: () ->
+
     @map_data() ##unclear why calling this in init returns NaNs
 
     if @mget('render_mode') == 'canvas'


  _canvas_text: () ->
    ctx = @plot_view.canvas_view.ctx
    for i in [0...@x.length]
      ctx.save()
      ctx.translate(@sx[i], @sy[i])
      ctx.rotate(@mget('angle'))

      @visuals.text.set_value(ctx)
      ctx.fillText(@text[i], 0, 0)
      ctx.restore()

  _css_text: () ->
    for i in [0...@text.length]
      if @label_div[i] == null
        @label_div[i] = $("<div>")
          .html(@text[i])
          .addClass('label')
          .css({
            'position': 'absolute'
            'top': "#{@sy[i] + @mget('y_offset')}px"
            'left': "#{@sx[i] + @mget('x_offset')}px"
            # 'background-color': 'rgba(255, 255, 255, 0)'
            'font-size': '9pt'
            'font-family': 'sans-serif'
            })

        overlays = @plot_view.$el.find('div.bk-canvas-events')
        @label_div[i].appendTo(overlays)

      else
        @label_div[i]
          .html(@text[i])
          .css({
            'position': 'absolute'
            'top': "#{@sy[i] + @mget('y_offset')}px"
            'left': "#{@sx[i] + @mget('x_offset')}px"
            # 'background-color': 'rgba(255, 255, 255, 0)'
            'font-size': '9pt'
            'font-family': 'sans-serif'
            })

class Label extends Annotation.Model
  default_view: LabelView

class LabelView extends Renderer.View
  initialize: (options) ->
    super(options)

    @set_visuals(@mget('source'))
    @set_data(@mget('source'))

  bind_bokeh_events: () ->
    if @mget('render_mode') == 'css'
