index.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>TS3 channel usage</title>
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <link href="stylesheet.css" rel="stylesheet" type="text/css">
  8. <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../flot/excanvas.min.js"></script><![endif]-->
  9. <script language="javascript" type="text/javascript" src="../flot/jquery.min.js"></script>
  10. <script language="javascript" type="text/javascript" src="../flot/jquery.flot.min.js"></script>
  11. <script language="javascript" type="text/javascript" src="../flot/jquery.flot.stack.min.js"></script>
  12. <script language="javascript" type="text/javascript" src="../flot/jquery.flot.time.min.js"></script>
  13. <script language="javascript" type="text/javascript" src="../flot/jquery.flot.selection.min.js"></script>
  14. <script language="javascript" type="text/javascript" src="../flot/jquery.flot.resize.min.js"></script>
  15. </head>
  16. <body>
  17. <header class="main-head">TS3 channel usage</header>
  18. <div id="tree"></div>
  19. <div id="graphs"></div>
  20. <script>
  21. function update() {
  22. fetch("ajax.php").then(res=>res.json()).then(function(json) {
  23. let channelTree = {channelId: 0, name: 'Server'};
  24. makeTree(channelTree, json.channels, json.events);
  25. showTree(channelTree, document.getElementById('tree'));
  26. let div = $("#graphs")[0];
  27. div.innerHTML = "";
  28. for(const channel of channelTree.children) {
  29. if(channel.clientCount == 0)
  30. continue;
  31. let container = document.createElement("div");
  32. container.classList.add("demo-container");
  33. div.appendChild(container);
  34. let placeholder = document.createElement("div");
  35. placeholder.classList.add("demo-placeholder");
  36. container.appendChild(placeholder);
  37. plotEvents(channel, placeholder);
  38. }
  39. console.log(channelTree);
  40. });
  41. }
  42. update();
  43. setInterval(update, 30 * 1000);
  44. function makeTree(tree, channels, events) {
  45. tree.events = events.filter(e => e[0] == tree.id);
  46. tree.children = channels.filter((ch) => ch.parentId == tree.channelId).sort((a, b) => a.position - b.position);
  47. tree.clientCount = tree.events.reduce((sum, e) => sum+e[2], 0) / (tree.events.length > 0 ? tree.events.length : 1);
  48. for(const child of tree.children) {
  49. tree.clientCount += makeTree(child, channels.filter( ch => ch.parentId != tree.channelId), events.filter( e => e[0] != tree.id));
  50. }
  51. return tree.clientCount;
  52. }
  53. function showTree(tree, el) {
  54. el.innerHTML = `${formatHeadings(tree.name)}`;
  55. if(tree.events.length > 0 && (tree.events.length != 1 || tree.events[0][2] != 0))
  56. for(const event of tree.events) {
  57. el.innerHTML += `<br>${(new Date(event[1]*1000)).toLocaleTimeString('de-DE', {timeZone: 'Europe/Berlin'})}: ${event[2]}`
  58. }
  59. let ul = document.createElement('ul');
  60. el.appendChild(ul);
  61. for(const channel of tree.children) {
  62. if(channel.clientCount == 0)
  63. continue;
  64. let li = document.createElement('li');
  65. ul.appendChild(li);
  66. showTree(channel, li);
  67. }
  68. }
  69. function formatHeadings(str, html = true) {
  70. const res = /(?:\[(.)spacer[^\]]*\])?(.*)/.exec(str);
  71. if(!html)
  72. return res[2];
  73. switch(res[1]) {
  74. case '*':
  75. return `<div class='channel'>${res[2].repeat(50)}</div>`;
  76. case 'l':
  77. return `<div class='channel' align='left'>${res[2]}</div>`;
  78. case 'c':
  79. return `<div class='channel' align='center'>${res[2]}</div>`;
  80. case 'r':
  81. return `<div class='channel' align='right'>${res[2]}</div>`;
  82. default:
  83. return `<div class='channel'>${res[2]}</div>`;
  84. }
  85. }
  86. function plotEvents(tree, div) {
  87. let series = [];
  88. function iterChilds(tree, prefix="") {
  89. const data = tree.events.map(e => [e[1]*1000, e[2]]);
  90. const name = prefix + formatHeadings(tree.name, false);
  91. if(data.length > 0 && (data.length != 1 || data[0][1] != 0)) {
  92. series.push({
  93. label: name,
  94. data: data,
  95. lines: {
  96. show: true,
  97. fill: true,
  98. steps: true
  99. }
  100. });
  101. }
  102. for(const channel of tree.children) {
  103. iterChilds(channel, name + ' / ');
  104. }
  105. }
  106. iterChilds(tree);
  107. return $.plot(div, series, {
  108. xaxis: {
  109. mode: "time",
  110. timeBase: "milliseconds",
  111. timezone: "browser"
  112. }
  113. });
  114. }
  115. </script>
  116. </body>
  117. </html>