Skip to content

Instantly share code, notes, and snippets.

@biovisualize
Created October 11, 2011 05:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biovisualize/1277343 to your computer and use it in GitHub Desktop.
Save biovisualize/1277343 to your computer and use it in GitHub Desktop.
Parallel Coordinates Plot (first draft)
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
(function(){bio = {};
bio.pcp = {
init : function(container, x, y, w, h){
// mock data
var data = [],
dataMax = 100,
dataDim = [],
axisNum = 5,
polylineNum = 100;
for(var i=0; i<axisNum; i++){
data[i] = [];
for(var j=0; j<polylineNum; j++){
data[i][j] = ~~(Math.random()*dataMax);
}
dataDim.push("dimension"+i);
}
var container = container || "body",
margin = 10,
labelH = 20,
axisH = h-margin*2-labelH,
axisDist = w/data.length;
var rootSVG = d3.select(container)
.append("svg:svg")
.attr("class", "pcp_root")
.attr("width", w)
.attr("height", h);
var axisGroups = rootSVG.selectAll("g.axis_group")
.data(data)
.enter().append("svg:g")
.attr("class", "axis_group")
.each(function(parentD, parentI){
d3.select(this)
.selectAll("circle.dot")
.data(function(d, i){return d;})
.enter().append("svg:circle")
.attr("class", "dot")
.attr("cx", function(d, i){return parentI*axisDist+margin})
.attr("cy", function(d, i){return d/dataMax*axisH+margin})
.attr("r", 1);
if(parentI < data.length-1){
d3.select(this)
.selectAll("line.link")
.data(function(d, i){return d;})
.enter().append("svg:line")
.attr("class", "link")
.attr("x1", function(d, i){return parentI*axisDist+margin})
.attr("y1", function(d, i){return d/dataMax*axisH+margin})
.attr("x2", function(d, i){return (parentI+1)*axisDist+margin})
.attr("y2", function(d, i){return data[parentI+1][i]/dataMax*axisH+margin})
.attr("stroke", "black")
.attr("opacity", 0.5);
}
});
axisGroups.append("svg:line")
.attr("class", "axis")
.attr("x1", function(d, i){return i*axisDist+margin})
.attr("y1", margin)
.attr("x2", function(d, i){return i*axisDist+margin})
.attr("y2", axisH+margin)
.attr("stroke", "silver");
axisGroups.append("svg:rect")
.attr("class", "label")
.attr("x", function(d, i){return i*axisDist+margin})
.attr("y", axisH+margin+10) //offset hardcoded
.attr("width", 80) //hardcoded
.attr("height", labelH)
.attr("stroke", "black")
.attr("fill", "white");
axisGroups.append("svg:text")
.attr("x", function(d, i){return i*axisDist+margin})
.attr("y", axisH+margin+labelH+5) //offset hardcoded
.text(function(d, i){return dataDim[i];})
.style("pointer-events", "none");
//document.onselectstart = function(){return false;};
rootSVG.node().onselectstart = function(){return false;};
rootSVG.on("mousedown", addBrush)
.on("mouseup", removeBrush);
var brushStartValue = 0;
var brushEndValue = dataMax;
var axisIdx = null;
function addBrush(){
rootSVG.on("mousemove", moveBrush);
axisIdx = Math.round((event.offsetX-margin)/axisDist);
rootSVG.append("svg:line")
.attr("class", "slider")
.attr("x1", axisIdx*axisDist+margin-20)
.attr("y1", event.offsetY)
.attr("x2", axisIdx*axisDist+margin+20)
.attr("y2", event.offsetY)
.attr("stroke", "black");
brushStartValue = event.offsetY;
}
function moveBrush(){
if(event.which != 1) return;
rootSVG.select("line.slider")
.attr("class", "slider")
.attr("y1", Math.max(margin, Math.min(margin+axisH, event.offsetY)))
.attr("y2", Math.max(margin, Math.min(margin+axisH, event.offsetY)))
brushEndValue = event.offsetY;
fadeUnselected(brushStartValue, brushEndValue);
}
function removeBrush(){
rootSVG.on("mousemove", null);
d3.selectAll(".slider")
.remove();
}
function fadeUnselected(startX, endX){
d3.selectAll("line.link")
.attr("opacity", function(d, i){
var indexJ = i%polylineNum;
var dataAtTargetAxis = data[axisIdx][indexJ];
var y1 = dataAtTargetAxis/dataMax*axisH+margin;
if(y1 > brushStartValue && y1 < brushEndValue) return 0.5;
else return 0.1;
});
}
function moveAxis(){
//console.log(this.parentNode);
}
return this;
}
};
})();
bio.pcp.init("#viz", 0, 0, 600, 200);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment