Simple PHP & SQL weight tracker for multiple persons
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <html lang="en">
  2. <head>
  3. <meta charset="utf-8" />
  4. <title>Weight-Track</title>
  5. <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.0/dist/Chart.bundle.min.js" integrity="sha256-tSYaQkuUF17Z5HozxXRWckY1j6uVLYFEHGEooJ6YsP0=" crossorigin="anonymous"></script>
  6. </head>
  7. <body>
  8. <div id="content">
  9. <h1>Weight-Track</h1>
  10. <p id="status">Please wait while Weight-Track is loading... (JavaScript needed)</p>
  11. </div>
  12. <div id="footer">
  13. <p>Made with <a href="https://www.chartjs.org/docs/latest/">Chart.js</a></p>
  14. </div>
  15. <script type="text/javascript">
  16. var colorFromIndex = function(index) {
  17. var colors = [
  18. '129, 38, 204',
  19. '48, 181, 36',
  20. '255, 99, 132',
  21. '54, 162, 235',
  22. '255, 206, 86',
  23. '75, 192, 192',
  24. '153, 102, 255',
  25. '255, 159, 64'
  26. ];
  27. if (index < colors.length) {
  28. return colors[index];
  29. } else {
  30. return '120, 120, 120';
  31. }
  32. };
  33. var createDataset = function(name, data, color) {
  34. return {
  35. label: name,
  36. data: data,
  37. backgroundColor: [
  38. 'rgba(' + color + ', 0)'
  39. ],
  40. borderColor: [
  41. 'rgba(' + color + ', 1)'
  42. ],
  43. pointBorderColor: 'rgba(' + color + ', 1)',
  44. pointRadius: 2,
  45. borderWidth: 4
  46. };
  47. };
  48. var addToForm = function(form, element, name) {
  49. var fe = document.createElement('p');
  50. fe.innerHTML = name + ' ';
  51. fe.appendChild(element);
  52. form.appendChild(fe);
  53. };
  54. var renderUser = function(data) {
  55. var div = document.createElement('div');
  56. var ctx = document.createElement('canvas');
  57. var min_date = new Date('3000-01-01T00:00:00');
  58. var max_date = new Date('1000-01-01T00:00:00');
  59. var min_kilo = 1000;
  60. var max_kilo = 0;
  61. for (var i = 0; i < data.users.length; i++) {
  62. for (var j = 0; j < data.users[i].data.length; j++) {
  63. temp_date = new Date(data.users[i].data[j].x);
  64. temp_kilo = parseInt(data.users[i].data[j].y);
  65. if (temp_date < min_date) {
  66. min_date = temp_date;
  67. }
  68. if (temp_date > max_date) {
  69. max_date = temp_date;
  70. }
  71. if (temp_kilo < min_kilo) {
  72. min_kilo = temp_kilo;
  73. }
  74. if (temp_kilo > max_kilo) {
  75. max_kilo = temp_kilo;
  76. }
  77. }
  78. }
  79. var days = (max_date - min_date) / 1000 / 60 / 60 / 24;
  80. var pixels_per_day = 3000 / 365;
  81. var width_px = days * pixels_per_day;
  82. var kilos = (max_kilo - min_kilo);
  83. var pixels_per_kilo = 1400 / 100;
  84. var height_px = kilos * pixels_per_kilo;
  85. var datasets = [];
  86. for (var i = 0; i < data.users.length; i++) {
  87. var set = createDataset(data.users[i].name,
  88. data.users[i].data, colorFromIndex(i));
  89. datasets.push(set);
  90. }
  91. var chart = new Chart(ctx, {
  92. type: 'line',
  93. data: {
  94. datasets: datasets
  95. },
  96. options: {
  97. maintainAspectRatio: false,
  98. scales: {
  99. xAxes: [{
  100. type: 'time',
  101. time: {
  102. unit: 'day'
  103. }
  104. }]
  105. },
  106. events: [
  107. 'mousemove', 'mouseout', 'click',
  108. 'touchstart', 'touchmove', 'touchend'
  109. ],
  110. tooltips: {
  111. mode: 'nearest',
  112. intersect: false,
  113. axis: 'x'
  114. }
  115. }
  116. });
  117. if (data.users.length > 0) {
  118. div_wrapper = document.createElement('div');
  119. div_wrapper.setAttribute('style', 'width: ' + Math.ceil(width_px) + 'px;');
  120. div_wrapper.style.width = Math.ceil(width_px) + 'px';
  121. div_wrapper.style.height = height_px + 'px';
  122. div_wrapper.width = Math.ceil(width_px);
  123. div_wrapper.height = height_px;
  124. div_wrapper.appendChild(ctx);
  125. div_wrapper2 = document.createElement('div');
  126. div_wrapper2.setAttribute('style', 'overflow-x: auto; overflow-y: auto;');
  127. div_wrapper2.appendChild(div_wrapper);
  128. div.appendChild(div_wrapper2);
  129. div.appendChild(document.createElement('hr'));
  130. var date = new Date();
  131. var hours = date.getHours();
  132. hours = (hours < 10) ? '0' + hours : hours;
  133. var minutes = date.getMinutes();
  134. minutes = (minutes < 10) ? '0' + minutes : minutes;
  135. var form_append = document.createElement('form');
  136. form_append.setAttribute('method', 'post');
  137. form_append.setAttribute('action', 'weight.php');
  138. var p_append = document.createElement('p');
  139. p_append.innerHTML = 'Add new Data-Point:';
  140. form_append.appendChild(p_append);
  141. var name_append = document.createElement('select');
  142. for (var i = 0; i < data.users.length; i++) {
  143. var option = document.createElement('option');
  144. option.text = data.users[i].name;
  145. option.value = 'user_' + data.users[i].id;
  146. name_append.add(option);
  147. }
  148. name_append.setAttribute('name', 'username');
  149. name_append.required = true;
  150. addToForm(form_append, name_append, 'Username:');
  151. var date_append = document.createElement('input');
  152. date_append.setAttribute('type', 'date');
  153. date_append.setAttribute('name', 'date');
  154. date_append.setAttribute('placeholder', 'Date');
  155. date_append.required = true;
  156. date_append.value = date.toISOString().slice(0, 10);
  157. addToForm(form_append, date_append, 'Date:');
  158. var time_append = document.createElement('input');
  159. time_append.setAttribute('type', 'time');
  160. time_append.setAttribute('name', 'time');
  161. time_append.setAttribute('placeholder', 'Time');
  162. time_append.required = true;
  163. time_append.value = hours + ':' + minutes;
  164. addToForm(form_append, time_append, 'Time:');
  165. var weight_append = document.createElement('input');
  166. weight_append.setAttribute('type', 'number');
  167. weight_append.setAttribute('name', 'weight');
  168. weight_append.setAttribute('step', '0.1');
  169. weight_append.min = 42.0;
  170. weight_append.max = 999.9;
  171. weight_append.setAttribute('placeholder', 'Weight');
  172. weight_append.required = true;
  173. addToForm(form_append, weight_append, 'Weight:');
  174. var submit_append = document.createElement('input');
  175. submit_append.setAttribute('type', 'submit');
  176. submit_append.setAttribute('value', 'Add Data');
  177. form_append.appendChild(submit_append);
  178. div.appendChild(form_append);
  179. div.appendChild(document.createElement('hr'));
  180. }
  181. var form_new = document.createElement('form');
  182. form_new.setAttribute('method', 'post');
  183. form_new.setAttribute('action', 'weight.php');
  184. var p_new = document.createElement('p');
  185. p_new.innerHTML = 'Add new User:';
  186. form_new.appendChild(p_new);
  187. var name_new = document.createElement('input');
  188. name_new.setAttribute('type', 'text');
  189. name_new.setAttribute('name', 'username');
  190. name_new.setAttribute('placeholder', 'Name');
  191. name_new.required = true;
  192. addToForm(form_new, name_new, 'Username:');
  193. var submit_new = document.createElement('input');
  194. submit_new.setAttribute('type', 'submit');
  195. submit_new.setAttribute('value', 'Add User');
  196. form_new.appendChild(submit_new);
  197. div.appendChild(form_new);
  198. div.appendChild(document.createElement('hr'));
  199. document.getElementById("content").appendChild(div);
  200. };
  201. var getJSON = function(url, callback) {
  202. var xhr = new XMLHttpRequest();
  203. xhr.open('GET', url, true);
  204. xhr.responseType = 'json';
  205. xhr.onload = function() {
  206. if (xhr.status === 200) {
  207. callback(null, xhr.response);
  208. } else {
  209. callback(xhr.status, xhr.response);
  210. }
  211. };
  212. xhr.send();
  213. };
  214. document.getElementById("status").textContent = "Loading from Database...";
  215. getJSON('weight.php', function(err, data) {
  216. if (err !== null) {
  217. document.getElementById("status").textContent = 'Error: ' + err;
  218. return;
  219. }
  220. if (typeof data.error !== 'undefined') {
  221. document.getElementById("status").textContent = 'Error: ' + data.error;
  222. return;
  223. }
  224. if (typeof data.users !== 'undefined') {
  225. var s = 'Received data for ' + data.users.length + ' users';
  226. if (data.users.length > 0) {
  227. s += ': ';
  228. for (var i = 0; i < data.users.length; i++) {
  229. s += '"' + data.users[i].name + '"';
  230. if (i < (data.users.length - 1)) {
  231. s += ', ';
  232. }
  233. }
  234. s += '. Rendering...';
  235. } else {
  236. s += '. Nothing to show!';
  237. }
  238. document.getElementById("status").textContent = s;
  239. renderUser(data);
  240. } else {
  241. document.getElementById("status").textContent = 'Error: no data';
  242. return;
  243. }
  244. });
  245. </script>
  246. </body>
  247. </html>