Skip to content

Instantly share code, notes, and snippets.

@sfsheath
Forked from mbostock/.block
Last active August 29, 2015 13:57
Show Gist options
  • Save sfsheath/9745576 to your computer and use it in GitHub Desktop.
Save sfsheath/9745576 to your computer and use it in GitHub Desktop.
Compare Information about Roman Amphitheaters

The above figure allows relationships between the "year created", "seating capacity", elevation, longitude and latitude of Roman amphitheaters to be explored. The data is incomplete, though it is being regularly expanded and improved.

Drag your mouse along the axes to define ranges of interest. Hover over a blue line to which amphitheater it represents.

The following SPARQL should be close to what is used to generate the CSV, though I don't guarantee that I've kept it up to date.

PREFIX dc: <http://purl.org/dc/terms/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX ex: <http://example.org/>
PREFIX geo: <http://geovocab.org/geometry#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?name ?year_created ?seating_capacity ?elevation ?longitude ?latitude
FROM <http://rdf.greggkellogg.net/distiller?format=rdfxml&in_fmt=jsonld&uri=http://sfsheath.github.io/roman-amphitheaters/roman-amphitheaters.geojson>
WHERE {
?name rdfs:isDefinedBy/dc:created ?year_created .
?name rdfs:isDefinedBy/dbp:seatingCapacity ?seating_capacity .
?name geo:geometry/rdf:value/rdf:first ?longitude .
?name geo:geometry/rdf:value/rdf:rest/rdf:first ?latitude .
?name geo:geometry/rdf:value/rdf:rest/rdf:rest/rdf:first ?elevation .
 }

Further acknowledgements/description:

From the original bl.ock: "This parallel coordinates visualization of cars from the ‘70s and ‘80s demonstrates one of D3 2.5.0’s new interactive features: the brush component. By clicking and dragging along any axis, you can specify a filter for that dimension. The brush component is also used in the updated scatterplot matrix example."

name year_created seating_capacity elevation longitude latitude
http://purl.org/roman-amphitheaters/id/carnuntumLargeAmphitheater 150 15000 164 1.6892619e1 4.8126824e1
http://purl.org/roman-amphitheaters/id/pozzuoliFlavianAmphitheater 70 20000 41 1.4125315e1 4.0825929e1
http://purl.org/roman-amphitheaters/id/thevesteAmphitheater 120 14200 877 8.123809e0 3.5401171e1
http://purl.org/roman-amphitheaters/id/marcianopolisAmphitheater 200 4000 120 2.7556674e1 4.3218689e1
http://purl.org/roman-amphitheaters/id/colAugustaRauricaAmphitheatre 200 6000 285 7.72061e0 4.7529294e1
http://purl.org/roman-amphitheaters/id/bordeauxAmphitheater 220 28700 17 -5.82476e-1 4.4847382e1
http://purl.org/roman-amphitheaters/id/carnuntumPetronellAmphitheater 100 12000 185 1.6850943e1 4.8110019e1
http://purl.org/roman-amphitheaters/id/italicaAmphitheater 140 25000 17 -6.046742e0 3.7443893e1
http://purl.org/roman-amphitheaters/id/pulaAmphitheater 1 26000 16 1.3850243e1 4.4873229e1
http://purl.org/roman-amphitheaters/id/ludusMagnusArena 81 500 22 1.2494913e1 4.188995e1
http://purl.org/roman-amphitheaters/id/thysdrusAmphitheater 238 35000 111 1.0706939e1 3.529639e1
http://purl.org/roman-amphitheaters/id/trierAmphitheater 100 20000 168 6.649088e0 4.9748052e1
http://purl.org/roman-amphitheaters/id/thaenaeAmphitheater 125 8700 7 1.0673126e1 3.4655481e1
http://purl.org/roman-amphitheaters/id/sabrathaAmphitheater 125 20700 11 1.249404e1 3.2803879e1
http://purl.org/roman-amphitheaters/id/paestumAmphitheater -75 4500 18 1.5006449e1 4.0422354e1
http://purl.org/roman-amphitheaters/id/empuriesAmphitheater 50 3300 27 3.117431e0 4.2130042e1
http://purl.org/roman-amphitheaters/id/castraAlbanaAmphitheater 212 20000 454 1.266501e1 4.1732637e1
http://purl.org/roman-amphitheaters/id/romeAmphitheater 80 50000 22 1.2492269e1 4.1890169e1
http://purl.org/roman-amphitheaters/id/meridaAmphitheater -8 15000 231 -6.337952e0 3.8916168e1
http://purl.org/roman-amphitheaters/id/romeAmphitheatrumCastrense 218 7000 48 1.2515144e1 4.1887715e1
http://purl.org/roman-amphitheaters/id/conimbrigaAmphitheater 50 4000 100 -8.49333e0 4.0099444e1
http://purl.org/roman-amphitheaters/id/leptisMagnaAmphitheater 56 16000 18 1.4309452e1 3.263234e1
http://purl.org/roman-amphitheaters/id/duraEuroposAmphitheater 216 1000 223 4.0728926e1 3.4749855e1
http://purl.org/roman-amphitheaters/id/thysdrusSmallAmphitheater 125 9000 116 1.0707911e1 3.5290106e1
http://purl.org/roman-amphitheaters/id/pompeiiAmphitheater -70 22000 21 1.4495262e1 4.0751213e1
http://purl.org/roman-amphitheaters/id/cagliariAmphitheater 100 10000 60 9.113227999999999e0 3.9223908e1
http://purl.org/roman-amphitheaters/id/carmonaAmphitheater -50 8000 223 -5.650907e0 3.7469674e1
http://purl.org/roman-amphitheaters/id/sbeitlaAmphitheater 160 6600 556 9.114582e0 3.5243617e1
http://purl.org/roman-amphitheaters/id/arezzoAmphitheater 80 8000 263 1.188037e1 4.3460491e1
http://purl.org/roman-amphitheaters/id/lyonAmphitheater 19 20000 206 4.830556e0 4.5770556e1
http://purl.org/roman-amphitheaters/id/uthinaAmphitheatre 120 16000 112 1.0169215e1 3.6608597e1
http://purl.org/roman-amphitheaters/id/corinthAmphitheater -44 14000 98 2.2892126e1 3.7909629e1
http://purl.org/roman-amphitheaters/id/newsteadAmphitheater 80 2000 83 -2.6919e0 5.56026e1
http://purl.org/roman-amphitheaters/id/tarragonaAmphitheater 100 15000 13 1.25878e0 4.1114522e1
http://purl.org/roman-amphitheaters/id/arlesAmphitheater 90 20000 21 4.631111e0 4.3677778e1
http://purl.org/roman-amphitheaters/id/nimesAmphitheater 90 24000 50 4.359599e0 4.3834876e1
http://purl.org/roman-amphitheaters/id/segobrigaAmphitheater 90 7500 817 -2.813944e0 3.9886018e1
http://purl.org/roman-amphitheaters/id/veronaAmphitheatre 30 30000 62 1.099435e1 4.543904e1
http://purl.org/roman-amphitheaters/id/pergamumAmphitheater 100 25000 100 2.7174177e1 3.9125751e1
http://purl.org/roman-amphitheaters/id/telesiaAmphitheatre -75 9000 68 1.4500496e1 4.1223911e1
http://purl.org/roman-amphitheaters/id/sophiaAmphitheater 284 20000 554 2.332865e1 4.2697178e1
http://purl.org/roman-amphitheaters/id/gemellaeAmphitheater 130 3000 83 5.522904e0 3.4636598e1
http://purl.org/roman-amphitheaters/id/vindonissaAmphitheater 50 11000 361 8.213604999999999e0 4.747629e1
http://purl.org/roman-amphitheaters/id/durresAmphitheatre 100 20000 15 1.9445131e1 4.1312241e1
http://purl.org/roman-amphitheaters/id/carthageAmphitheater 100 30000 14 1.0314924e1 3.6856078e1
http://purl.org/roman-amphitheaters/id/sutriumAmphitheatre -50 8500 271 1.22293009e1 4.22393124e1
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
font: 10px sans-serif;
}
.background path {
fill: none;
stroke: #ccc;
stroke-opacity: .4;
shape-rendering: crispEdges;
}
.foreground path {
fill: none;
stroke: steelblue;
stroke-width: 2;
stroke-opacity: .7;
}
.brush .extent {
fill-opacity: .3;
stroke: #fff;
shape-rendering: crispEdges;
}
.axis line,
.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text {
text-shadow: 0 1px 0 #fff;
cursor: move;
}
.tooltip {
background-color: rgba(220,220,220,0.5);
color: #333;
margin: 10px;
height: 25px;
padding-right: 10px;
padding-left: 10px;
padding-top: 10px;
-webkit-border-radius:10px;
-moz-border-radius:10px;
border-radius:10px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip")
.attr("class","tooltip");
var m = [30, 10, 10, 10],
w = 960 - m[1] - m[3],
h = 500 - m[0] - m[2];
var x = d3.scale.ordinal().rangePoints([0, w], 1),
y = {},
dragging = {};
var line = d3.svg.line(),
axis = d3.svg.axis().orient("left"),
background,
foreground;
var svg = d3.select("body").append("svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.csv("amphitheaters.csv", function(error, cars) {
// Extract the list of dimensions and create a scale for each.
x.domain(dimensions = d3.keys(cars[0]).filter(function(d) {
return d != "name" && (y[d] = d3.scale.linear()
.domain(d3.extent(cars, function(p) { return +p[d]; }))
.range([h, 0]));
}));
// Add grey background lines for context.
background = svg.append("g")
.attr("class", "background")
.selectAll("path")
.data(cars)
.enter().append("path")
.attr("d", path);
// Add blue foreground lines for focus.
foreground = svg.append("g")
.attr("class", "foreground")
.selectAll("path")
.data(cars)
.enter().append("path")
.attr("d", path)
.on("mouseover", function(n){
d3.select(this).transition().duration(100)
.style({'stroke' : '#F00'})
.style({'stroke-width': '4'});
tooltip.text(n.name);
return tooltip.style("visibility", "visible");
})
.on("mousemove", function(){return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
.on("mouseout", function(d){
d3.select(this).transition().duration(100)
.style({'stroke': 'steelblue' })
.style({'stroke-width' : '2'});
return tooltip.style("visibility", "hidden");
});
// Add a group element for each dimension.
var g = svg.selectAll(".dimension")
.data(dimensions)
.enter().append("g")
.attr("class", "dimension")
.attr("transform", function(d) { return "translate(" + x(d) + ")"; })
.call(d3.behavior.drag()
.on("dragstart", function(d) {
dragging[d] = this.__origin__ = x(d);
background.attr("visibility", "hidden");
})
.on("drag", function(d) {
dragging[d] = Math.min(w, Math.max(0, this.__origin__ += d3.event.dx));
foreground.attr("d", path);
dimensions.sort(function(a, b) { return position(a) - position(b); });
x.domain(dimensions);
g.attr("transform", function(d) { return "translate(" + position(d) + ")"; })
})
.on("dragend", function(d) {
delete this.__origin__;
delete dragging[d];
transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")");
transition(foreground)
.attr("d", path);
background
.attr("d", path)
.transition()
.delay(500)
.duration(0)
.attr("visibility", null);
}));
// Add an axis and title.
g.append("g")
.attr("class", "axis")
.each(function(d) { d3.select(this).call(axis.scale(y[d])); })
.append("text")
.attr("text-anchor", "middle")
.attr("y", -9)
.text(String);
// Add and store a brush for each axis.
g.append("g")
.attr("class", "brush")
.each(function(d) { d3.select(this).call(y[d].brush = d3.svg.brush().y(y[d]).on("brushstart", brushstart).on("brush", brush)); })
.selectAll("rect")
.attr("x", -8)
.attr("width", 16);
});
function position(d) {
var v = dragging[d];
return v == null ? x(d) : v;
}
function transition(g) {
return g.transition().duration(500);
}
// Returns the path for a given data point.
function path(d) {
return line(dimensions.map(function(p) { return [position(p), y[p](d[p])]; }));
}
// When brushing, don’t trigger axis dragging.
function brushstart() {
d3.event.sourceEvent.stopPropagation();
}
// Handles a brush event, toggling the display of foreground lines.
function brush() {
var actives = dimensions.filter(function(p) { return !y[p].brush.empty(); }),
extents = actives.map(function(p) { return y[p].brush.extent(); });
foreground.style("display", function(d) {
return actives.every(function(p, i) {
return extents[i][0] <= d[p] && d[p] <= extents[i][1];
}) ? null : "none";
});
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment