]> de.git.xonotic.org Git - xonotic/xonstat.git/blob - xonstat/static/js/weaponCharts.js
Update the weapon charts to match.
[xonotic/xonstat.git] / xonstat / static / js / weaponCharts.js
1 // Colors assigned to the various weapons
2 var weaponColors = {
3   "arc": "#7c9ceb", 
4   "laser": "#f7717b", 
5   "blaster": "#f7717b", 
6   "shotgun": "#849ba8", 
7   "uzi": "#81f13d", 
8   "machinegun": "#81f13d", 
9   "grenadelauncher": "#fd7865", 
10   "mortar": "#fd7865", 
11   "minelayer": "#fd7865", 
12   "electro": "#6899f2",
13   "crylink": "#ea6ff9", 
14   "nex": "#75c3d5", 
15   "vortex": "#75c3d5", 
16   "hagar": "#e39160", 
17   "rocketlauncher": "#e9be57", 
18   "devastator": "#e9be57", 
19   "porto": "#6899f2", 
20   "minstanex": "#978ed2", 
21   "vaporizer": "#978ed2", 
22   "hook": "#81f13d", 
23   "hlac": "#e5965b",
24   "seeker": "#f7717b", 
25   "rifle": "#e39160", 
26   "tuba": "#e9be57", 
27   "fireball": "#f0855f"
28 };
29
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"]);
35
36 // these weapons are used in the accuracy chart
37 var accuracyWeapons = new Set(["vortex", "machinegun", "shotgun", "vaporizer",
38         "arc", "uzi", "nex", "minstanex", "rifle"]);
39
40 // draw an accuracy chart into the given element id
41 function drawAccuracyChart(id, data) {
42
43     // transform games list into a map such that games[game_id] = linear sequence
44     var games = {};
45     data.games.forEach(function(v,i){ games[v] = i; });
46
47     // for use in filtering out weapons that were not fired
48     function wasFired(e) { return e.fired != 0; }
49
50     // for use in filtering out splash-damage weapons
51     function isAccuracyWeapon(e) { return accuracyWeapons.has(e.weapon_cd); }
52
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));
56
57     nv.addGraph(function() {
58       var chart = nv.models.lineChart()
59         .useInteractiveGuideline(false)
60         .forceY([0,1])
61         .showLegend(true)
62         .showYAxis(true)
63         .showXAxis(true)
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; })
67       ;
68
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)" + 
74               "</td></tr></table>";
75       });
76
77       chart.lines.dispatch.on("elementClick", function(e) { 
78           window.location.href = "http://stats.xonotic.org/game/" + e.point.game_id.toString();
79       });
80
81       chart.yAxis
82           .axisLabel('Accuracy')
83           .tickFormat(d3.format('2%'));
84
85       chart.xAxis
86           .axisLabel('Games')
87           .tickFormat(function(e) { return ''; });
88
89       d3.select("#accuracyChartSVG")
90           .datum(accuracyData)
91           .call(chart);
92
93       nv.utils.windowResize(function() { chart.update() });
94       return chart;
95     });
96 };
97
98 // draw an damage chart into the given element id
99 function drawDamageChart(id, data) {
100     
101     // transform games list into a map such that games[game_id] = linear sequence
102     var games = {};
103     data.games.forEach(function(v,i){ games[v] = i; });
104
105     // for use in filtering out splash-damage weapons
106     function isDamageWeapon(e) { return damageWeapons.has(e.weapon_cd); }
107
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));
111
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.
118           .showXAxis(true)
119           .stacked(true)
120           .color(function(d){ return weaponColors[d.key]; })
121           .x(function(d) { return games[d.game_id] })
122           .y(function(d) { return d.actual; })
123         ;
124
125         chart.tooltip.contentGenerator(function(key, y, e, graph) {
126
127             var txt = "<table><tr><td>" +
128                 key.data.weapon_cd  + ": " + key.data.actual + " HP damage";
129
130             if (key.data.frags > 0) {
131                 if(key.data.frags > 1) {
132                     txt += " (" + key.data.frags + " frags)";
133                 } else {
134                     txt += " (" + key.data.frags + " frag)";
135                 }
136             }
137             txt += "</td></tr></table>";
138
139             return txt;
140         });
141
142         chart.multibar.dispatch.on("elementClick", function(e) { 
143             window.location.href = "http://stats.xonotic.org/game/" + e.data.game_id.toString();
144         });
145
146         chart.xAxis
147             .axisLabel('Games')
148             .tickFormat(function(e){ return '';});
149
150         chart.yAxis
151             .axisLabel('Damage (HP)')
152             .tickFormat(d3.format(',d'));
153
154         d3.select('#damageChartSVG')
155             .datum(damageData)
156             .call(chart);
157
158         nv.utils.windowResize(chart.update);
159
160         return chart;
161     });
162 };