Published
Edited
Dec 11, 2021
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof competitiveSelection = Inputs.select(["All", "Top 5", "Top 10", "Top 20"], {label: "Opponent Competitiveness: "})
Insert cell
viewof playerSearch = Inputs.search(GOATPlayers, {label: html `<b style="color:yellow; text-shadow: #000 0px 0px 1.5px; font-size:20px">Player 1</b>`, columns: ["name"], query: "Roger Federer"})
Insert cell
viewof playerSearch2 = Inputs.search(GOATPlayers, {label: html `<b style="color:rgb(193, 148, 255); text-shadow: #000 0px 0px 1.5px; font-size:20px">Player 2</b>`, columns: ["name"], query: "Rafael Nadal"})
Insert cell
viewof rows = Inputs.table(playerSearch, {label: "Players", rows: 4, multiple: false, width: 400, id: "search1", value: [defaultData1]})
Insert cell
viewof rows2 = Inputs.table(playerSearch2, {label: "Players", rows: 4, multiple: false, width: 400, value: [defaultData2]})
Insert cell
defaultData1 = GOATPlayers.filter(function(d){ return d.name == "Roger Federer" })
Insert cell
defaultData2 = GOATPlayers.filter(function(d){ return d.name == "Rafael Nadal" })
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
GOATPlayers = FileAttachment("GOATList.csv").csv()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
leg = require("d3-svg-legend")
Insert cell
d3Chrome = require("d3-scale-chromatic")
Insert cell
map_json = FileAttachment("map.json").json()
Insert cell
upsets = FileAttachment("upsets_scored_w_total.csv").csv()
Insert cell
upsets_collapsed = FileAttachment("upsets_collapsed.csv").csv()
Insert cell
clayVgrass = FileAttachment("clayVgrass.csv").csv()
Insert cell
Insert cell
aces = FileAttachment("aceATPdata.csv").csv()
Insert cell
hardVgrass = FileAttachment("hardVgrass.csv").csv()
Insert cell
clay_upsets = FileAttachment("top100upsets.csv").csv()
Insert cell
hard_upsets = FileAttachment("top100upsetshard.csv").csv()
Insert cell
grass_upsets = FileAttachment("top100upsetsgrass.csv").csv()
Insert cell
fave_surfaces = FileAttachment("fave_surfaces.csv").csv()
Insert cell
Insert cell
titles = FileAttachment("alltitlesbycountry.csv").csv()
Insert cell
gsCountryTitles = FileAttachment("grandslamsbycountry.csv").csv()
Insert cell
Insert cell
selected_countryA = ({id: "ESP", country: "Spain"})
Insert cell
viewof r = Inputs.radio(["Grand Slams", "All Professional Tournaments"], {label: "Tournament Level", value: "Grand Slams"})
Insert cell
function updateTree(){
// var gs = document.getElementById("level-radio").firstChild.nextSibling.firstChild.nextSibling.nextSibling.firstChild.nextSibling.firstChild.checked;
var gs = 0;
console.log("in update tree");
if (radios == "Grand Slams") {
gs = 1;
}
if (gs) {d3.select("#titles-won-title").text("Grand Slam Titles Won By Male Players from " + selected_country.country); } else {
console.log(d3.select("#titles-won-title"));
d3.select("#titles-won-title").text("All Professional Titles Won By Male Players from " + selected_country.country); }

var num = -1;
for (var i = 0; i < gsCountryTitles.length; i++) {
if (gsCountryTitles[i].country_id === selected_country.id) {num = i;}
}
if (num >= 0 || !gs) {
var elem = document.getElementById("tree-map");
elem.remove();
var parent = document.getElementById("tree-map-holder");
var new_chart_holder = document.createElement("div");
new_chart_holder.id = "tree-map";
var chart = tree(selected_country.id);
new_chart_holder.appendChild(chart);
parent.appendChild(new_chart_holder);
} else {
var elem = document.getElementById("tree-map");
elem.remove();
var parent = document.getElementById("tree-map-holder");
var new_chart_holder = document.createElement("div");
new_chart_holder.id = "tree-map";
var chart = emptyTree();
new_chart_holder.appendChild(chart);
parent.appendChild(new_chart_holder);

}
}
Insert cell
players100clay = FileAttachment("upsets100clay_players.csv").csv()
Insert cell
players100hard = FileAttachment("upsets100hard_players.csv").csv()
Insert cell
players100grass = FileAttachment("upsets100grass_players.csv").csv()
Insert cell
Insert cell
Insert cell
frenchSuccess = FileAttachment("french.csv").csv()
Insert cell
viewof radios = Inputs.radio(["Grand Slams", "All Professional Tournaments"], {id: "gsVat", label: "Tournament Level", value: "Grand Slams"})

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function tree(id){
// set the dimensions and margins of the graph
const margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 425 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;

// append the svg object to the body of the page
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom).attr("id", "tree-map")
// .append("g")
// .attr("transform",
// `translate(${margin.left}, ${margin.top})`);
console.log(radios);
var gs = 0;
if (radios == "Grand Slams") {
gs = 1;
} console.log(gs)


