toolkit/javascript/d3/examples/spline/spline.js
author Nicolas Sauret <nicolas.sauret@iri.centrepompidou.fr>
Fri, 18 Apr 2014 14:31:58 +0200
changeset 51 79833eaa394a
parent 47 c0b4a8b5a012
permissions -rw-r--r--
set up second level for navigation

var w = 960,
    h = 500,
    line = d3.svg.line(),
    points = d3.range(1, 5).map(function(i) { return [i * w / 5, 50 + Math.random() * (h - 100)]; }),
    dragged = null,
    selected = points[0];

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

vis.append("svg:rect")
    .attr("width", w)
    .attr("height", h)
    .on("mousedown", function() {
      points.push(selected = dragged = d3.svg.mouse(vis.node()));
      update();
    });

vis.append("svg:path")
    .data([points])
    .attr("class", "line")
    .call(update);

d3.select(window)
    .on("mousemove", mousemove)
    .on("mouseup", mouseup)
    .on("keydown", keydown);

// Add interpolator dropdown
d3.select("#interpolate")
    .on("change", function() {
      line.interpolate(this.value);
      update();
    })
  .selectAll("option")
    .data([
      "linear",
      "step-before",
      "step-after",
      "basis",
      "basis-open",
      "basis-closed",
      "cardinal",
      "cardinal-open",
      "cardinal-closed",
      "monotone"
    ])
  .enter().append("option")
    .attr("value", String)
    .text(String);

function update() {
  vis.select("path").attr("d", line);

  var circle = vis.selectAll("circle")
      .data(points, function(d) { return d; });

  circle.enter().append("svg:circle")
      .attr("class", function(d) { return d === selected ? "selected" : null; })
      .attr("cx", function(d) { return d[0]; })
      .attr("cy", function(d) { return d[1]; })
      .attr("r", 1e-6)
      .on("mousedown", function(d) {
        selected = dragged = d;
        update();
      })
    .transition()
      .duration(750)
      .ease("elastic")
      .attr("r", 6.5);

  circle
      .attr("class", function(d) { return d === selected ? "selected" : null; })
      .attr("cx", function(d) { return d[0]; })
      .attr("cy", function(d) { return d[1]; });

  circle.exit().remove();

  if (d3.event) {
    d3.event.preventDefault();
    d3.event.stopPropagation();
  }
}


function mousemove() {
  if (!dragged) return;
  var m = d3.svg.mouse(vis.node());
  dragged[0] = Math.max(0, Math.min(w, m[0]));
  dragged[1] = Math.max(0, Math.min(h, m[1]));
  update();
}

function mouseup() {
  if (!dragged) return;
  mousemove();
  dragged = null;
}

function keydown() {
  if (!selected) return;
  switch (d3.event.keyCode) {
    case 8: // backspace
    case 46: { // delete
      var i = points.indexOf(selected);
      points.splice(i, 1);
      selected = points.length ? points[i > 0 ? i - 1 : 0] : null;
      update();
      break;
    }
  }
}