Created
December 4, 2019 21:19
-
-
Save oikonang/9ae1ba78e49da0445fd57ce1cf55dc1c to your computer and use it in GitHub Desktop.
Greece D3js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
@import url(style.css); | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="//d3js.org/queue.v1.min.js"></script> | |
<body> | |
<!-- Table to hold the data table, map and legend --> | |
<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> | |
<td><div id="legend_container"></div></td> | |
</tr> | |
</table> | |
<script> | |
var mw = 500; // map container width | |
var mh = 600; // map container height | |
var main_chart_svg = d3.select("#map_container") | |
.append("svg") | |
.attr({ | |
"width":mw, | |
"height":mh, | |
}); | |
var legend_svg = d3.select("#legend_container") | |
.append("svg") | |
.attr({ | |
"width":200, | |
"height":600, | |
}); | |
var hue = "g"; /* b=blue, g=green, r=red colours - from ColorBrewer */ | |
/* break the data values into 9 ranges of €100 each */ | |
/* max and min values already known so 400-1300 works */ | |
var quantize = d3.scale.quantize() | |
.domain([400, 1300]) | |
.range(d3.range(9).map(function(i) { return hue + i + "-9"; })); | |
/* declare locale so we can format values with euro symbol */ | |
var ie = d3.locale({ | |
"decimal": ".", | |
"thousands": ",", | |
"grouping": [3], | |
"currency": ["€", ""], | |
"dateTime": "%a %b %e %X %Y", | |
"date": "%d/%m/%Y", | |
"time": "%H:%M:%S", | |
"periods": ["AM", "PM"], | |
"days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], | |
"shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], | |
"months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], | |
"shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] | |
}); | |
var rateById = d3.map(); | |
var lastActive = ""; | |
var ireland; | |
var data; | |
var defaultScale = 0.6; /* default scale of map - fits nicely on standard screen */ | |
var scale = 3; /* maximum size to zoom county */ | |
var format = ie.numberFormat("$, #,##0d"); | |
/* Thanks to http://stackoverflow.com/users/3128209/ameliabr for tips on creating a quantized legend */ | |
var legend = legend_svg.selectAll('g.legendEntry') | |
.data(quantize.range()) | |
.enter() | |
.append('g').attr('class', 'legendEntry'); | |
legend | |
.append('rect') | |
.attr("x", 20) | |
.attr("y", function(d, i) { | |
return i * 25 + 20; | |
}) | |
.attr("width", 15) | |
.attr("height", 15) | |
.attr("class", function(d){ return d;}) | |
.style("stroke", "black") | |
.style("stroke-width", 1) | |
.on("click", function(d) | |
{ | |
if (lastActive == "") { | |
resetAll(); | |
d3.select(ireland).selectAll("." + d).attr("class", "highlight"); /* Highlight all counties in range selected */ | |
} | |
}); | |
legend | |
.append('text') | |
.attr("x", 40) //leave 5 pixel space after the <rect> | |
.attr("y", function(d, i) { | |
return i * 25 + 20; | |
}) | |
.attr("dy", "0.8em") //place text one line *below* the x,y point | |
.text(function(d,i) { | |
var extent = quantize.invertExtent(d); | |
//extent will be a two-element array, format it however you want: | |
return format(extent[0]) + " - " + format(+extent[1]) | |
}) | |
.style("font-family", "sans-serif") | |
.style("font-size", "12px"); | |
/* Data has key "county" and value "rental" - i.e. average rental price per county */ | |
queue() | |
.defer(d3.csv, "rentals-2015-bycounty.csv", data) | |
.await(ready); | |
function ready(error, data) { | |
if (error) throw error; | |
d3.map(data, function(d) {rateById.set(d.county, +d.rental)}); /* create the data map */ | |
d3.xml("greece.svg", "image/svg+xml", function(error, xml) { /* embed the SVG map */ | |
if (error) throw error; | |
var countyTable = tabulate(data, ["county", "rental"]); /* render the data table */ | |
var svgMap = xml.getElementsByTagName("g")[0]; /* set svgMap to root g */ | |
ireland = main_chart_svg.node().appendChild(svgMap); /* island of Ireland map */ | |
d3.select(ireland).selectAll("#NI") /* Group Northern Ireland together */ | |
.attr("class", "region NI"); | |
d3.select(ireland).selectAll("#republic") /* Group Republic of Ireland together */ | |
.attr("class", "region republic"); | |
d3.select(ireland).selectAll("#republic").selectAll("path") /* Map Republic counties to rental data */ | |
.attr("class", function(d) { | |
return quantize(rateById.get(this.id)); | |
}) | |
.append("title").text(function(d) { /* add title = name of each county and average rental */ | |
return this.parentNode.id + ", " + format(rateById.get(this.parentNode.id)) | |
}); | |
d3.select(ireland).selectAll("#republic").selectAll("path") | |
.on("mouseover", function(d) | |
{ | |
if (d3.select(this).classed("active")) return; /* no need to change class when county is already selected */ | |
d3.select(this).attr("class", "hover"); | |
}) | |
.on("mouseout", function(d) | |
{ | |
if (d3.select(this).classed("active")) return; | |
d3.select(this).attr("class", function(d) { /* reset county color to quantize range */ | |
return quantize(rateById.get(this.id)) | |
}); | |
}) | |
.on("click", function (d) { zoomed(d3.select(this)); }); | |
/* Let's add an id to each group that wraps a path */ | |
d3.select(ireland).selectAll("#republic").selectAll("path") | |
.each(function(d) { | |
d3.select(this.parentNode).attr("id", this.id); | |
}); | |
/* Now add a text box to the group with content equal to the id of the group */ | |
d3.select(ireland).selectAll("#republic").selectAll("g") | |
.append("svg:text") | |
.text(function(d){ | |
return this.parentNode.id; | |
}) | |
.attr("x", function(d){ | |
console.log(d3.select(this.parentNode).select("path").attr("d")); | |
//return 600; | |
//d3.select(ireland).select("path") | |
return getBoundingBox(d3.select(this.parentNode).select("path"))[4]; | |
}) | |
.attr("y", function(d){ | |
return getBoundingBox(d3.select(this.parentNode).select("path"))[5]; | |
}) | |
// .attr("text-anchor","middle") | |
// .attr("font-family", "sans-serif") | |
// .attr("stroke-width", 0.5) | |
.classed("text", true) | |
// .attr("fill", "#333") | |
// .attr('font-size','10pt') | |
; | |
}); | |
} | |
/* Thanks to http://bl.ocks.org/phil-pedruco/7557092 for the table code */ | |
/* and style - and what a coincidence he also used a map of Ireland! */ | |
function tabulate(data, columns) { | |
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") | |
.on("click", function (d) { tableRowClicked(d)}); | |
// 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") | |
// .attr("style", "font-family: Courier") // sets the font style | |
.html(function(d) { | |
if (d.column == "rental") return format(d.value); else return d.value; | |
}); | |
return table; | |
} | |
function zoomed(d) { | |
/* Thanks to http://complextosimple.blogspot.ie/2012/10/zoom-and-center-with-d3.html */ | |
/* for a simple explanation of transform scale and translation */ | |
/* This function centers the county's bounding box in the map container */ | |
/* The scale is set to the minimum value that enables the county to fit in the */ | |
/* container, horizontally or vertically, up to a maximum value of 3. */ | |
/* If the full width of container is not required, the county is horizontally centred */ | |
/* Likewise, if the full height of the container is not required, the county is */ | |
/* vertically centred. */ | |
var xy = getBoundingBox(d); /* get top left co-ordinates and width and height */ | |
if (d.classed("active")) { /* if county is active reset map scale and county colour */ | |
d.attr("class", function(d) { | |
return quantize(rateById.get(this.id)) | |
}); | |
main_chart_svg.selectAll("#viewport") | |
.transition().duration(750).attr("transform", "scale(" + defaultScale + ")"); | |
lastActive = ""; | |
} else { /* zoom into new county */ | |
resetAll(); /* reset county colors */ | |
/* scale is the max number of times bounding box will fit into container, capped at 3 times */ | |
scale = Math.min(mw/xy[1], mh/xy[3], 3); | |
/* tx and ty are the translations of the x and y co-ordinates */ | |
/* the translation centers the bounding box in the container */ | |
var tx = -xy[0] + (mw - xy[1]*scale)/(2*scale); | |
var ty = -xy[2] + (mh - xy[3]*scale)/(2*scale); | |
main_chart_svg.selectAll("#viewport") | |
.transition().duration(750).attr("transform", "scale(" + scale + ")translate("+ tx +"," + ty + ")"); | |
d.attr("class", "active"); | |
lastActive = d.attr("id"); | |
} | |
} | |
function reset(selection) { | |
/* resets the color of a single county */ | |
if (selection != "") | |
d3.select(ireland).select("#" + selection).attr("class", function(d) { | |
return quantize(rateById.get(this.id)) | |
}); | |
} | |
function resetAll() { | |
/* resets the color of all counties */ | |
d3.select(ireland).selectAll("#republic").selectAll("path") | |
.attr("class", function(d) { | |
return quantize(rateById.get(this.id)) | |
}); | |
} | |
function tableRowClicked(x) { | |
/* resets colors and zooms into new county */ | |
resetAll(); | |
lastActive = x.county; | |
zoomed(d3.select(ireland).selectAll("#" + x.county).select("path")); | |
} | |
function getBoundingBox(selection) { | |
/* get x,y co-ordinates of top-left of bounding box and width and height */ | |
var element = selection.node(), | |
bbox = element.getBBox(); | |
cx = bbox.x + bbox.width/2; | |
cy = bbox.y + bbox.height/2; | |
return [bbox.x, bbox.width, bbox.y, bbox.height, cx, cy]; | |
} | |
d3.select(self.frameElement).style("height", "650px"); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type | bedrooms | address | rental | county | |
---|---|---|---|---|---|
All property types | All bedrooms | Carlow | 633.84 | Carlow | |
All property types | All bedrooms | Cavan | 453.01 | Cavan | |
All property types | All bedrooms | Clare | 524.19 | Clare | |
All property types | All bedrooms | Cork | 806.69 | Cork | |
All property types | All bedrooms | Donegal | 452.97 | Donegal | |
All property types | All bedrooms | Dublin | 1207.37 | Dublin | |
All property types | All bedrooms | Galway | 829.52 | Galway | |
All property types | All bedrooms | Kerry | 553.56 | Kerry | |
All property types | All bedrooms | Kildare | 887.66 | Kildare | |
All property types | All bedrooms | Kilkenny | 644.59 | Kilkenny | |
All property types | All bedrooms | Laois | 567.85 | Laois | |
All property types | All bedrooms | Leitrim | 414.23 | Leitrim | |
All property types | All bedrooms | Limerick | 643.55 | Limerick | |
All property types | All bedrooms | Longford | 422.36 | Longford | |
All property types | All bedrooms | Louth | 672.48 | Louth | |
All property types | All bedrooms | Mayo | 514.76 | Mayo | |
All property types | All bedrooms | Meath | 765.04 | Meath | |
All property types | All bedrooms | Monaghan | 499.16 | Monaghan | |
All property types | All bedrooms | Offaly | 545.5 | Offaly | |
All property types | All bedrooms | Roscommon | 462.79 | Roscommon | |
All property types | All bedrooms | Sligo | 600.72 | Sligo | |
All property types | All bedrooms | Tipperary | 539.24 | Tipperary | |
All property types | All bedrooms | Waterford | 554.23 | Waterford | |
All property types | All bedrooms | Westmeath | 568.02 | Westmeath | |
All property types | All bedrooms | Wexford | 560.88 | Wexford | |
All property types | All bedrooms | Wicklow | 911.88 | Wicklow |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* style.css */ | |
.region.republic { | |
fill: #fee391; | |
stroke: #333; | |
stroke-width: 1px; | |
} | |
.active | |
{fill: #f29929; | |
} | |
.hover | |
{fill: #fee391; | |
} | |
.highlight | |
{fill: #fec44f; | |
} | |
.region.NI { | |
fill: #aaa; | |
stroke: #aaa; | |
} | |
rect { | |
fill: none; | |
pointer-events: all; | |
} | |
/* Colors taken from colorbrewer2.org - blue */ | |
.b0-9 { fill:rgb(247,251,255); } | |
.b1-9 { fill:rgb(222,235,247); } | |
.b2-9 { fill:rgb(198,219,239); } | |
.b3-9 { fill:rgb(158,202,225); } | |
.b4-9 { fill:rgb(107,174,214); } | |
.b5-9 { fill:rgb(66,146,198); } | |
.b6-9 { fill:rgb(33,113,181); } | |
.b7-9 { fill:rgb(8,81,156); } | |
.b8-9 { fill:rgb(8,48,107); } | |
/* Colors taken from colorbrewer2.org - red */ | |
.r0-9 { fill:rgb(255,245,240); } | |
.r1-9 { fill:rgb(254,224,210); } | |
.r2-9 { fill:rgb(252,187,161); } | |
.r3-9 { fill:rgb(252,146,114); } | |
.r4-9 { fill:rgb(251,106,74); } | |
.r5-9 { fill:rgb(239,59,44); } | |
.r6-9 { fill:rgb(203,24,29); } | |
.r7-9 { fill:rgb(165,15,21); } | |
.r8-9 { fill:rgb(103,0,13); } | |
/* Colors taken from colorbrewer2.org - green */ | |
.g0-9 { fill:rgb(247,252,245); } | |
.g1-9 { fill:rgb(229,245,224); } | |
.g2-9 { fill:rgb(199,233,192); } | |
.g3-9 { fill:rgb(161,217,155); } | |
.g4-9 { fill:rgb(116,196,118); } | |
.g5-9 { fill:rgb(65,171,93); } | |
.g6-9 { fill:rgb(35,139,69); } | |
.g7-9 { fill:rgb(0,109,44); } | |
.g8-9 { fill:rgb(0,68,27); } | |
.text { stroke:#333; | |
text-anchor: middle; | |
font-family: "sans-serif"; | |
stroke-width: 0.5; | |
fill: #333; | |
font-size: 10pt; | |
} | |
.csvTable table { | |
border-collapse: collapse; | |
text-align: left; | |
width: 100%; | |
} | |
.csvTable { | |
font: normal 12px/120% Arial, Helvetica, sans-serif; | |
background: #fff; | |
overflow: hidden; | |
border: 1px solid #063; | |
-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: #006633; /* #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: #063; | |
color: white; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment