block by renecnielsen 3d2313ff60b01f0dfcf8

Line Intersection Brushing

Full Screen

Select lines in parallel coordinates by brushing an intersecting line. Called “pinch” in Alfred Inselberg’s Parallax software.

forked from syntagmatic‘s block: Line Intersection Brushing

index.html

<style>
  html, body { margin: 0; }
</style>
<title>Line Intersection Tests</title>
<body>
  <canvas id="canvas" width="960" height="500"></canvas>    
</body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 960;
var height = 500;
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = "rgba(0,0,0,0.05)";
ctx.lineWidth = 2.5;

var p1 = [0,0];
var p2 = [0,0];

var drag = d3.behavior.drag()
  .on("dragstart", function(d,i) {
    var ev = d3.event.sourceEvent;
    p1 = [ev.x,ev.y];
  })
  .on("drag", function(d,i) {
    mouseMove(d3.event.x,d3.event.y);
  });

d3.select("#canvas")
  .call(drag);

var points = [];
for (var i = 0; i < 600; i++) {
  var point = [Math.random()*height, Math.random()*height];
  line([0,point[0]],[width,point[1]]);
  points.push(point);
}

function mouseMove(x,y) {
  ctx.clearRect(0, 0, width, height);
  p2 = [x,y];

  // type of lines
  var test = containmentTest(p1,p2);

  points.forEach(function(point) {
    ctx.strokeStyle = "rgba(90,80,70,0.05)";
    // containment test
    if (test(point)) ctx.strokeStyle = "rgba(0,80,120,0.5)";
    line([0,point[0]],[width,point[1]]);
  });

  // sweeper
  ctx.strokeStyle = "#0f8";
  line(p1,p2);
};

function line(p1,p2) {
  ctx.beginPath();
  ctx.moveTo(p1[0],p1[1]);
  ctx.lineTo(p2[0],p2[1]);
  ctx.stroke();
};

function containmentTest(p1,p2) {
  var m1 = 1 - width/p1[0];
  var b1 = p1[1]*(1-m1);
  var m2 = 1 - width/p2[0];
  var b2 = p2[1]*(1-m2);
  
  // test if point falls between lines
  return function(p) {
    var x = p[0];
    var y = p[1];
    var y1 = m1*x + b1;
    var y2 = m2*x + b2;
    if (y > Math.min(y1,y2) && y < Math.max(y1,y2)) return true;
    return false;
  };
};
</script>