Skip to content

Instantly share code, notes, and snippets.

@syntagmatic
Created November 5, 2012 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save syntagmatic/4020926 to your computer and use it in GitHub Desktop.
Save syntagmatic/4020926 to your computer and use it in GitHub Desktop.
Parallel Coordinates Ordinal Axis
name economy (mpg) cylinders displacement (cc) power (hp) weight (lb) 0-60 mph (s) year
AMC Ambassador Brougham 13 8 360 175 3821 11 73
AMC Ambassador DPL 15 8 390 190 3850 8.5 70
AMC Ambassador SST 17 8 304 150 3672 11.5 72
AMC Concord DL 6 20.2 6 232 90 3265 18.2 79
AMC Concord DL 18.1 6 258 120 3410 15.1 78
AMC Concord DL 23 4 151 3035 20.5 82
AMC Concord 19.4 6 232 90 3210 17.2 78
AMC Concord 24.3 4 151 90 3003 20.1 80
AMC Gremlin 18 6 232 100 2789 15 73
AMC Gremlin 19 6 232 100 2634 13 71
AMC Gremlin 20 6 232 100 2914 16 75
AMC Gremlin 21 6 199 90 2648 15 70
AMC Hornet Sportabout (Wagon) 18 6 258 110 2962 13.5 71
AMC Hornet 18 6 199 97 2774 15.5 70
AMC Hornet 18 6 232 100 2945 16 73
AMC Hornet 19 6 232 100 2901 16 74
AMC Hornet 22.5 6 232 90 3085 17.6 76
AMC Matador (Wagon) 14 8 304 150 4257 15.5 74
AMC Matador (Wagon) 15 8 304 150 3892 12.5 72
AMC Matador 14 8 304 150 3672 11.5 73
AMC Matador 15 6 258 110 3730 19 75
AMC Matador 15.5 8 304 120 3962 13.9 76
AMC Matador 16 6 258 110 3632 18 74
AMC Matador 18 6 232 100 3288 15.5 71
AMC Pacer D/L 17.5 6 258 95 3193 17.8 76
AMC Pacer 19 6 232 90 3211 17 75
AMC Rebel SST (Wagon) 8 360 175 3850 11 70
AMC Rebel SST 16 8 304 150 3433 12 70
AMC Spirit DL 27.4 4 121 80 2670 15 79
Audi 100 LS 20 4 114 91 2582 14 73
Audi 100 LS 23 4 115 95 2694 15 75
Audi 100 LS 24 4 107 90 2430 14.5 70
Audi 4000 34.3 4 97 78 2188 15.8 80
Audi 5000 20.3 5 131 103 2830 15.9 78
Audi 5000S (Diesel) 36.4 5 121 67 2950 19.9 80
Audi Fox 29 4 98 83 2219 16.5 74
BMW 2002 26 4 121 113 2234 12.5 70
BMW 320i 21.5 4 121 110 2600 12.8 77
Buick Century 350 13 8 350 175 4100 13 73
Buick Century Limited 25 6 181 110 2945 16.4 82
Buick Century Luxus (Wagon) 13 8 350 150 4699 14.5 74
Buick Century Special 20.6 6 231 105 3380 15.8 78
Buick Century 17 6 231 110 3907 21 75
Buick Century 22.4 6 231 110 3415 15.8 81
Buick Electra 225 Custom 12 8 455 225 4951 11 73
Buick Estate Wagon (Wagon) 14 8 455 225 3086 10 70
Buick Estate Wagon (Wagon) 16.9 8 350 155 4360 14.9 79
Buick Lesabre Custom 13 8 350 155 4502 13.5 72
Buick Opel Isuzu Deluxe 30 4 111 80 2155 14.8 77
Buick Regal Sport Coupe (Turbo) 17.7 6 231 165 3445 13.4 78
Buick Skyhawk 21 6 231 110 3039 15 75
Buick Skylark 320 15 8 350 165 3693 11.5 70
Buick Skylark Limited 28.4 4 151 90 2670 16 79
Buick Skylark 20.5 6 231 105 3425 16.9 77
Buick Skylark 26.6 4 151 84 2635 16.4 81
Cadillac Eldorado 23 8 350 125 3900 17.4 79
Cadillac Seville 16.5 8 350 180 4380 12.1 76
Chevroelt Chevelle Malibu 16 6 250 105 3897 18.5 75
Chevrolet Bel Air 15 8 350 145 4440 14 75
Chevrolet Camaro 27 4 151 90 2950 17.3 82
Chevrolet Caprice Classic 13 8 400 150 4464 12 73
Chevrolet Caprice Classic 17 8 305 130 3840 15.4 79
Chevrolet Caprice Classic 17.5 8 305 145 3880 12.5 77
<!DOCTYPE html>
<meta charset="utf-8">
<title>Parallel Coordinates Ordinal Axis</title>
<style>
svg {
font: 12px sans-serif;
}
.background path {
fill: none;
stroke: none;
stroke-width: 20px;
pointer-events: stroke;
}
.foreground path {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.axis .title {
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
}
.axis line,
.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis.string {
font-size: 6px;
}
.label {
-webkit-transition: fill 125ms linear;
}
.active .label:not(.inactive) {
font-weight: bold;
font-size: 11px;
}
.label.inactive {
fill: #ccc;
}
.foreground path.inactive {
stroke: #ccc;
stroke-opacity: .5;
stroke-width: 1px;
}
</style>
<body>
<script src="http://d3js.org/d3.v2.min.js"></script>
<script>
var margin = {top: 30, right: 40, bottom: 20, left: 200},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var dimensions = [
{
name: "name",
scale: d3.scale.ordinal().rangePoints([0, height]),
type: "string"
},
{
name: "economy (mpg)",
scale: d3.scale.linear().range([0, height]),
type: "number"
},
{
name: "cylinders",
scale: d3.scale.linear().range([height, 0]),
type: "number"
},
{
name: "displacement (cc)",
scale: d3.scale.linear().range([height, 0]),
type: "number"
},
{
name: "power (hp)",
scale: d3.scale.linear().range([height, 0]),
type: "number"
},
{
name: "weight (lb)",
scale: d3.scale.linear().range([height, 0]),
type: "number"
},
{
name: "0-60 mph (s)",
scale: d3.scale.linear().range([height, 0]),
type: "number"
},
{
name: "year",
scale: d3.scale.linear().range([height, 0]),
type: "number"
},
];
var x = d3.scale.ordinal()
.domain(dimensions.map(function(d) { return d.name; }))
.rangePoints([0, width]);
var line = d3.svg.line()
.defined(function(d) { return !isNaN(d[1]); });
var yAxis = d3.svg.axis()
.orient("left");
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 dimension = svg.selectAll(".dimension")
.data(dimensions)
.enter().append("g")
.attr("class", "dimension")
.attr("transform", function(d) { return "translate(" + x(d.name) + ")"; });
d3.csv("cars.small.csv", function(data) {
dimensions.forEach(function(dimension) {
dimension.scale.domain(dimension.type === "number"
? d3.extent(data, function(d) { return +d[dimension.name]; })
: data.map(function(d) { return d[dimension.name]; }).sort());
});
svg.append("g")
.attr("class", "background")
.selectAll("path")
.data(data)
.enter().append("path")
.attr("d", draw);
svg.append("g")
.attr("class", "foreground")
.selectAll("path")
.data(data)
.enter().append("path")
.attr("d", draw);
dimension.append("g")
.attr("class", "axis")
.each(function(d) { d3.select(this).call(yAxis.scale(d.scale)); })
.append("text")
.attr("class", "title")
.attr("text-anchor", "middle")
.attr("y", -9)
.text(function(d) { return d.name; });
var ordinal_labels = svg.selectAll(".axis text")
.on("mouseover", mouseover)
.on("mouseout", mouseout);
var projection = svg.selectAll(".background path,.foreground path")
.on("mouseover", mouseover)
.on("mouseout", mouseout);
function mouseover(d) {
svg.classed("active", true);
// this could be more elegant
if (typeof d === "string") {
projection.classed("inactive", function(p) { return p.name !== d; });
projection.filter(function(p) { return p.name === d; }).each(moveToFront);
ordinal_labels.classed("inactive", function(p) { return p !== d; });
ordinal_labels.filter(function(p) { return p === d; }).each(moveToFront);
} else {
projection.classed("inactive", function(p) { return p !== d; });
projection.filter(function(p) { return p === d; }).each(moveToFront);
ordinal_labels.classed("inactive", function(p) { return p !== d.name; });
ordinal_labels.filter(function(p) { return p === d.name; }).each(moveToFront);
}
}
function mouseout(d) {
svg.classed("active", false);
projection.classed("inactive", false);
ordinal_labels.classed("inactive", false);
}
function moveToFront() {
this.parentNode.appendChild(this);
}
});
function draw(d) {
return line(dimensions.map(function(dimension) {
return [x(dimension.name), dimension.scale(d[dimension.name])];
}));
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment