stats.php 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. <?php
  2. /**
  3. * Runs view.
  4. *
  5. * Contains the view layout and ome code to present the data.
  6. *
  7. * @author Iñigo Valentin <i@inigovalentin.com>
  8. * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3
  9. * @package SWDB
  10. * @category View
  11. * @property Stats_Page $page The page model.
  12. * @var Stats_Page $page The page model.
  13. */
  14. ?>
  15. <!DOCTYPE html>
  16. <html lang='en'>
  17. <head>
  18. <?=$page->generate_head()?>
  19. <script>
  20. function selectAreaType(){
  21. var areaType = document.getElementById('filter_area_type').options[document.getElementById('filter_area_type').selectedIndex].value;
  22. // Clear all selectors
  23. document.getElementById('filter_stage').style.display = 'none';
  24. document.getElementById('filter_difficulty').style.display = 'none';
  25. var areas = document.getElementsByClassName('filter_area');
  26. for (var i = 0; i < areas.length; i++) {
  27. areas[i].style.display = 'none';
  28. areas[i].removeAttribute('name');
  29. }
  30. // Show selected selector.
  31. switch (areaType){
  32. case '<?=AREA_TYPE_ID::SCENARIO?>':
  33. document.getElementById('filter_area_scenario').style.display = 'inline-block';
  34. document.getElementById('filter_area_scenario').setAttribute('name', 'area');
  35. populateStage(7);
  36. document.getElementById('filter_stage').style.display = 'inline-block';
  37. populateDifficulty();
  38. document.getElementById('filter_difficulty').style.display = 'inline-block';
  39. break;
  40. case '<?=AREA_TYPE_ID::CAIROS_DUNGEON?>':
  41. document.getElementById('filter_area_cairos').style.display = 'inline-block';
  42. document.getElementById('filter_area_cairos').setAttribute('name', 'area');
  43. populateStage(10);
  44. document.getElementById('filter_stage').style.display = 'inline-block';
  45. break;
  46. case '<?=AREA_TYPE_ID::RIFT_DUNGEON?>':
  47. document.getElementById('filter_area_rift_dungeon').style.display = 'inline-block';
  48. document.getElementById('filter_area_rift_dungeon').setAttribute('name', 'area');
  49. break;
  50. // TODO: Other areas
  51. // Rift Raid: Don't filter by area.
  52. // Arena: Don't filter by area.
  53. // Guild War: Don't filter by area.
  54. // Guild Siege: Don't filter by area.
  55. // Rift Raid: Don't filter by area.
  56. // Tartarus: Don't filter by area.
  57. // TOA: Don't filter by area.
  58. // Rift Raid: Don't filter by area.
  59. // WB: Don't filter by area.
  60. // Dimensional Rift: Don't filter by area.
  61. // TODO: Filter Dimensional Hole dungeon
  62. }
  63. }
  64. /**
  65. * Shows the stage selector in the filters.
  66. *
  67. * @param total The number of stages to show.
  68. */
  69. function populateStage(total){
  70. var sel = document.getElementById('filter_stage');
  71. while (sel.firstChild) {
  72. sel.removeChild(sel.firstChild);
  73. }
  74. var opt;
  75. var att;
  76. // Empty
  77. opt = document.createElement('option');
  78. tex = document.createTextNode('');
  79. opt.appendChild(tex);
  80. sel.appendChild(opt);
  81. for (var i = 1; i <= total; i ++){
  82. opt = document.createElement('option');
  83. tex = document.createTextNode('Stage ' + i);
  84. att = document.createAttribute('value');
  85. att.value = i;
  86. opt.setAttributeNode(att);
  87. opt.appendChild(tex);
  88. sel.appendChild(opt);
  89. }
  90. }
  91. /**
  92. * Shows the difficulty selector in the filter panel.
  93. *
  94. * @param labyrinth Indicates if the area type is the Tartarus
  95. * labyrinth. If so, it includes 'Easy'.
  96. * @param toa Indicates if the area type is the Tower of
  97. * Ascension. If so, it excludes 'Hell'.
  98. */
  99. function populateDifficulty(labyrinth = false, toa = false){
  100. var sel = document.getElementById('filter_difficulty');
  101. while (sel.firstChild) {
  102. sel.removeChild(sel.firstChild);
  103. }
  104. var opt;
  105. var att;
  106. var tex;
  107. // Empty
  108. opt = document.createElement('option');
  109. tex = document.createTextNode('');
  110. opt.appendChild(tex);
  111. sel.appendChild(opt);
  112. // Easy (Labyrinth only)
  113. if (labyrinth){
  114. opt = document.createElement('option');
  115. tex = document.createTextNode('Easy difficulty');
  116. att = document.createAttribute('value');
  117. att.value = '<?=DIFFICULTY_ID::EASY?>';
  118. opt.setAttributeNode(att);
  119. opt.appendChild(tex);
  120. sel.appendChild(opt);
  121. }
  122. // Normal
  123. opt = document.createElement('option');
  124. tex = document.createTextNode('Normal difficulty');
  125. att = document.createAttribute('value');
  126. att.value = '<?=DIFFICULTY_ID::NORMAL?>';
  127. opt.setAttributeNode(att);
  128. opt.appendChild(tex);
  129. sel.appendChild(opt);
  130. // Hard
  131. opt = document.createElement('option');
  132. tex = document.createTextNode('Hard difficulty');
  133. att = document.createAttribute('value');
  134. att.value = '<?=DIFFICULTY_ID::HARD?>';
  135. opt.setAttributeNode(att);
  136. opt.appendChild(tex);
  137. sel.appendChild(opt);
  138. // Hell
  139. if (!toa){
  140. opt = document.createElement('option');
  141. tex = document.createTextNode('Hell difficulty');
  142. att = document.createAttribute('value');
  143. att.value = '<?=DIFFICULTY_ID::HELL?>';
  144. opt.setAttributeNode(att);
  145. opt.appendChild(tex);
  146. sel.appendChild(opt);
  147. }
  148. }
  149. /**
  150. * Sets the values for the stage and difficulty at page load.
  151. */
  152. function initialValues(){
  153. <?php
  154. if ($page->filters["STAGE"] != null && $page->filters["STAGE"] > 0){
  155. ?>
  156. document.getElementById('filter_stage').selectedIndex = <?=$page->filters["STAGE"]?>;
  157. <?php
  158. }
  159. if ($page->filters["DIFFICULTY"] != null && $page->filters["DIFFICULTY"] > 0){
  160. ?>
  161. document.getElementById('filter_difficulty').selectedIndex = <?=$page->filters["DIFFICULTY"]?>;
  162. <?php
  163. }
  164. ?>
  165. }
  166. /**
  167. * Calls all required functions to draw all diagrams.
  168. */
  169. function populateDiagrams(){
  170. <?php
  171. if ($page->show_data){
  172. ?>
  173. diagramWin();
  174. diagramDropType();
  175. diagramDropRuneSlot();
  176. diagramDropRuneStars();
  177. diagramDropRuneQuality();
  178. <?php
  179. }
  180. ?>
  181. }
  182. /**
  183. * Generates the win rate diagram.
  184. */
  185. function diagramWin(){
  186. var canvas = document.getElementById("diagram_win");
  187. var ctx = canvas.getContext("2d");
  188. ctx.lineWidth = 2;
  189. var lastend = 0;
  190. var data = [<?=$page->win_lose[0]?>, <?=$page->win_lose[1]?>];
  191. var total = 0;
  192. var color = [
  193. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_1')).color,
  194. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_2')).color
  195. ];
  196. for(var e = 0; e < data.length; e++){
  197. total += data[e];
  198. }
  199. for (var i = 0; i < data.length; i++) {
  200. ctx.beginPath();
  201. ctx.moveTo(canvas.width / 2, canvas.height / 2);
  202. ctx.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, lastend, lastend + (Math.PI * 2 * (data[i] / total)), false);
  203. ctx.lineTo(canvas.width / 2, canvas.height / 2);
  204. ctx.fillStyle = '#000000';
  205. ctx.stroke();
  206. ctx.fillStyle = color[i];
  207. ctx.fill();
  208. lastend += Math.PI * 2 * (data[i] / total);
  209. }
  210. }
  211. /**
  212. * Generates the drop rate diagram.
  213. */
  214. function diagramDropType(){
  215. // TODO: Diferenciate scenario, dungeon and hall.
  216. var canvas = document.getElementById("diagram_drop_type");
  217. var ctx = canvas.getContext("2d");
  218. ctx.lineWidth = 2;
  219. var lastend = 0;
  220. var data = [
  221. <?=$page->drop_type["rune"]?>,
  222. <?=$page->drop_type["rune_craft"]?>,
  223. <?=$page->drop_type["item"]?>,
  224. <?=$page->drop_type["sd"]?>,
  225. <?=$page->drop_type["shapeshifting"]?>,
  226. <?=$page->drop_type["unit"]?>,
  227. ];
  228. var total = 0;
  229. var color = [
  230. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_1')).color,
  231. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_2')).color,
  232. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_3')).color,
  233. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_4')).color,
  234. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_5')).color,
  235. getComputedStyle(document.querySelector('div.diagram table.legend tr.color_6')).color,
  236. ];
  237. for(var e = 0; e < data.length; e++){
  238. total += data[e];
  239. }
  240. for (var i = 0; i < data.length; i++) {
  241. ctx.beginPath();
  242. ctx.moveTo(canvas.width/2, canvas.height/2);
  243. ctx.arc(canvas.width/2, canvas.height/2, canvas.height/2, lastend, lastend + (Math.PI * 2 * (data[i] / total)), false);
  244. ctx.lineTo(canvas.width/2, canvas.height/2);
  245. ctx.fillStyle = '#000000';
  246. ctx.stroke();
  247. ctx.fillStyle = color[i];
  248. ctx.fill();
  249. lastend += Math.PI * 2 * (data[i] / total);
  250. }
  251. }
  252. /**
  253. * Generates the rune slot rate diagram.
  254. */
  255. function diagramDropRuneSlot(){
  256. var canvas = document.getElementById("diagram_rune_slot");
  257. var data = [
  258. <?=$page->drop_rune_slot["1"]?>,
  259. <?=$page->drop_rune_slot["2"]?>,
  260. <?=$page->drop_rune_slot["3"]?>,
  261. <?=$page->drop_rune_slot["4"]?>,
  262. <?=$page->drop_rune_slot["5"]?>,
  263. <?=$page->drop_rune_slot["6"]?>
  264. ];
  265. var total = 6;
  266. // Polarchart base
  267. var ctx_base = canvas.getContext("2d");
  268. ctx_base.lineWidth = 1;
  269. ctx_base.font = '32px serif'
  270. ctx_base.textBaseline = 'middle'
  271. ctx_base.textAlign = 'middle'
  272. var lastend = Math.PI + Math.PI / total;
  273. var radius = Math.round((canvas.width / 2) * ((i + 1) / total));
  274. for (var i = 0; i < total; i++) {
  275. ctx_base.moveTo(canvas.width / 2, canvas.height / 2);
  276. ctx_base.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, lastend, lastend + (Math.PI * 2 / total), false);
  277. ctx_base.lineTo(canvas.width / 2, canvas.height / 2);
  278. ctx_base.strokeStyle = '#333333';
  279. ctx_base.stroke();
  280. lastend += (Math.PI * 2 / total);
  281. }
  282. ctx_base.fillStyle = '#33333366';
  283. ctx_base.fill();
  284. // Numbers
  285. ctx_base.fillStyle = '#ffffff';
  286. lastend = Math.PI + Math.PI / total;
  287. for (var i = 0; i < total; i ++){
  288. lastend += (Math.PI * 2 / total);
  289. tx = canvas.width / 2 + canvas.width / 2.3 * Math.cos(lastend);
  290. ty = canvas.width / 2 + canvas.width / 2.3 * Math.sin(lastend);
  291. ctx_base.fillText(i + 1, tx - 8, ty);
  292. }
  293. // Polarchart content
  294. var ctx_data = canvas.getContext("2d");
  295. max = Math.max.apply(null, data) * 1.1;
  296. var initX = 0;
  297. var initY = 0;
  298. let region = new Path2D();
  299. for (var i = 0; i < total; i++) {
  300. var r = Math.round((canvas.width / 2) * data[i] / max);
  301. var x = Math.round(r * Math.sin(Math.PI * 2 / total));
  302. var y = Math.round(r * Math.cos(Math.PI * 2 / total));
  303. // Rotate the point
  304. angle = (i + 4) * Math.PI * 2 / total;
  305. rx = x * Math.cos(angle) - y * Math.sin(angle)
  306. ry = y * Math.cos(angle) + x * Math.sin(angle)
  307. rx += canvas.width / 2;
  308. ry += canvas.width / 2;
  309. if (i == 0){
  310. region.moveTo(rx, ry);
  311. initX = rx;
  312. initY = ry;
  313. }
  314. else{
  315. region.lineTo(rx, ry);
  316. }
  317. }
  318. region.lineTo(initX, initY);
  319. ctx_data.lineWidth = 2;
  320. ctx_data.strokeStyle = '#ff0000';
  321. ctx_data.stroke(region)
  322. ctx_data.fillStyle = '#ff000055';
  323. ctx_data.fill(region)
  324. }
  325. /**
  326. * Generates the rune star rate diagram.
  327. */
  328. function diagramDropRuneStars(){
  329. var canvas = document.getElementById("diagram_rune_stars");
  330. var data = [
  331. <?=$page->drop_rune_stars["6"]?>,
  332. <?=$page->drop_rune_stars["5"]?>,
  333. <?=$page->drop_rune_stars["4"]?>,
  334. <?=$page->drop_rune_stars["3"]?>,
  335. <?=$page->drop_rune_stars["2"]?>,
  336. <?=$page->drop_rune_stars["1"]?>
  337. ];
  338. var total = 6;
  339. // Polarchart base
  340. var ctx_base = canvas.getContext("2d");
  341. ctx_base.lineWidth = 1;
  342. ctx_base.font = '32px serif'
  343. ctx_base.textBaseline = 'middle'
  344. ctx_base.textAlign = 'middle'
  345. var lastend = Math.PI + Math.PI / total;
  346. for (var i = 0; i < total; i++) {
  347. radius = Math.round((canvas.width / 2) * ((i + 1) / total));
  348. ctx_base.moveTo(canvas.width / 2, canvas.height / 2);
  349. ctx_base.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, lastend, lastend + (Math.PI * 2 / total), false);
  350. ctx_base.lineTo(canvas.width / 2, canvas.height / 2);
  351. ctx_base.strokeStyle = '#333333';
  352. ctx_base.stroke();
  353. lastend += (Math.PI * 2 / total);
  354. }
  355. ctx_base.fillStyle = '#33333366';
  356. ctx_base.fill();
  357. // Numbers
  358. ctx_base.fillStyle = '#ffffff';
  359. lastend = Math.PI + Math.PI / total;
  360. for (var i = 0; i < total; i ++){
  361. lastend += (Math.PI * 2 / total);
  362. tx = canvas.width / 2 + canvas.width / 2.3 * Math.cos(lastend);
  363. ty = canvas.width / 2 + canvas.width / 2.3 * Math.sin(lastend);
  364. ctx_base.fillText(6 - i, tx - 8, ty);
  365. }
  366. // Polarchart content
  367. var ctx_data = canvas.getContext("2d");
  368. max = Math.max.apply(null, data) * 1.1;
  369. var initX = 0;
  370. var initY = 0;
  371. let region = new Path2D();
  372. for (var i = 0; i < total; i++) {
  373. var r = Math.round((canvas.width / 2) * data[i] / max);
  374. var x = Math.round(r * Math.sin(Math.PI * 2 / total));
  375. var y = Math.round(r * Math.cos(Math.PI * 2 / total));
  376. // Rotate the point
  377. angle = (i + 4) * Math.PI * 2 / total;
  378. rx = x * Math.cos(angle) - y * Math.sin(angle)
  379. ry = y * Math.cos(angle) + x * Math.sin(angle)
  380. rx += canvas.width / 2;
  381. ry += canvas.width / 2;
  382. if (i == 0){
  383. region.moveTo(rx, ry);
  384. initX = rx;
  385. initY = ry;
  386. }
  387. else{
  388. region.lineTo(rx, ry);
  389. }
  390. }
  391. region.lineTo(initX, initY);
  392. ctx_data.lineWidth = 2;
  393. ctx_data.strokeStyle = '#ff0000';
  394. ctx_data.stroke(region)
  395. ctx_data.fillStyle = '#ff000055';
  396. ctx_data.fill(region)
  397. }
  398. /**
  399. * Generates the rune quality rate diagram.
  400. */
  401. function diagramDropRuneQuality(){
  402. var canvas = document.getElementById("diagram_rune_quality");
  403. var data = [
  404. <?=$page->drop_rune_quality[strval(QUALITY_ID::LEGEND)]?>,
  405. <?=$page->drop_rune_quality[strval(QUALITY_ID::HERO)]?>,
  406. <?=$page->drop_rune_quality[strval(QUALITY_ID::RARE)]?>,
  407. <?=$page->drop_rune_quality[strval(QUALITY_ID::MAGIC)]?>,
  408. <?=$page->drop_rune_quality[strval(QUALITY_ID::NORMAL)]?>
  409. ];
  410. var total = 5;
  411. // Polarchart base
  412. var ctx_base = canvas.getContext("2d");
  413. ctx_base.lineWidth = 1;
  414. //var lastend = Math.PI * 2 / (0.5 * total / Math.PI);
  415. var lastend = ((270 - (180 / (total))) * Math.PI / 180);
  416. var color = [
  417. '#f5790066', // LEGEND
  418. '#ad7fa866', // HERO
  419. '#15c6e166', // RARE
  420. '#55ff5566', // MAGIC
  421. '#cccccc66' // NORMAL
  422. ];
  423. for (var i = 0; i < total; i++) {
  424. ctx_base.beginPath();
  425. radius = Math.round((canvas.width / 2) * ((i + 1) / total));
  426. ctx_base.moveTo(canvas.width / 2, canvas.height / 2);
  427. ctx_base.arc(canvas.width / 2, canvas.height / 2, canvas.height / 2, lastend, lastend + (Math.PI * 2 / total), false);
  428. ctx_base.lineTo(canvas.width / 2, canvas.height / 2);
  429. ctx_base.fillStyle = color[i];
  430. ctx_base.fill();
  431. ctx_base.strokeStyle = '#333333';
  432. ctx_base.stroke();
  433. lastend += (Math.PI * 2 / total);
  434. }
  435. //ctx_base.fillStyle = '#33333366';
  436. //ctx_base.fill()
  437. // Polarchart content
  438. var ctx_data = canvas.getContext("2d");
  439. max = Math.max.apply(null, data) * 1.1;
  440. var initX = 0;
  441. var initY = 0;
  442. let region = new Path2D();
  443. for (var i = 0; i < total; i++) {
  444. var r = Math.round((canvas.width / 2) * data[i] / max);
  445. var x = Math.round(r * Math.sin(Math.PI * 2 / total));
  446. var y = Math.round(r * Math.cos(Math.PI * 2 / total));
  447. // Rotate the point
  448. // TOTALLY experimental, not reliable for a different number of sectors.
  449. angle = (i * Math.PI * 2 / total) + 2 * Math.PI / (2 * (total - 1)) + 270 * (4.6/6) * Math.PI / 180;
  450. rx = x * Math.cos(angle) - y * Math.sin(angle)
  451. ry = y * Math.cos(angle) + x * Math.sin(angle)
  452. rx += canvas.width / 2;
  453. ry += canvas.width / 2;
  454. if (i == 0){
  455. region.moveTo(rx, ry);
  456. initX = rx;
  457. initY = ry;
  458. }
  459. else{
  460. region.lineTo(rx, ry);
  461. }
  462. }
  463. region.lineTo(initX, initY);
  464. ctx_data.lineWidth = 2;
  465. ctx_data.strokeStyle = '#ff0000';
  466. ctx_data.stroke(region)
  467. ctx_data.fillStyle = '#ff000055';
  468. ctx_data.fill(region)
  469. }
  470. // TODO: Script to show/hide area selector
  471. </script>
  472. </head>
  473. <body onload='populateDiagrams();selectAreaType();initialValues();'>
  474. <?php
  475. include __DIR__ . "/inc/header_app.php";
  476. include __DIR__ . "/inc/header_player.php";
  477. ?>
  478. <aside class='filters'>
  479. <h2>
  480. Statistics
  481. </h2>
  482. <form action='/<?=get_context()->get_player()-id?>/stats/' method='get' class='filter'>
  483. <table>
  484. <tr>
  485. <td class='filter'>
  486. <span>Area:</span>
  487. </td>
  488. </tr>
  489. <tr>
  490. <td class='filter'>
  491. <?php
  492. $selected = array_fill(0, 12 + 1, "");
  493. $selected[$page->filters["AREA_TYPE"]] = "selected";
  494. ?>
  495. <select name='area_type' id='filter_area_type' onChange='selectAreaType();'>
  496. <option value='0'></option>
  497. <option value='<?=AREA_TYPE_ID::SCENARIO?>' <?=$selected[AREA_TYPE_ID::SCENARIO]?>>Scenario</option>
  498. <option value='<?=AREA_TYPE_ID::CAIROS_DUNGEON?>' <?=$selected[AREA_TYPE_ID::CAIROS_DUNGEON]?>>Cairos Dungeon</option>
  499. <option value='<?=AREA_TYPE_ID::RIFT_DUNGEON?>' <?=$selected[AREA_TYPE_ID::RIFT_DUNGEON]?>>Rift Beast</option>
  500. <option value='<?=AREA_TYPE_ID::RIFT_RAID?>' <?=$selected[AREA_TYPE_ID::RIFT_RAID]?>>Rift Raid</option>
  501. <option value='<?=AREA_TYPE_ID::DIMENSIONAL_HOLE?>' <?=$selected[AREA_TYPE_ID::DIMENSIONAL_HOLE]?>>Dimensional Hole</option>
  502. </select>
  503. <?php
  504. $selected = array_fill(0, 9002, "");
  505. $selected[$page->filters["AREA"]] = "selected";
  506. ?>
  507. <select class='filter_area' id='filter_area_scenario'>
  508. <option value='0'></option>
  509. <option value='<?=AREA_TYPE_ID::SCENARIO?>' <?=$selected[AREA_TYPE_ID::SCENARIO]?>>Scenario</option>
  510. <option value='<?=AREA_TYPE_ID::CAIROS_DUNGEON?>' <?=$selected[AREA_TYPE_ID::CAIROS_DUNGEON]?>>Cairos Dungeon</option>
  511. <option value='<?=AREA_TYPE_ID::RIFT_DUNGEON?>' <?=$selected[AREA_TYPE_ID::RIFT_DUNGEON]?>>Rift Beast</option>
  512. <option value='<?=AREA_TYPE_ID::RIFT_RAID?>' <?=$selected[AREA_TYPE_ID::RIFT_RAID]?>>Rift Raid</option>
  513. <option value='<?=AREA_TYPE_ID::DIMENSIONAL_HOLE?>' <?=$selected[AREA_TYPE_ID::DIMENSIONAL_HOLE]?>>Dimensional Hole</option>
  514. <option value='<?=AREA_TYPE_ID::ARENA?>' <?=$selected[AREA_TYPE_ID::ARENA]?>>Arena</option>
  515. <option value='<?=AREA_TYPE_ID::GUILD_WAR?>' <?=$selected[AREA_TYPE_ID::GUILD_WAR]?>>Guild War</option>
  516. <option value='<?=AREA_TYPE_ID::GUILD_SIEGE?>' <?=$selected[AREA_TYPE_ID::GUILD_SIEGE]?>>Guild Siege</option>
  517. <option value='<?=AREA_TYPE_ID::TARTARUS_LABYRINTH?>' <?=$selected[AREA_TYPE_ID::TARTARUS_LABYRINTH]?>>Tartarus Labyrinth</option>
  518. <option value='<?=AREA_TYPE_ID::TRIAL_OF_ASCENSION?>' <?=$selected[AREA_TYPE_ID::TRIAL_OF_ASCENSION]?>>Trial of Ascension</option>
  519. <option value='<?=AREA_TYPE_ID::WORLD_BOSS?>' <?=$selected[AREA_TYPE_ID::WORLD_BOSS]?>>World Boss</option>
  520. <option value='<?=AREA_TYPE_ID::DIMENSIONAL_RIFT?>' <?=$selected[AREA_TYPE_ID::DIMENSIONAL_RIFT]?>>Dimensional Rift</option>
  521. </select>
  522. <select class='filter_area' id='filter_area_cairos'>
  523. <option value='0'></option>
  524. <option value='<?=DUNGEON_ID::GIANTS_KEEP?>' <?=$selected[DUNGEON_ID::GIANTS_KEEP]?>>Giant&#39;s Keep</option>
  525. <option value='<?=DUNGEON_ID::DRAGONS_LAIR?>' <?=$selected[DUNGEON_ID::DRAGONS_LAIR]?>>Dragon&#39;s Lair</option>
  526. <option value='<?=DUNGEON_ID::NECROPOLIS?>' <?=$selected[DUNGEON_ID::NECROPOLIS]?>>Necropolis</option>
  527. <option value='<?=DUNGEON_ID::HALL_OF_MAGIC?>' <?=$selected[DUNGEON_ID::HALL_OF_MAGIC]?>>Hall of Magic</option>
  528. <option value='<?=DUNGEON_ID::HALL_OF_LIGHT?>' <?=$selected[DUNGEON_ID::HALL_OF_LIGHT]?>>Hall of Light</option>
  529. <option value='<?=DUNGEON_ID::HALL_OF_DARK?>' <?=$selected[DUNGEON_ID::HALL_OF_DARK]?>>Hall of Dark</option>
  530. <option value='<?=DUNGEON_ID::HALL_OF_FIRE?>' <?=$selected[DUNGEON_ID::HALL_OF_FIRE]?>>Hall of Fire</option>
  531. <option value='<?=DUNGEON_ID::HALL_OF_WATER?>' <?=$selected[DUNGEON_ID::HALL_OF_WATER]?>>Hall of Water</option>
  532. <option value='<?=DUNGEON_ID::HALL_OF_WIND?>' <?=$selected[DUNGEON_ID::HALL_OF_WIND]?>>Hall of Wind</option>
  533. </select>
  534. <select id='filter_area_rift_dungeon' class='filter_area'>
  535. <option value='0'></option>
  536. <option value='<?=ELEMENTAL_RIFT_DUNGEON_ID::LIGHT_BEAST?>' <?=$selected[ELEMENTAL_RIFT_DUNGEON_ID::LIGHT_BEAST]?>>Light Beast</option>
  537. <option value='<?=ELEMENTAL_RIFT_DUNGEON_ID::DARK_BEAST?>' <?=$selected[ELEMENTAL_RIFT_DUNGEON_ID::DARK_BEAST]?>>Dark Beast</option>
  538. <option value='<?=ELEMENTAL_RIFT_DUNGEON_ID::FIRE_BEAST?>' <?=$selected[ELEMENTAL_RIFT_DUNGEON_ID::FIRE_BEAST]?>>Fire Beast</option>
  539. <option value='<?=ELEMENTAL_RIFT_DUNGEON_ID::ICE_BEAST?>' <?=$selected[ELEMENTAL_RIFT_DUNGEON_ID::ICE_BEAST]?>>Ice Beast</option>
  540. <option value='<?=ELEMENTAL_RIFT_DUNGEON_ID::WIND_BEAST?>' <?=$selected[ELEMENTAL_RIFT_DUNGEON_ID::WIND_BEAST]?>>Wind Beast</option>
  541. </select>
  542. <select id='filter_stage' name='stage'>
  543. </select>
  544. <select id='filter_difficulty' name='difficulty'>
  545. </select>
  546. </td>
  547. </tr>
  548. </table>
  549. <input type='submit' value='Apply'/>
  550. </form>
  551. </aside> <!-- #filters -->
  552. <main>
  553. <?php
  554. if ($page->show_data){
  555. ?>
  556. <section class='content'>
  557. <h2>
  558. Stats
  559. </h2>
  560. <article>
  561. <div id='win' class='diagram'>
  562. <h3>
  563. Victory rate
  564. </h3>
  565. <canvas id='diagram_win' width='200' height='200'></canvas>
  566. <?php
  567. $total = $page->win_lose[0] + $page->win_lose[1];
  568. // Fix divisions by 0 (dont use in total count):
  569. if ($total == 0){
  570. $total ++;
  571. }
  572. ?>
  573. <table class='legend'>
  574. <tr class='color_1'>
  575. <td>
  576. Victories:
  577. </td>
  578. <td>
  579. <?=$page->win_lose[0]?>
  580. </td>
  581. <td>
  582. (<?=number_format(($page->win_lose[0] * 100) / $total, 2, ".", ",")?>%)
  583. </td>
  584. </tr>
  585. <tr class='color_2'>
  586. <td>
  587. Defeats:
  588. </td>
  589. <td>
  590. <?=$page->win_lose[1]?>
  591. </td>
  592. <td>
  593. (<?=number_format(($page->win_lose[1] * 100) / $total, 2, ".", ",")?>%)
  594. </td>
  595. </tr>
  596. <tr class='color_0'>
  597. <td>
  598. Total:
  599. </td>
  600. <td colspan='2'>
  601. <?=($page->win_lose[0] + $page->win_lose[1])?>
  602. </td>
  603. </tr>
  604. </table>
  605. </div>
  606. <div id='drop_type' class='diagram'>
  607. <h3>
  608. Drop rate
  609. </h3>
  610. <canvas id='diagram_drop_type' width='200' height='200'></canvas>
  611. <table class='legend'>
  612. <?php
  613. // Do some calculations
  614. $rune = $page->drop_type["rune"];
  615. $rucr = $page->drop_type["rune_craft"];
  616. $item = $page->drop_type["item"];
  617. $sedu = $page->drop_type["sd"];
  618. $shap = $page->drop_type["shapeshifting"];
  619. $unit = $page->drop_type["unit"];
  620. $total = $rune + $rucr + $item + $sedu + $shap + $unit;
  621. // Fix divisions by 0:
  622. if ($total == 0){
  623. $total ++;
  624. }
  625. ?>
  626. <tr class='color_1'>
  627. <td>
  628. Rune:
  629. </td>
  630. <td>
  631. <?=$rune?>
  632. </td>
  633. <td>
  634. (<?=number_format(($rune * 100) / $total, 2, ".", ",")?>%)
  635. </td>
  636. </tr>
  637. <tr class='color_2'>
  638. <td>
  639. Rune craft item:
  640. </td>
  641. <td>
  642. <?=$rucr?>
  643. </td>
  644. <td>
  645. (<?=number_format(($rucr * 100) / $total, 2, ".", ",")?>%)
  646. </td>
  647. </tr>
  648. <tr class='color_3'>
  649. <td>
  650. Item:
  651. </td>
  652. <td>
  653. <?=$item?>
  654. </td>
  655. <td>
  656. (<?=number_format(($item * 100) / $total, 2, ".", ",")?>%)
  657. </td>
  658. </tr>
  659. <tr class='color_4'>
  660. <td>
  661. Secret Dungeon:
  662. </td>
  663. <td>
  664. <?=$sedu?>
  665. </td>
  666. <td>
  667. (<?=number_format(($sedu * 100) / $total, 2, ".", ",")?>%)
  668. </td>
  669. </tr>
  670. <tr class='color_5'>
  671. <td>
  672. Transmog Stone:
  673. </td>
  674. <td>
  675. <?=$shap?>
  676. </td>
  677. <td>
  678. (<?=number_format(($shap * 100) / $total, 2, ".", ",")?>%)
  679. </td>
  680. </tr>
  681. <tr class='color_6'>
  682. <td>
  683. Unit:
  684. </td>
  685. <td>
  686. <?=$unit?>
  687. </td>
  688. <td>
  689. (<?=number_format(($unit * 100) / $total, 2, ".", ",")?>%)
  690. </td>
  691. </tr>
  692. </table>
  693. </div>
  694. <div id='drop_rune_slot' class='diagram'>
  695. <h3>
  696. Rune drops by slot
  697. </h3>
  698. <canvas id='diagram_rune_slot' width='200' height='200'></canvas>
  699. <table class='legend'>
  700. <?php
  701. $total = array_sum($page->drop_rune_slot);
  702. // Fix divisions by 0:
  703. if ($total == 0){
  704. $total ++;
  705. }
  706. for ($i = 1; $i <= 6; $i ++){
  707. $val = $page->drop_rune_slot[strval($i)]
  708. ?>
  709. <tr class='color_0'>
  710. <td>
  711. Slot <?=$i?>:
  712. </td>
  713. <td>
  714. <?=$val?>
  715. </td>
  716. <td>
  717. (<?=number_format(($val * 100) / $total, 2, ".", ",")?>%)
  718. </td>
  719. </tr>
  720. <?php
  721. }
  722. ?>
  723. </table>
  724. </div>
  725. <div id='drop_rune_stars' class='diagram'>
  726. <h3>
  727. Rune drops by stars
  728. </h3>
  729. <canvas id='diagram_rune_stars' width='200' height='200'></canvas>
  730. <table class='legend'>
  731. <?php
  732. $total = array_sum($page->drop_rune_stars);
  733. // Fix divisions by 0:
  734. if ($total == 0){
  735. $total ++;
  736. }
  737. for ($i = 6; $i >= 1; $i --){
  738. $val = $page->drop_rune_stars[strval($i)]
  739. ?>
  740. <tr class='color_0'>
  741. <td>
  742. <?php
  743. for ($j = 1; $j <= $i; $j ++){
  744. ?>
  745. <img class='star star_gold' src='<?=URL::IMG["ICON"]?>star.png'/>
  746. <?php
  747. }
  748. ?>
  749. </td>
  750. <td>
  751. <?=$val?>
  752. </td>
  753. <td>
  754. (<?=number_format(($val * 100) / $total, 2, ".", ",")?>%)
  755. </td>
  756. </tr>
  757. <?php
  758. }
  759. ?>
  760. </table>
  761. </div>
  762. <div id='drop_rune_quality' class='diagram'>
  763. <h3>
  764. Rune drops by quality
  765. </h3>
  766. <canvas id='diagram_rune_quality' width='200' height='200'></canvas>
  767. <table class='legend'>
  768. <?php
  769. $total = array_sum($page->drop_rune_quality);
  770. // Fix divisions by 0:
  771. if ($total == 0){
  772. $total ++;
  773. }
  774. ?>
  775. <tr class='color_legend'>
  776. <td>
  777. Legend:
  778. </td>
  779. <td>
  780. <?=$page->drop_rune_quality[QUALITY_ID::LEGEND]?>
  781. </td>
  782. <td>
  783. (<?=number_format(($page->drop_rune_quality[QUALITY_ID::LEGEND] * 100) / $total, 2, ".", ",")?>%)
  784. </td>
  785. </tr>
  786. <tr class='color_hero'>
  787. <td>
  788. Hero:
  789. </td>
  790. <td>
  791. <?=$page->drop_rune_quality[QUALITY_ID::HERO]?>
  792. </td>
  793. <td>
  794. (<?=number_format(($page->drop_rune_quality[QUALITY_ID::HERO] * 100) / $total, 2, ".", ",")?>%)
  795. </td>
  796. </tr>
  797. <tr class='color_rare'>
  798. <td>
  799. Rare:
  800. </td>
  801. <td>
  802. <?=$page->drop_rune_quality[QUALITY_ID::RARE]?>
  803. </td>
  804. <td>
  805. (<?=number_format(($page->drop_rune_quality[QUALITY_ID::RARE] * 100) / $total, 2, ".", ",")?>%)
  806. </td>
  807. </tr>
  808. <tr class='color_magic'>
  809. <td>
  810. Magic:
  811. </td>
  812. <td>
  813. <?=$page->drop_rune_quality[QUALITY_ID::MAGIC]?>
  814. </td>
  815. <td>
  816. (<?=number_format(($page->drop_rune_quality[QUALITY_ID::MAGIC] * 100) / $total, 2, ".", ",")?>%)
  817. </td>
  818. </tr>
  819. <tr class='color_normal'>
  820. <td>
  821. Normal:
  822. </td>
  823. <td>
  824. <?=$page->drop_rune_quality[QUALITY_ID::NORMAL]?>
  825. </td>
  826. <td>
  827. (<?=number_format(($page->drop_rune_quality[QUALITY_ID::NORMAL] * 100) / $total, 2, ".", ",")?>%)
  828. </td>
  829. </tr>
  830. </table>
  831. </div>
  832. </article>
  833. </section>
  834. <?php
  835. }
  836. ?>
  837. </main>
  838. <?php
  839. include __DIR__ . "/inc/footer.php";
  840. ?>
  841. </body>
  842. </html>