         .attr("pointer-events", "all")
         .on("mousedown.drag", @plot_drag)
         .on("touchstart.drag", @plot_drag)
-        @plot.call(d3.behavior.zoom().x(@x).y(@y).on("zoom", @redraw()))
+        @plot.call(d3.behavior.zoom().x(@x).y(@y).on("zoom", @redraw))
 
     @vis.append("svg")
         .attr("top", 0)

      newpoint.x = @x.invert(Math.max(0, Math.min(@size.width,  p[0])));
      newpoint.y = @y.invert(Math.max(0, Math.min(@size.height, p[1])));
      @points.push(newpoint);
      @points.sort( (a, b) ->
        return -1 if a.x < b.x
        return  1 if a.x > b.x
        return 0
      )
      @selected = newpoint
      @update()
      d3.event.preventDefault()

  redraw: () =>
    console.log "REDRAWing"
    self = this;
    # return () ->
    tx = (d) ->
      return "translate(" + self.x(d) + ",0)"
    ty = (d) ->
      return "translate(0," + self.y(d) + ")"
    stroke = (d) ->
      return if d then "#ccc" else "#666"
    fx = self.x.tickFormat(10)
    fy = self.y.tickFormat(10)

    # Regenerate x-ticks…
    gx = self.vis.selectAll("g.x")
        .data(self.x.ticks(10), String)
        .attr("transform", tx)

    gx.select("text")
        .text(fx)

    gxe = gx.enter().insert("g", "a")
        .attr("class", "x")
        .attr("transform", tx)

    gxe.append("line")
        .attr("stroke", stroke)
        .attr("y1", 0)
        .attr("y2", self.size.height)

    gxe.append("text")
        .attr("class", "axis")
        .attr("y", self.size.height)
        .attr("dy", "1em")
        .attr("text-anchor", "middle")
        .text(fx)
        .style("cursor", "ew-resize")
        .on("mouseover", (d) -> d3.select(this).style("font-weight", "bold"))
        .on("mouseout",  (d) -> d3.select(this).style("font-weight", "normal"))
        .on("mousedown.drag",  self.xaxis_drag)
        .on("touchstart.drag", self.xaxis_drag);

    gx.exit().remove();

    # Regenerate y-ticks…
    gy = self.vis.selectAll("g.y")
        .data(self.y.ticks(10), String)
        .attr("transform", ty)

    gy.select("text")
        .text(fy);

    gye = gy.enter().insert("g", "a")
        .attr("class", "y")
        .attr("transform", ty)
        .attr("background-fill", "#FFEEB6")

    gye.append("line")
        .attr("stroke", stroke)
        .attr("x1", 0)
        .attr("x2", self.size.width)

    gye.append("text")
        .attr("class", "axis")
        .attr("x", -3)
        .attr("dy", ".35em")
        .attr("text-anchor", "end")
        .text(fy)
        .style("cursor", "ns-resize")
        .on("mouseover", (d) -> d3.select(this).style("font-weight", "bold"))
        .on("mouseout",  (d) -> d3.select(this).style("font-weight", "normal"))
        .on("mousedown.drag",  self.yaxis_drag)
        .on("touchstart.drag", self.yaxis_drag)

    gy.exit().remove();
    self.plot.call(d3.behavior.zoom().x(self.x).y(self.y).on("zoom", self.redraw));
    self.update();    

  update: () =>
    lines = @vis.select("path").attr("d", @line(@points));
          
    circle = @vis.select("svg").selectAll("circle")
        .data(@points, (d) -> return d)

    circle.enter().append("circle")
        .attr("class", (d) => if d is @selected then "selected" else null )
        .attr("cx",    (d) => @x(d.x) )
        .attr("cy",    (d) => @y(d.y) )
        .attr("r", 10.0)
        .style("cursor", "ns-resize")
        .on("mousedown.drag",  @datapoint_drag)
        .on("touchstart.drag", @datapoint_drag);

    circle
        .attr("class", (d) => if d is @selected then "selected" else null )
        .attr("cx",    (d) => @x(d.x) )
        .attr("cy",    (d) => @y(d.y) )

    circle.exit().remove();

