Public
Edited
Mar 5, 2023
Insert cell
Insert cell
games1 = FileAttachment("games1.json").json()
Insert cell
games2 = FileAttachment("games2.json").json()
Insert cell
arrayMatches1 = FileAttachment("test.json").json()
Insert cell
arrayMatches2 = FileAttachment("test2@1.json").json()
Insert cell
// Games of all players in the Spartan Company from 01/01/2019 to 12/31/2022
gameData = games1.concat(games2)
Insert cell
// Each object is an array of players that played in that game together
spartanCompanyMatches = arrayMatches1.concat(arrayMatches2)
Insert cell
// All the players in the spartan company
gamertags = ["OC McBuckets","MiniPuffDaddy","Stookey8144","TTV Elimessi10","Freaknbull","EkTwEnTyFoUr","RFxXDeBaTeAbLeX","Smoke2003x","SpaghettiPigeon","Groeds25","FierceCheesev2","SpaghettiSniper","Smelliot21","SuuperChicken"]
Insert cell
gameData.filter((d) => { return d.MapVariantName === "Viking" })
Insert cell
/*{
const players = {};
spartanCompanyMatches.forEach(function(d) {
players[d.key] = d.values.filter(function (object) {
return object.Players[0].Player.Gamertag;
});
});
}*/
Insert cell
function getData(game_data,players) {
var player_data = [];
for (let i = 0; i < game_data.length; i++) {
for (let j = 0; j < game_data[i].Players.length; j++) {
/*player_data.push(i)*/
var kd = game_data[i].Players[j].TotalKills/game_data[i].Players[j].TotalDeaths;
if(kd>5){
continue
}
if (players.indexOf(game_data[i].Players[j].Player.Gamertag) == -1){
continue;
}
var player_dict = {};
player_dict["name"] = game_data[i].Players[j].Player.Gamertag;
player_dict["game_day"] = game_data[i].MatchCompletedDate.ISO8601Date;
player_dict["kd"] = kd;
player_dict["date_sub"] = i;
player_data.push(player_dict)
/*
player_data.push([game_data[i].Players[j].Player.Gamertag,game_data[i].MatchCompletedDate.ISO8601Date,
game_data[i].Players[j].TotalKills/game_data[i].Players[j].TotalDeaths,i]) */
}
}
return player_data
}
Insert cell
gamer_data = getData(gameData,player_list)
Insert cell
Insert cell
chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

svg.append("g")
.call(xAxis);

svg.append("g")
.call(yAxis);
function colorSelector(d, player_list){
if(player_list){
var color_list = ["green", "purple", "orange", "yellow", "blue", "pink", "brown", "grey", "green", "lavender","black","magenta","violet","aero"]
return color_list[player_list.indexOf(d.name)]
}
}

svg.append("g")
.selectAll("circle")
.data(gamer_data)
.join("circle")
.filter(d => d.kd)
.attr("cx", d => time(new Date(d.game_day)))
.attr("cy", d => y(d.kd))
.attr("r", 2)
.attr("fill", function (d) {
return colorSelector(d,player_list) ;
})
.on("mouseover", function (event, d) {
var name = d.name;
var killdeath = d.kd;
const tooltipText = `Name-${name}; KD-${killdeath}`;
d3.select("#tooltip")
.transition()
.duration(500)
.style("opacity", 1)
.text(tooltipText);
})
.on("mouseout", function () {
d3.select("#tooltip").style("opacity", 0);
})
.on("mousemove", function (event, d) {
d3.select("#tooltip")
.style("top", event.pageY + "px")
.style("left", event.pageX + "px");
})
;
return svg.node();
}
Insert cell
player_list.indexOf("OC McBuckets")
Insert cell
height=400
Insert cell
x2 = d3.scaleTime()
.domain([new Date("2019-01-01T00:00:00"), new Date("2022-12-31T00:00:00")])
Insert cell
y = d3.scaleLinear()
.domain(d3.extent(gamer_data, d => d.kd)).nice()
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(time))
Insert cell
time = d3.scaleTime()
.domain([new Date("2019-01-01T00:00:00"), new Date("2022-12-31T00:00:00")])
.range([0, width - margin.left - margin.right])
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
Insert cell
margin = ({top: 25, right: 20, bottom: 35, left: 40})
Insert cell
class Tooltip {
constructor(selection) {
if (!selection || !selection.size()) {
throw "Requires a tooltip div element selection";
}
this._selection = selection;
}

move(event) {
if (!event) return;
const margin = 20;
const { clientX: x, clientY: y } = event;
const { width, height } = this.selection.node().getBoundingClientRect();
const left = this.clamp(
margin,
x - width / 2,
window.innerWidth - width - margin
);
const top =
window.innerHeight > y + margin + height
? y + margin
: y - height - margin;
this.selection.style("top", `${top}px`).style("left", `${left}px`);
}

display(datum, callback) {
if (!callback || typeof callback !== "function") {
throw "ToolTip.display requires a callback function that returns an HTML string";
}
this.selection.style("display", "block").html(callback(datum));
}

hide() {
this.selection.style("display", "none").html("");
}

clamp(min, d, max) {
return Math.max(min, Math.min(max, d));
}

get selection() {
return this._selection;
}

set selection(sel) {
if (sel && sel.size()) {
this._selection = sel;
} else {
throw "selection must be a non-empty selected element";
}
}
}
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