211 lines
6.2 KiB
HTML
211 lines
6.2 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8" />
|
|
<html>
|
|
<head>
|
|
<!-- add title -->
|
|
|
|
<!-- import required libraries here -->
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
|
<script type="text/javascript" src="../lib/d3.v5.min.js"></script>
|
|
<script type="text/javascript" src="../lib/d3-legend.min.js"></script>
|
|
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
|
|
<script src="../lib/d3-tip.min.js"></script>
|
|
|
|
<style>
|
|
/* define CSS rules here */
|
|
#tooltip {
|
|
background-color: #444;
|
|
color: white;
|
|
padding: 10px;
|
|
}
|
|
|
|
#select_board_game {
|
|
|
|
}
|
|
#gameDropdown {
|
|
position: absolute;
|
|
top: 30px;
|
|
left: 10px;
|
|
}
|
|
</style>
|
|
|
|
<title></title>
|
|
</head>
|
|
|
|
<body>
|
|
<!-- Add heading for the visualization -->
|
|
<div class="select_board_game">Select Board Game:</div>
|
|
|
|
<!-- Create dropdown element here. Options should be added after reading in game file, they should not be created here.-->
|
|
|
|
<!-- append visualization svg to this div-->
|
|
<script>
|
|
var margin = { top: 1, right: 1, bottom: 1, left: 1 };
|
|
var width = 1000 - margin.left - margin.right;
|
|
var height = 600 - margin.top - margin.bottom;
|
|
|
|
var body = d3.select("body");
|
|
var svg_choropleth = body.append("svg").attr("id", "choropleth");
|
|
var g_countries = svg_choropleth.append("g").attr("id", "countries");
|
|
// var g_legend = svg_choropleth.append("g");
|
|
var select_gameDropdown = body
|
|
.append("select")
|
|
.attr("id", "gameDropdown");
|
|
|
|
|
|
// var div_tooltip = body.append("div").attr("id", "tooltip");
|
|
|
|
// DOM OK
|
|
const tip = d3
|
|
.tip()
|
|
.attr("class", "d3-tip")
|
|
.attr("id", "tooltip")
|
|
.html((d) => d)
|
|
.direction("s")
|
|
.offset([0, 0]);
|
|
|
|
svg_choropleth.call(tip);
|
|
|
|
svg_choropleth
|
|
.attr("width", width + margin.left + margin.right)
|
|
.attr("height", height + margin.top + margin.bottom)
|
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
|
|
colorbrewer = ["#fb6a4a", "#fc9272", "#a50f15", "#de2d26"];
|
|
|
|
const projection = d3
|
|
.geoRobinson()
|
|
.scale(148)
|
|
.rotate([352, 0, 0])
|
|
.translate([width / 2, height / 2]);
|
|
const path = d3.geoPath().projection(projection);
|
|
|
|
gameData = [];
|
|
Promise.all([
|
|
d3.json("world_countries.json"),
|
|
d3.csv("ratings-by-country.csv"),
|
|
]).then(ready);
|
|
|
|
function ready([world_countries, ratings_by_country]) {
|
|
unique_games = d3.map(ratings_by_country, (d) => d.Game).keys();
|
|
unique_games.sort();
|
|
|
|
var games_dropdown = document.getElementById("gameDropdown");
|
|
for (game in unique_games) {
|
|
var option0 = document.createElement("option");
|
|
option0.value = unique_games[game];
|
|
option0.text = unique_games[game];
|
|
games_dropdown.appendChild(option0);
|
|
}
|
|
|
|
createMapAndLegend({
|
|
world: world_countries,
|
|
gameData: ratings_by_country,
|
|
selectedGame: unique_games[0],
|
|
});
|
|
|
|
$("#gameDropdown").change(function () {
|
|
return createMapAndLegend({
|
|
world: world_countries,
|
|
gameData: ratings_by_country,
|
|
selectedGame: $("#gameDropdown").val(),
|
|
});
|
|
});
|
|
}
|
|
|
|
function createMapAndLegend({ world, gameData, selectedGame }) {
|
|
console.log({ world, gameData, selectedGame });
|
|
//
|
|
data = gameData.filter((n, i) => n.Game == selectedGame);
|
|
|
|
colorScale = d3
|
|
.scaleQuantize()
|
|
.domain(d3.map(gameData, (d) => +d["Average Rating"]).keys())
|
|
.range(colorbrewer);
|
|
|
|
svg_choropleth.selectAll("*").remove();
|
|
svg_choropleth
|
|
.append("g")
|
|
.attr("id", "countries")
|
|
.selectAll("path")
|
|
.data(world.features)
|
|
.enter()
|
|
.append("path")
|
|
.attr("fill", (d) => {
|
|
country_name = data.filter(
|
|
(n, i) => n.Country == d.properties.name
|
|
);
|
|
|
|
if (country_name.length == 0) {
|
|
return "#aaa";
|
|
}
|
|
|
|
return colorScale(country_name[0]["Average Rating"]);
|
|
})
|
|
.attr("d", path)
|
|
.on("mouseover", (d, i) => {
|
|
//
|
|
country_name = data.filter(
|
|
(n, i) => n.Country == d.properties.name
|
|
);
|
|
|
|
let html = "<b>Country: </b>" + d.properties.name + "<br>";
|
|
html = html + "<b>Game: </b>" + $("#gameDropdown").val() + "<br>";
|
|
if (country_name.length == 0) {
|
|
html = html + "<b>Avg Rating: </b>" + " N/A " + "<Br>";
|
|
html = html + "<b>Number of Users: </b>" + " N/A " + "<br>";
|
|
} else {
|
|
html =
|
|
html +
|
|
"<b>Avg Rating: </b>" +
|
|
country_name[0]["Average Rating"] +
|
|
"<Br>";
|
|
html =
|
|
html +
|
|
"<b>Number of Users: </b>" +
|
|
country_name[0]["Number of Users"] +
|
|
"<br>";
|
|
}
|
|
|
|
tip.show(html);
|
|
})
|
|
.on("mouseout", (d, i) => {
|
|
tip.hide();
|
|
});
|
|
|
|
var avg_rating = [];
|
|
gameData.forEach(function(d){
|
|
for (game in d) {
|
|
if (d.Game == selectedGame) {
|
|
avg_rating.push(d['Average Rating'])
|
|
}
|
|
}
|
|
})
|
|
console.log(avg_rating)
|
|
var quantile = d3.scaleQuantile()
|
|
.domain(avg_rating.sort())
|
|
.range(colorbrewer)
|
|
|
|
|
|
var colors_for_legend = d3
|
|
.legendColor()
|
|
.labelFormat(d3.format(",.2f"))
|
|
.scale(quantile)
|
|
.shapePadding(3)
|
|
.shapeWidth(20)
|
|
.shapeHeight(20)
|
|
.labelOffset(12)
|
|
.labelOffset(12);
|
|
|
|
// add legend
|
|
svg_choropleth
|
|
.append("g").attr("id", "legend")
|
|
.attr("transform", "translate(900,80)")
|
|
.call(colors_for_legend);
|
|
}
|
|
</script>
|
|
|
|
<div id="signature">tlou31</div>
|
|
</body>
|
|
</html>
|