stats.php 35 KB

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