scatterplot = (w, h) => {
var var_x = "scored";
var var_y = "conceded";
var padding = 0.03 * width;
var svg = d3.create("svg").attr("width", w).attr("height", h);
const x_max = d3.max(dataset, (d) => d[var_x]);
const y_max = d3.max(dataset, (d) => d[var_y]);
var xScale = d3
.scaleLinear()
.domain([-1, x_max + 2])
.range([padding, w - padding * 2]);
var yScale = d3
.scaleLinear()
.domain([-1, y_max + 5])
.range([h - padding, padding]);
let line = d3
.line()
.x((d) => xScale(d.x))
.y((d) => yScale(d.y));
var xAxis = d3.axisBottom().scale(xScale).ticks(5);
var yAxis = d3.axisLeft().scale(yScale).ticks(5);
svg
.append("clipPath")
.attr("id", "chart-area")
.append("rect")
.attr("x", padding)
.attr("y", padding)
.attr("width", w - padding * 3)
.attr("height", h - padding * 2);
// Add y=x line to the plot :
svg
.append("line")
.attr("class", "line")
.attr("clip-path", "url(#chart-area)")
.attr("fill", "none")
.attr("stroke", "grey")
.attr("stroke-dasharray", "4,4")
.attr("x1", xScale(-1))
.attr("y1", yScale(-1))
.attr("x2", xScale(x_max))
.attr("y2", yScale(x_max));
//g for the plot zone
const g = svg
.append("g")
.attr("class", "scatterplot-zone")
.attr("clip-path", "url(#chart-area)");
// Create tooltip labels in advance (and mask them)
// We will display them only on mouseover event :
g.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("class", "scatter-label-text")
.style("outline", "solid 3px black")
.style("background-color", "white")
.style("float", "left")
.style("display", "none") //this helps to mask the label
.style("border-radius", `${Math.round(0.015 * h)}px`)
.style("font-family", "Tahoma")
.attr("id", function (d) {
return `scatter-label-${flag_data[d.team]}`;
})
.attr("x", function (d) {
return xScale(d[var_x]);
})
.attr("y", function (d) {
if (d[var_y] > 0.7 * y_max) {
return yScale(d[var_y]) + 0.1 * h;
} else {
return yScale(d[var_y]) - 0.03 * h;
}
})
.text(function (d) {
return ` ${d.team} (${d[var_x]};${d[var_y]}) `;
})
.attr("text-anchor", function (d) {
if (d[var_x] > 0.7 * x_max) {
return "end";
} else {
return "start";
}
})
.attr("opacity", 0); //this helps also to mask the label
g.selectAll("image")
.data(dataset)
.enter()
.append("image")
.attr("class", "scatter-flag")
.attr("xlink:href", function (d) {
//We use API from Flagpedia to add the flags (https://flagpedia.net/download/api)
return `https://flagcdn.com/w20/${flag_data[d.team]}.webp`;
})
.attr("id", function (d) {
return `scatter-flag-${flag_data[d.team]}`;
})
.attr("x", function (d) {
return xScale(d[var_x]);
})
.attr("y", function (d) {
return yScale(d[var_y]);
})
.attr("width", 0.025 * w)
.attr("height", 0.025 * h)
.on("mouseover", function (d) {
var data = d.path[0].__data__;
var team = data.team;
// Mask all labels :
d3.selectAll(".scatter-label-text")
.attr("opacity", 0)
.style("display", "none");
// Reduce opacity of all flags:
d3.selectAll(".scatter-flag")
.attr("opacity", 0.1)
.style("outline", "None");
// Display current flag with outline :
d3.select(`#scatter-flag-${flag_data[team]}`)
.attr("opacity", 1)
.style("outline", "1px solid black");
//Display label for current label :
d3.select(`#scatter-label-${flag_data[team]}`)
.attr("opacity", 1)
.style("display", "unset");
})
.on("mouseleave", function (d) {
var data = d.path[0].__data__;
var team = data.team;
//Mask label for curent flag :
d3.select(`#scatter-label-${flag_data[team]}`)
.attr("opacity", 0)
.style("display", "none");
//Restore opacity of all flags :
d3.selectAll(".scatter-flag").attr("opacity", 1);
//Remove the outline for the highlighted flag :
d3.select(`#scatter-flag-${flag_data[team]}`).style("outline", "None");
});
//Create X axis
svg
.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
//X label
svg
.append("text")
.attr("x", w - padding)
.attr("y", h)
.attr("fill", "#0a4a90")
.attr("font-size", 0.035 * h)
.attr("text-anchor", "end")
.text("Goals scored");
//Create Y axis
svg
.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
// Y label
svg
.append("text")
.attr("x", 0.5 * padding)
.attr("y", 0.5 * padding)
.attr("fill", "#0a4a90")
.attr("font-size", 0.035 * h)
.attr("text-anchor", "start")
.text("Goals conceded");
//Display year in the upper corner :
svg
.append("text")
.attr("text-anchor", "end")
.text(selectedYear)
.attr("x", w)
.attr("y", 0.077 * h)
.attr("fill", "#0a4a90")
.attr("font-weight", "bold")
.attr("font-family", "sans-serif")
.attr("font-size", 0.077 * h);
return svg.node();
}