123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- <html lang="en">
- <head>
- <meta charset="utf-8" />
- <title>Weight-Track</title>
- <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.0/dist/Chart.bundle.min.js" integrity="sha256-tSYaQkuUF17Z5HozxXRWckY1j6uVLYFEHGEooJ6YsP0=" crossorigin="anonymous"></script>
- </head>
- <body>
- <div id="content">
- <h1>Weight-Track</h1>
- <p id="status">Please wait while Weight-Track is loading... (JavaScript needed)</p>
- </div>
- <div id="footer">
- <p>Made with <a href="https://www.chartjs.org/docs/latest/">Chart.js</a></p>
- </div>
- <script type="text/javascript">
- var colorFromIndex = function(index) {
- var colors = [
- '129, 38, 204',
- '48, 181, 36',
- '255, 99, 132',
- '54, 162, 235',
- '255, 206, 86',
- '75, 192, 192',
- '153, 102, 255',
- '255, 159, 64'
- ];
- if (index < colors.length) {
- return colors[index];
- } else {
- return '120, 120, 120';
- }
- };
-
- var createDataset = function(name, data, color, id) {
- return {
- label: name,
- data: data,
- yAxisID: id,
- backgroundColor: [
- 'rgba(' + color + ', 0)'
- ],
- borderColor: [
- 'rgba(' + color + ', 1)'
- ],
- pointBorderColor: 'rgba(' + color + ', 1)',
- pointRadius: 2,
- borderWidth: 4
- };
- };
-
- var addToForm = function(form, element, name) {
- var fe = document.createElement('p');
- fe.innerHTML = name + ' ';
- fe.appendChild(element);
- form.appendChild(fe);
- };
-
- var renderUser = function(data) {
- var div = document.createElement('div');
- var ctx = document.createElement('canvas');
-
- var min_date = new Date('3000-01-01T00:00:00');
- var max_date = new Date('1000-01-01T00:00:00');
- var min_kilo = 1000;
- var max_kilo = 0;
- for (var i = 0; i < data.users.length; i++) {
- for (var j = 0; j < data.users[i].data.length; j++) {
- temp_date = new Date(data.users[i].data[j].x);
- temp_kilo = parseInt(data.users[i].data[j].y);
- if (temp_date < min_date) {
- min_date = temp_date;
- }
- if (temp_date > max_date) {
- max_date = temp_date;
- }
- if (temp_kilo < min_kilo) {
- min_kilo = temp_kilo;
- }
- if (temp_kilo > max_kilo) {
- max_kilo = temp_kilo;
- }
- }
- }
-
- var days = (max_date - min_date) / 1000 / 60 / 60 / 24;
- var pixels_per_day = 3000 / 365;
- var width_px = days * pixels_per_day;
-
- var kilos = (max_kilo - min_kilo);
- var pixels_per_kilo = 1400 / 100;
- var height_px = kilos * pixels_per_kilo;
-
- var datasets = [];
- for (var i = 0; i < data.users.length; i++) {
- for (var j = 0; j <= 1; j++) {
- var set = createDataset(data.users[i].name,
- data.users[i].data, colorFromIndex(i), j ? 'A' : 'B');
- datasets.push(set);
- }
- }
-
- var chart = new Chart(ctx, {
- type: 'line',
- data: {
- datasets: datasets
- },
- options: {
- maintainAspectRatio: false,
- scales: {
- xAxes: [{
- type: 'time',
- time: {
- unit: 'day'
- }
- }],
- yAxes: [{
- id: 'A',
- type: 'linear',
- position: 'left'
- }, {
- id: 'B',
- type: 'linear',
- position: 'right'
- }]
- },
- events: [
- 'mousemove', 'mouseout', 'click',
- 'touchstart', 'touchmove', 'touchend'
- ],
- tooltips: {
- mode: 'nearest',
- intersect: false,
- axis: 'xy'
- }
- }
- });
-
- if (data.users.length > 0) {
- div_wrapper = document.createElement('div');
- div_wrapper.setAttribute('style', 'width: ' + Math.ceil(width_px) + 'px;');
-
- div_wrapper.style.width = Math.ceil(width_px) + 'px';
- div_wrapper.style.height = height_px + 'px';
- div_wrapper.width = Math.ceil(width_px);
- div_wrapper.height = height_px;
-
- div_wrapper.appendChild(ctx);
- div_wrapper2 = document.createElement('div');
- div_wrapper2.id = 'scroller';
- div_wrapper2.setAttribute('style', 'overflow-x: auto; overflow-y: auto;');
- div_wrapper2.appendChild(div_wrapper);
-
-
- size_slider = document.createElement('input');
- size_slider.setAttribute('type', 'range');
- size_slider.setAttribute('min', window.innerWidth);
- size_slider.setAttribute('max', Math.ceil(width_px));
- size_slider.setAttribute('value', Math.ceil(width_px));
- size_slider.oninput = function() {
- div_wrapper.setAttribute('style', 'width: ' + Math.ceil(width_px) + 'px;');
- div_wrapper.style.width = Math.ceil(width_px) + 'px';
- div_wrapper.width = Math.ceil(width_px);
- }
- div.appendChild(size_slider);
-
- div.appendChild(div_wrapper2);
- div.appendChild(document.createElement('hr'));
-
- var date = new Date();
- var hours = date.getHours();
- hours = (hours < 10) ? '0' + hours : hours;
- var minutes = date.getMinutes();
- minutes = (minutes < 10) ? '0' + minutes : minutes;
-
- var form_append = document.createElement('form');
- form_append.setAttribute('method', 'post');
- form_append.setAttribute('action', 'weight.php');
-
- var p_append = document.createElement('p');
- p_append.innerHTML = 'Add new Data-Point:';
- form_append.appendChild(p_append);
-
- var name_append = document.createElement('select');
- for (var i = 0; i < data.users.length; i++) {
- var option = document.createElement('option');
- option.text = data.users[i].name;
- option.value = 'user_' + data.users[i].id;
- name_append.add(option);
- }
- name_append.setAttribute('name', 'username');
- name_append.required = true;
- addToForm(form_append, name_append, 'Username:');
-
- var date_append = document.createElement('input');
- date_append.setAttribute('type', 'date');
- date_append.setAttribute('name', 'date');
- date_append.setAttribute('placeholder', 'Date');
- date_append.required = true;
- date_append.value = date.toISOString().slice(0, 10);
- addToForm(form_append, date_append, 'Date:');
-
- var time_append = document.createElement('input');
- time_append.setAttribute('type', 'time');
- time_append.setAttribute('name', 'time');
- time_append.setAttribute('placeholder', 'Time');
- time_append.required = true;
- time_append.value = hours + ':' + minutes;
- addToForm(form_append, time_append, 'Time:');
-
- var weight_append = document.createElement('input');
- weight_append.setAttribute('type', 'number');
- weight_append.setAttribute('name', 'weight');
- weight_append.setAttribute('step', '0.1');
- weight_append.min = 42.0;
- weight_append.max = 999.9;
- weight_append.setAttribute('placeholder', 'Weight');
- weight_append.required = true;
- addToForm(form_append, weight_append, 'Weight:');
-
- var submit_append = document.createElement('input');
- submit_append.setAttribute('type', 'submit');
- submit_append.setAttribute('value', 'Add Data');
- form_append.appendChild(submit_append);
-
- div.appendChild(form_append);
- div.appendChild(document.createElement('hr'));
- }
-
- var form_new = document.createElement('form');
- form_new.setAttribute('method', 'post');
- form_new.setAttribute('action', 'weight.php');
-
- var p_new = document.createElement('p');
- p_new.innerHTML = 'Add new User:';
- form_new.appendChild(p_new);
-
- var name_new = document.createElement('input');
- name_new.setAttribute('type', 'text');
- name_new.setAttribute('name', 'username');
- name_new.setAttribute('placeholder', 'Name');
- name_new.required = true;
- addToForm(form_new, name_new, 'Username:');
-
- var submit_new = document.createElement('input');
- submit_new.setAttribute('type', 'submit');
- submit_new.setAttribute('value', 'Add User');
- form_new.appendChild(submit_new);
-
- div.appendChild(form_new);
- div.appendChild(document.createElement('hr'));
- document.getElementById("content").appendChild(div);
-
- document.getElementById("scroller").scrollLeft += width_px * 4;
- };
-
- var getJSON = function(url, callback) {
- var xhr = new XMLHttpRequest();
- xhr.open('GET', url, true);
- xhr.responseType = 'json';
- xhr.onload = function() {
- if (xhr.status === 200) {
- callback(null, xhr.response);
- } else {
- callback(xhr.status, xhr.response);
- }
- };
- xhr.send();
- };
-
- document.getElementById("status").textContent = "Loading from Database...";
-
- getJSON('weight.php', function(err, data) {
- if (err !== null) {
- document.getElementById("status").textContent = 'Error: ' + err;
- return;
- }
- if (typeof data.error !== 'undefined') {
- document.getElementById("status").textContent = 'Error: ' + data.error;
- return;
- }
- if (typeof data.users !== 'undefined') {
- var s = 'Received data for ' + data.users.length + ' users';
- if (data.users.length > 0) {
- s += ': ';
- for (var i = 0; i < data.users.length; i++) {
- s += '"' + data.users[i].name + '"';
- if (i < (data.users.length - 1)) {
- s += ', ';
- }
- }
- s += '. Rendering...';
- } else {
- s += '. Nothing to show!';
- }
- document.getElementById("status").textContent = s;
- renderUser(data);
- } else {
- document.getElementById("status").textContent = 'Error: no data';
- return;
- }
- });
- </script>
- </body>
- </html>
|