if (gs) {d3.select("#titles-won-title").text("Grand Slam Titles Won By Male Players from " + selected_country.country); } else {
console.log("in. here");
console.log(d3.select("#titles-won-title"));
d3.select("#titles-won-title").text("All Professional Titles Won By Male Players from " + selected_country.country); }


//var gs = document.getElementById("level-radio").firstChild.nextSibling.firstChild.nextSibling.nextSibling.firstChild.nextSibling.firstChild.checked;

var adjusted = [];
if (gs) {
var num = -1;
for (var i = 0; i < gsCountryTitles.length; i++) {
if (gsCountryTitles[i].country_id === id) {num = i;}
}
var raw_data;
if (num >= 0) {
raw_data = gsCountryTitles[num];
adjusted = [{name: "Origin", parent: "", value: ""}, {name: "clay", parent: "Origin", value: raw_data.sum_clay_slams},{name: "hard", parent: "Origin", value: raw_data.sum_hard_slams},{name: "grass", parent: "Origin", value: raw_data.sum_grass_slams},];
} else {
return (emptyTree());
adjusted = [{name: "Origin", parent: "", value: ""}, {name: "clay", parent: "Origin", value: 0},{name: "hard", parent: "Origin", value: 0},{name: "grass", parent: "Origin", value: 0},];

}
// Read data

} else {
var num = -1;
for (var i = 0; i < titles.length; i++) {
if (titles[i].country_id === id) {num = i;}
}
if (num >= 0) {
var raw_data = titles[num];
// Read data
adjusted = [{name: "Origin", parent: "", value: ""}, {name: "clay", parent: "Origin", value: raw_data.clay_titles},{name: "hard", parent: "Origin", value: raw_data.hard_titles},{name: "grass", parent: "Origin", value: raw_data.grass_titles},];
} else {
var raw_data = titles[num];
// Read data
return (emptyTree());
adjusted = [{name: "Origin", parent: "", value: ""}, {name: "clay", parent: "Origin", value: 0},{name: "hard", parent: "Origin", value: 0},{name: "grass", parent: "Origin", value: 0},];
}

}
adjusted = adjusted.filter((n) => {return n.value > 0 || n.name === "Origin"});


// stratify the data: reformatting for d3.js
const root = d3.stratify()
.id(function(d) { return d.name; }) // Name of the entity (column name is name in csv)
.parentId(function(d) { return d.parent; }) // Name of the parent (column name is parent in csv)
(adjusted);
root.sum(function(d) { return +d.value }) // Compute the numeric value for each entity

// Then d3.treemap computes the position of each element of the hierarchy
// The coordinates are added to the root object above
d3.treemap()
.size([width, height])
.padding(4)
(root)

// use this information to add rectangles:
svg
.selectAll("rect")
.data(root.leaves())
.join("rect")
.attr('x', function (d) { return d.x0; })
.attr('y', function (d) { return d.y0; })
.attr('width', function (d) { return d.x1 - d.x0; })
.attr('height', function (d) { return d.y1 - d.y0; })
.style("stroke", "black")
.style("fill", function (d) {
if (d.data.name === "clay") return "#ff968f";
if (d.data.name === "hard") return "#b0caff";
if (d.data.name === "grass") return "green";
}).on('mouseover',function(d, i){
var added = "";
if (gs) added = " grand slam";
d3.select(this)
.style("opacity", .8);
svg.append('text')
.attr('class', 'ptLabel')
.style('background-color', 'white')//Set class to 'ptLabel' so can remove easily later
.attr('x', 0)
.attr('y', 343)
.attr('fill', "black")
.text(selected_country.id + ": " + i.value + added + " title(s) won by male players on " + i.id );
})
.on('mouseout', function(d){
svg.selectAll('.ptLabel').remove()
d3.select(this)
.style("opacity", 1)
});

// and to add the text labels
svg
.selectAll("text")
.data(root.leaves())
.join("text")
.attr("x", function(d){ return d.x0+10}) // +10 to adjust position (more right)
.attr("y", function(d){ return d.y0+20}) // +20 to adjust position (lower)
.text(function(d){ return (d.data.name + ": " + d.data.value) })
.attr("font-size", "15px")
.attr("fill", "white")


return svg.node()
}
Insert cell
function overall() {
let width = 600
let height = 300
const svg_map_container = d3.create("svg").attr("width", width).attr("height", height).attr("id", "container");
// Map and projection
var path = d3.geoPath();
const projection = d3.geoNaturalEarth1()
.scale(width / 2 / Math.PI)
.translate([width / 2, height / 2])
var path = d3.geoPath().projection(projection);



// Load external data and boot
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson").then( function(data) {
data.features = data.features.filter(function(d){return d.properties.name!="Antarctica"}) //no players from antarctica (use this to control on click behavior => on click of country show list of players and their upsets, include reset button)

const Tooltip = svg_map_container.append("div")
.attr("class", "tooltip")
.style("opacity", 1)
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px")


// Draw the map
svg_map_container.append("g")
.selectAll("path")
.data(data.features)
.join("path")
.attr("fill", function (d) { //sum total for the country
let country = fave_surfaces.filter(c => c.country_id == d.id);
let favored = "";
if (country.length > 0) {
favored = country[0].favorite_surface;
} else {return "white";}
if (favored === "clay") return "#ff968f";
if (favored === "hard") return "#b0caff";
if (favored === "grass") return "green";
return "white";
})
.attr("d", d3.geoPath().projection(projection))
.style("stroke", "black").style("stroke-width",0.1).on('mouseover',function(d, i){
Tooltip.style("opacity", 1)
d3.select(this)
.style("opacity", 1)
.style("stroke","yellow")
.style("stroke-width",4);

var country = fave_surfaces.filter(c => c.country_id == i.id);
let favored = "Not enough data.";
if (country.length > 0) {
favored = country[0].favorite_surface;
svg_map_container.append('text')
.attr('class', 'ptLabel')
.style('background-color', 'white')//Set class to 'ptLabel' so can remove easily later
.attr('x', d.layerX + 1)
.attr('y', d.layerY - 10)
.attr('fill', "black")
.text(country[0].country_id + ": " + favored);
} else {
svg_map_container.append('text')
.attr('class', 'ptLabel')
.style('background-color', 'white')//Set class to 'ptLabel' so can remove easily later
.attr('x', d.layerX + 1)
.attr('y', d.layerY - 10)
.attr('fill', "black")
.text(i.id + ": " + favored);
}
})
.on('mouseout', function(d){
svg_map_container.selectAll('.ptLabel').remove()
d3.select(this)
.style("opacity", 0.8)
.style("stroke","black")
.style("stroke-width",0.1);
}).on('click',function(d, i){

var country = fave_surfaces.filter(c => c.country_id == i.id);
if (country.length > 0) {
selected_country.id = country[0].country_id;
var country = "";
for (var i = 0; i < titles.length; i++) {
if (titles[i].country_id == selected_country.id) {selected_country.country = titles[i].country_name;}
}
updateTree();

}
});
})
var g = svg_map_container.append("g").attr("class", "legend")
.attr("transform", "translate(20,20)");

var ordinal = d3.scaleOrdinal()
.domain(["Hard", "Grass", "Clay"])
.range([ "#b0caff", "green", "#ff968f"]);
svg_map_container.append("g")
.attr("class", "legendOrdinal")
.attr("transform", "translate(20,20)");
var legendOrdinal = leg.legendColor()
.shape("path", d3.symbol().size(300)())
.shapePadding(40).labelOffset(15)
.scale(ordinal);
svg_map_container.select(".legendOrdinal")
.call(legendOrdinal);
return svg_map_container.node()
}
Insert cell
function emptyTree() {
const margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 425 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;

// append the svg object to the body of the page
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom).attr("id", "tree-map")

svg
.append("text")
.attr("x", 0) // +10 to adjust position (more right)
.attr("y", height/2) // +20 to adjust position (lower)
.text("None won yet by male tennis players from " + selected_country.country)
.attr("font-size", "15px")
.attr("fill", "black")
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more