Based on following data and viz: https://github.com/conrad-mac/d3/tree/master/cricket-grounds
TO DO: Select/search by country
forked from tomshanley's block: Cricket grounds
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Catamaran" rel="stylesheet">
<style>
body {
font-family: 'Catamaran', sans-serif;
margin: 15px;
top: 15px;
right: 15px;
bottom: 15px;
left: 15px;
}
ellipse {
stroke: black;
fill: darkolivegreen;
}
line {
stroke: darkgray;
}
.pitch {
fill: beige;
}
.default-ground {
fill-opacity: 0.1;
stroke-opacity: 0.1;
}
.highlighted-ground {
fill-opacity: 1;
stroke-opacity: 1;
}
.muted-ground {
fill-opacity: 0;
stroke-opacity: 0.1;
}
</style>
</head>
<body>
<h1>Cricket grounds of the world</h1>
<p><i>The following visualisation is based on the work and data collected by <a href="https://github.com/conrad-mac/d3/tree/master/cricket-grounds">Conrad MacCormick</a></i>.
<div id="chart-options">
<p>Cricket ground:
<select id="select-cricket-ground">
</select>
<p>Highlight:
<select id="select-highlights">
<option value="None"></option>
<option value="Sher-e-Bangla">Longest</option>
<option value="University Oval">Shortest</option>
<option value="MCG">Widest</option>
<option value="Eden Park">Narrowest</option>
<option value="Sher-e-Bangla">Largest area</option>
<option value="Eden Park">Smallest area</option>
</select>
</div>
<div id="chart"></div>
<script>
var groundData;
const chartWidth = 300;
var chartHeight;
var xAxis, yAxis;
var ryScale = d3.scaleLinear();
var rxScale = d3.scaleLinear().range([0, chartWidth / 2]);
const margin = { "top": 50, "bottom": 10, "left": 250, "right": 10, };
const pitchLength = 20.12; //m (22 yards) long
const pitchWidth = 3.05; //m
const barExtent = 3;
let selectGround = d3.select("#select-cricket-ground");
let selectHighlights = d3.select("#select-highlights");
d3.csv("data.csv", convertTextToNumbers, function (error, data) {
groundData = data;
let cricketGroundNames = [];
data.forEach(function (d) { cricketGroundNames.push(d.ground); });
cricketGroundNames.sort();
selectGround.selectAll("option")
.data(cricketGroundNames)
.enter()
.append("option")
.attr("value", function (d) { return d; })
.text(function (d) { return d; });
selectGround.on("change", function (d) {
var selectedGround = d3.select(this).property("value");
selectHighlights.property("value", "None");
highlightGround(selectedGround);
});
selectHighlights.on("change", function (d) {
var selectedGround = d3.select(this).property("value");
if (selectedGround != "None") {
selectGround.property("value", selectedGround);
highlightGround(selectedGround);
};
});
const maxRX = d3.max(data, function (d) { return d.rx; });
const maxRY = d3.max(data, function (d) { return d.ry; });
const ratio = maxRX / maxRY;
chartHeight = chartWidth / ratio;
rxScale.domain([0, maxRX]);
ryScale.domain([0, maxRY])
.range([0, chartHeight / 2]);
let svg = d3.select("#chart")
.append("svg")
.attr("width", chartWidth + margin.left + margin.right)
.attr("height", chartHeight + margin.top + margin.bottom);
let g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
let cricketGrounds = g.selectAll(".cricket-ground")
.data(data)
.enter()
.append("g")
.attr("class", "cricket-ground")
.attr("transform", "translate(" + chartWidth / 2 + "," + chartHeight / 2 + ")");
cricketGrounds.append("ellipse")
.attr("class", "default-ground")
.attr("rx", function (d) { return rxScale(d.rx); })
.attr("ry", function (d) { return ryScale(d.ry); });
g.append("g")
.attr("transform", "translate(" + chartWidth / 2 + "," + chartHeight / 2 + ")")
.append("ellipse")
.attr("id", "highlight-ground")
.attr("rx", rxScale(maxRX))
.attr("ry", ryScale(maxRY))
.style("opacity", 0);
g.append("g").append("rect")
.attr("x", (chartWidth / 2) - ((rxScale(pitchWidth)) / 2))
.attr("y", (chartHeight / 2) - ((ryScale(pitchLength)) / 2))
.attr("width", rxScale(pitchWidth))
.attr("height", ryScale(pitchLength))
.attr("class", "pitch")
xAxis = svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + margin.left + "," + (margin.top / 2) + ")")
xAxis.append("line")
.attr("id", "x-end-1")
.attr("x1", 0)
.attr("x2", 0)
.attr("y1", -barExtent)
.attr("y2", barExtent)
xAxis.append("line")
.attr("id", "x-end-2")
.attr("y1", -barExtent)
.attr("y2", barExtent)
.attr("x1", chartWidth)
.attr("x2", chartWidth)
xAxis.append("line")
.attr("id", "x-axis-line")
.attr("x1", 0)
.attr("x2", chartWidth)
.attr("y1", 0)
.attr("y2", 0);
xAxis.append("text")
.attr("class", "x-axis-label")
.text("Max width: " + d3.max(data, function (d) { return d.width; }) + "m")
.attr("x", chartWidth / 2)
.attr("y", -3)
.style("text-anchor", "middle")
yAxis = svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + (margin.left - 20) + "," + (margin.top) + ")")
yAxis.append("line")
.attr("id", "y-end-1")
.attr("x1", -barExtent)
.attr("x2", barExtent)
.attr("y1", 0)
.attr("y2", 0)
yAxis.append("line")
.attr("id", "y-end-2")
.attr("x1", -barExtent)
.attr("x2", barExtent)
.attr("y1", chartHeight)
.attr("y2", chartHeight)
yAxis.append("line")
.attr("id", "y-axis-line")
.attr("x1", 0)
.attr("x2", 0)
.attr("y1", 0)
.attr("y2", chartHeight);
yAxis.append("text")
.attr("class", "y-axis-label-a")
.text("Max height:")
.attr("x", -3)
.attr("y", chartHeight / 2 - 8)
.style("text-anchor", "end")
yAxis.append("text")
.attr("class", "y-axis-label-b")
.text(d3.max(data, function (d) { return d.height; }) + "m")
.attr("x", -3)
.attr("y", chartHeight / 2 + 8)
.style("text-anchor", "end")
});
function highlightGround(selectedGround) {
d3.selectAll(".default-ground")
.attr("class", "muted-ground");
/*d3.selectAll("ellipse")
.attr("class", function (d) {
return d.ground == selectedGround
? "highlighted-ground"
: "muted-ground";
});*/
let selectedGroundObject = searchGround(groundData, selectedGround);
let t = d3.transition()
.duration(500)
.ease(d3.easeLinear);
d3.select("#highlight-ground")
.transition(t)
.style("opacity", 0.9)
.attr("rx", rxScale(selectedGroundObject.rx))
.attr("ry", ryScale(selectedGroundObject.ry));
xAxis.select(".x-axis-label")
.text(selectedGround + "'s width: " + selectedGroundObject.width + "m");
yAxis.select(".y-axis-label-a")
.text(selectedGround + "'s length:");
yAxis.select(".y-axis-label-b")
.text(selectedGroundObject.height + "m");
let yTop = (chartHeight - ryScale(selectedGroundObject.height))/2;
let yBottom = ryScale(selectedGroundObject.height) + yTop;
yAxis.select("#y-axis-line")
.transition(t)
.attr("y1", yTop)
.attr("y2", yBottom);
yAxis.select("#y-end-1")
.transition(t)
.attr("y1", yTop)
.attr("y2", yTop);
yAxis.select("#y-end-2")
.transition(t)
.attr("y1", yBottom)
.attr("y2", yBottom);
let xLeft = ((chartWidth - rxScale(selectedGroundObject.width))/2);
let xRight = rxScale(selectedGroundObject.width) + xLeft;
xAxis.select("#x-axis-line")
.transition(t)
.attr("x1", xLeft)
.attr("x2", xRight);
xAxis.select("#x-end-1")
.transition(t)
.attr("x1", xLeft)
.attr("x2", xLeft);
xAxis.select("#x-end-2")
.transition(t)
.attr("x1", xRight)
.attr("x2", xRight);
};
function searchGround(data, ground) {
for (var i = 0; i < data.length; i++) {
if (data[i].ground === ground) {
return data[i];
};
};
};
function convertTextToNumbers(d) {
d.height = +d.height;
d.width = +d.width;
d.ry = d.height / 2;
d.rx = d.width / 2;
return d;
};
</script>
</body>
https://d3js.org/d3.v4.min.js