// Colors assigned to the various weapons
var weaponColors = {
"arc": "#b8e9ff",
"laser": "#ff5933",
"blaster": "#ff5933",
"shotgun": "#1f77b4",
"uzi": "#b9e659",
"machinegun": "#b9e659",
"grenadelauncher": "#ff2600",
"mortar": "#ff2600",
"minelayer": "#bfbf00",
"electro": "#597fff",
"crylink": "#d940ff",
"nex": "#00e6ff",
"vortex": "#00e6ff",
"hagar": "#d98059",
"rocketlauncher": "#ffbf33",
"devastator": "#ffbf33",
"porto": "#7fff7f",
"minstanex": "#d62728",
"vaporizer": "#d62728",
"hook": "#a5ffd8",
"hlac": "#ffa533",
"seeker": "#ff5959",
"rifle": "#9467bd",
"tuba": "#d87f3f",
"fireball": "#33ff33"
};
// these weapons are used in the damage chart
var damageWeapons = new Set(["vortex", "machinegun", "shotgun",
"arc", "uzi", "nex", "minstanex", "rifle", "grenadelauncher", "minelayer",
"rocketlauncher", "hlac", "seeker", "fireball",
"mortar", "electro", "crylink", "hagar", "devastator"]);
// these weapons are used in the accuracy chart
var accuracyWeapons = new Set(["vortex", "machinegun", "shotgun", "vaporizer",
"arc", "uzi", "nex", "minstanex", "rifle"]);
// draw an accuracy chart into the given element id
function drawAccuracyChart(id, data) {
// transform games list into a map such that games[game_id] = linear sequence
var games = {};
data.games.forEach(function(v,i){ games[v] = i; });
// for use in filtering out weapons that were not fired
function wasFired(e) { return e.fired != 0; }
// for use in filtering out splash-damage weapons
function isAccuracyWeapon(e) { return accuracyWeapons.has(e.weapon_cd); }
// transform it into something NVD3 can use
var accuracyData = d3.nest().key(function(d) { return d.weapon_cd; })
.entries(data.weapon_stats.filter(isAccuracyWeapon).filter(wasFired));
nv.addGraph(function() {
var chart = nv.models.lineChart()
.useInteractiveGuideline(false)
.forceY([0,1])
.showLegend(true)
.showYAxis(true)
.showXAxis(true)
.color(function(d){ return weaponColors[d.key]; })
.x(function(d) { return games[d.game_id] })
.y(function(d) { return d.fired > 0 ? d.hit/d.fired : 0; })
;
chart.tooltip.contentGenerator(function(key, y, e, graph) {
return "
" +
key.point.weapon_cd + ": " +
Math.round(key.point.y*100) + "% (" +
Math.round(data.averages[key.point.weapon_cd]) + "% avg)" +
" |
";
});
chart.lines.dispatch.on("elementClick", function(e) {
window.location.href = "http://stats.xonotic.org/game/" + e.point.game_id.toString();
});
chart.yAxis
.axisLabel('Accuracy')
.tickFormat(d3.format('2%'));
chart.xAxis
.axisLabel('Games')
.tickFormat(function(e) { return ''; });
d3.select("#accuracyChartSVG")
.datum(accuracyData)
.call(chart);
nv.utils.windowResize(function() { chart.update() });
return chart;
});
};
// draw an damage chart into the given element id
function drawDamageChart(id, data) {
// transform games list into a map such that games[game_id] = linear sequence
var games = {};
data.games.forEach(function(v,i){ games[v] = i; });
// for use in filtering out splash-damage weapons
function isDamageWeapon(e) { return damageWeapons.has(e.weapon_cd); }
// transform it into something NVD3 can use
var damageData = d3.nest().key(function(d) { return d.weapon_cd; })
.entries(data.weapon_stats.filter(isDamageWeapon));
nv.addGraph(function() {
var chart = nv.models.multiBarChart()
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
.rotateLabels(0) //Angle to rotate x-axis labels.
.showControls(true) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
.showXAxis(true)
.stacked(true)
.color(function(d){ return weaponColors[d.key]; })
.x(function(d) { return games[d.game_id] })
.y(function(d) { return d.actual; })
;
chart.tooltip.contentGenerator(function(key, y, e, graph) {
var txt = "" +
key.data.weapon_cd + ": " + key.data.actual + " HP damage";
if (key.data.frags > 0) {
if(key.data.frags > 1) {
txt += " (" + key.data.frags + " frags)";
} else {
txt += " (" + key.data.frags + " frag)";
}
}
txt += " |
";
return txt;
});
chart.multibar.dispatch.on("elementClick", function(e) {
window.location.href = "http://stats.xonotic.org/game/" + e.data.game_id.toString();
});
chart.xAxis
.axisLabel('Games')
.tickFormat(function(e){ return '';});
chart.yAxis
.axisLabel('Damage (HP)')
.tickFormat(d3.format(',d'));
d3.select('#damageChartSVG')
.datum(damageData)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
};