1 // Colors assigned to the various weapons
8 "machinegun": "#b9e659",
9 "grenadelauncher": "#ff2600",
11 "minelayer": "#bfbf00",
17 "rocketlauncher": "#ffbf33",
18 "devastator": "#ffbf33",
20 "minstanex": "#d62728",
21 "vaporizer": "#d62728",
30 // these weapons are used in the damage chart
31 var damageWeapons = new Set(["vortex", "machinegun", "shotgun",
32 "arc", "uzi", "nex", "minstanex", "rifle", "grenadelauncher", "minelayer",
33 "rocketlauncher", "hlac", "seeker", "fireball",
34 "mortar", "electro", "crylink", "hagar", "devastator"]);
36 // these weapons are used in the accuracy chart
37 var accuracyWeapons = new Set(["vortex", "machinegun", "shotgun", "vaporizer",
38 "arc", "uzi", "nex", "minstanex", "rifle"]);
40 // draw an accuracy chart into the given element id
41 function drawAccuracyChart(id, data) {
43 // transform games list into a map such that games[game_id] = linear sequence
45 data.games.forEach(function(v,i){ games[v] = i; });
47 // for use in filtering out weapons that were not fired
48 function wasFired(e) { return e.fired != 0; }
50 // for use in filtering out splash-damage weapons
51 function isAccuracyWeapon(e) { return accuracyWeapons.has(e.weapon_cd); }
53 // transform it into something NVD3 can use
54 var accuracyData = d3.nest().key(function(d) { return d.weapon_cd; })
55 .entries(data.weapon_stats.filter(isAccuracyWeapon).filter(wasFired));
57 nv.addGraph(function() {
58 var chart = nv.models.lineChart()
59 .useInteractiveGuideline(false)
64 .color(function(d){ return weaponColors[d.key]; })
65 .x(function(d) { return games[d.game_id] })
66 .y(function(d) { return d.fired > 0 ? d.hit/d.fired : 0; })
69 chart.tooltip.contentGenerator(function(key, y, e, graph) {
70 return "<table><tr><td>" +
71 key.point.weapon_cd + ": " +
72 Math.round(key.point.y*100) + "% (" +
73 Math.round(data.averages[key.point.weapon_cd]) + "% avg)" +
77 chart.lines.dispatch.on("elementClick", function(e) {
78 window.location.href = "http://stats.xonotic.org/game/" + e.point.game_id.toString();
82 .axisLabel('Accuracy')
83 .tickFormat(d3.format('2%'));
87 .tickFormat(function(e) { return ''; });
89 d3.select("#accuracyChartSVG")
93 nv.utils.windowResize(function() { chart.update() });
98 // draw an damage chart into the given element id
99 function drawDamageChart(id, data) {
101 // transform games list into a map such that games[game_id] = linear sequence
103 data.games.forEach(function(v,i){ games[v] = i; });
105 // for use in filtering out splash-damage weapons
106 function isDamageWeapon(e) { return damageWeapons.has(e.weapon_cd); }
108 // transform it into something NVD3 can use
109 var damageData = d3.nest().key(function(d) { return d.weapon_cd; })
110 .entries(data.weapon_stats.filter(isDamageWeapon));
112 nv.addGraph(function() {
113 var chart = nv.models.multiBarChart()
114 .reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
115 .rotateLabels(0) //Angle to rotate x-axis labels.
116 .showControls(true) //Allow user to switch between 'Grouped' and 'Stacked' mode.
117 .groupSpacing(0.1) //Distance between each group of bars.
120 .color(function(d){ return weaponColors[d.key]; })
121 .x(function(d) { return games[d.game_id] })
122 .y(function(d) { return d.actual; })
125 chart.tooltip.contentGenerator(function(key, y, e, graph) {
127 var txt = "<table><tr><td>" +
128 key.data.weapon_cd + ": " + key.data.actual + " HP damage";
130 if (key.data.frags > 0) {
131 if(key.data.frags > 1) {
132 txt += " (" + key.data.frags + " frags)";
134 txt += " (" + key.data.frags + " frag)";
137 txt += "</td></tr></table>";
142 chart.multibar.dispatch.on("elementClick", function(e) {
143 window.location.href = "http://stats.xonotic.org/game/" + e.data.game_id.toString();
148 .tickFormat(function(e){ return '';});
151 .axisLabel('Damage (HP)')
152 .tickFormat(d3.format(',d'));
154 d3.select('#damageChartSVG')
158 nv.utils.windowResize(chart.update);