block by eglassman 6f7cbde4826a86c18f92

Block

Full Screen

I would like to ink on some d3-created visualizations. I really like d3, so I thought I’d create the inking with it too, instead of introducing another library into my project.

However, I could only find one demo of d3-based inking: a block on bl.ocks.org by ‘cloudshape’.

It was almost exactly what I wanted, except there was this strange offset between where I placed my mouse, and where the line was drawn. So… I copied the code into Brackets and modified it until this offset was gone. I think it’s a small but significant improvement. Now I’m sharing it as a ‘block’ of my own!

Cloudshapes, thank you so much for creating the original drawing app. You did all this work, and I am grateful. I just changed one line of code!

index.html

<!doctype html>
<html lang="en">
<head lang=en>
<meta charset="utf-8">
<title>D3: Dotted Path Following the Mouse</title>
<style>

svg {
  background: #ddd;
  font: 10px sans-serif;
}

.line {
  fill: none;
  stroke: #FF0000;
  stroke-width: 3px;
}

</style>
</head>

<body>

<script src="//d3js.org/d3.v3.min.js"></script>
<script>

var margin = {top: 10, right: 10, bottom: 20, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;


var npoints = 25;
var ptdata = [];
var listOfPTdata = [];

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d, i) { return d[0]; })
    .y(function(d, i) { return d[1]; });

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g");
    //.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var svgagain = d3.select("body").select("svg")
    .on("mousedown", function(){
        d3.select("body").select("svg").on("mousemove", function() { 
            var pt = d3.mouse(this); 
            tick(pt); 
        });
    })
    .on("mouseup", function(){
        d3.select("body").select("svg").on("mousemove",null);
        var ans = prompt('Why is this confusing?');
        console.log(ans)
        listOfPTdata.push(ptdata.slice());
        console.log(listOfPTdata)
        //ptdata = [];
    });


//listOfPTdata.forEach(function(d,i){
var path = svg.append("g")
  .append("path")
    .data([ptdata])
    .attr("class", "line")
    .attr("d", line);
//});



function tick(pt) {

  // push a new data point onto the back
  ptdata.push(pt);

  // Redraw the path:
  path
      .attr("d", function(d) { return line(d);})


  // If more than 100 points, drop the old data pt off the front
  if (ptdata.length > npoints) {
	  ptdata.shift();
  }
}
</script>
</body>
</html>