Skip to content

Instantly share code, notes, and snippets.

@syntagmatic
Last active December 16, 2015 13:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syntagmatic/5441022 to your computer and use it in GitHub Desktop.
Save syntagmatic/5441022 to your computer and use it in GitHub Desktop.
Line Intersection Brushing

Select lines in parallel coordinates by brushing an intersecting line. Called "pinch" in Alfred Inselberg's Parallax software.

<style>
html, body { margin: 0; }
</style>
<title>Line Intersection Tests</title>
<body>
<canvas id="canvas" width="960" height="500"></canvas>
</body>
<script src="http://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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment