Skip to content

Instantly share code, notes, and snippets.

@majomo
Forked from phil-pedruco/index.html
Created March 21, 2016 16:25
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 majomo/38bc0048e9226c8bcbb3 to your computer and use it in GitHub Desktop.
Save majomo/38bc0048e9226c8bcbb3 to your computer and use it in GitHub Desktop.
Click to zoom with table and map in D3

An example of a click and zoom map using table cells as well as the map for Ireland. This is in response to this Stack Overflow question and the code at this page.

The visualisation also has the referendum results displ;ayed as a choropleth map, in green of course. The colours are from ColorBrewer.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
@import url(mapStyle.css);
</style>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<body>
<!-- Table to hold the Divs -->
<table border="0" cellpadding="10" style="overflow-y: scroll;">
<tr>
<td><div id="table_container" class="csvTable"></div></td>
<td><div id="map_container"></div></td>
</tr>
</table>
<script>
// Based on http://public.johnnyotoole.fastmail.fm/county_map.html
// Based on http://bl.ocks.org/mbostock/4699541
//Width and height
var w = 600;
var h = 600;
var active;
var jsonOutside;
//Define map projection NB change to mercator and changed zoom etc
var projection = d3.geo.mercator()
.center([0, 52.4])
.rotate([8.2, 0])
.scale(3500)
.translate([w / 2, h / 2]);
//Define path generator
var path = d3.geo.path()
.projection(projection);
//Create SVG element
var svg = d3.select("#map_container")
.append("svg")
.attr("width", w)
.attr("height", h);
// from colorbrewer (http://colorbrewer2.org/)
var colours = ["#BAE4B3", "#74C476", "#31A354", "#006D2C"];
// setup colours for choropleth
var colScale = d3.scale.ordinal()
.range(colours);
svg.append("rect")
.attr("width", w)
.attr("height", h)
.on("click", reset);
var g = svg.append("g");
//Load in CSV data
d3.csv("referendum_results.csv", function (data) {
//Load in GeoJSON data
d3.json("ireland_counties.json", function (json) {
// join csv data with json data and create
json.features.forEach(function (d,i) {
data.forEach(function (e,j) {
if (d.properties.name === e.County) {
d.properties.value = +e.Result;
};
})
})
jsonOutside = json; // pass json to a global so tableRowClicked has access
var columns = ["County", "Result"];
var table = d3.select("#table_container").append("table"),
thead = table.append("thead"),
tbody = table.append("tbody");
// append the header row
thead.append("tr")
.selectAll("th")
.data(columns)
.enter()
.append("th")
.text(function (column) { return column; });
// create a row for each object in the data
var rows = tbody.selectAll("tr")
.data(data)
.enter()
.append("tr");
// create a cell in each row for each column
var cells = rows.selectAll("td")
.data(function (row) {
return columns.map(function (column) {
return { column: column, value: row[column] };
});
})
.enter()
.append("td")
.text(function (d) { return d.value; }
)
.on("click", function (d) { tableRowClicked(d); }); // added on click eventto td element NB you need to click on the cell with the conuty name
// add extents (max and min) from data results for choropleth
colScale.domain(d3.extent(data, function (d) { return d.Result; } ));
//Bind data and create one path per GeoJSON feature
g.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path)
.attr("class", "feature")
.attr("id", function (d) { return d.properties.name; }) // added id so click could work on id which is common between the json and csv data
.on("click", function (d) { click(d); })
.style("stroke", "white")
.style("fill", function (d,i) { return colScale(d.properties.value); }); // fill based on colour scale
g.append("path")
.data(json.features)
.enter()
.append("path")
.attr("class", "mesh")
.attr("d", path);
});
});
function click(d) {
if (active === d) return reset();
g.selectAll(".active").classed("active", false);
d3.select("#"+d.properties.name).classed("active", active = d); // changed selection to id
var b = path.bounds(d);
g.transition().duration(750).attr("transform",
"translate(" + projection.translate() + ")"
+ "scale(" + .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h) + ")"
+ "translate(" + -(b[1][0] + b[0][0]) / 2 + "," + -(b[1][1] + b[0][1]) / 2 + ")");
}
function reset() {
g.selectAll(".active").classed("active", active = false);
g.transition().duration(750).attr("transform", "");
}
function tableRowClicked(x) {
jsonOutside.features.forEach(function (d) { // loop through json data to match td entry
if (x.value === d.properties.name) {
var county = d;
click(d); // pass json element that matches td data to click
};
})
}
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
rect {
fill: none;
pointer-events: all;
}
.feature {
fill: #ccc;
cursor: pointer;
}
.feature.active {
fill: orange;
}
.mesh {
fill: none;
stroke: #fff;
stroke-width: .5px;
stroke-linejoin: round;
}
.csvTable table {
border-collapse: collapse;
text-align: left;
width: 100%;
}
.csvTable {
font: normal 12px/150% Arial, Helvetica, sans-serif;
background: #fff;
overflow: hidden;
border: 1px solid #069;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.csvTable table td, .csvTable table th {
padding: 3px 10px;
}
.csvTable table thead th {
background: 0;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699',endColorstr='#00557F');
background-color: #006D2C;
color: #FFF;
font-size: 15px;
font-weight: 700;
border-left: 1px solid #0070A8;
}
.csvTable table thead th:first-child {
border: none;
}
.csvTable table tbody td {
color: #00496B;
border-left: 1px solid #E1EEF4;
font-size: 12px;
border-bottom: 1px solid #E1EEF4;
font-weight: 400;
}
.csvTable table tbody td:first-child {
border-left: none;
}
.csvTable table tbody tr:last-child td {
border-bottom: none;
}
.csvTable tr:hover td {
background-color: #069;
color: white;
}
County Result
Carlow 45.2
Cavan 43.7
Clare 50.2
Cork 54
Donegal 42
Dublin 39
Galway 61
Kerry 35
Kildare 49.2
Kilkenny 40.2
Laois 43.9
Leitrim 55.9
Limerick 50.1
Longford 66.1
Louth 61.2
Mayo 48.2
Meath 41.2
Monaghan 57.5
Offaly 49.2
Roscommon 56.2
Sligo 59.2
Tipperary 43.2
Waterford 49.2
Westmeath 48.2
Wexford 52.4
Wicklow 53.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment