Files
tunmnlu/task_2/hw2_skeleton/Q5/submit1/Q5.html
louiscklaw 9035c1312b update,
2025-02-01 02:09:32 +08:00

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>