// Redraw a particular chart function redrawGraph(chart_number, refresh_seconds, xaxis_duration_min, xaxis_reset) { chart[chart_number].redraw(); if (xaxis_reset) { const epoch_min = new Date().setMinutes(new Date().getMinutes() - (1 * (xaxis_duration_min))); const epoch_max = new Date().getTime(); // Ensure Reset Zoom button resets to the proper start and end times chart[chart_number].xAxis[0].update({min: epoch_min}, false); chart[chart_number].xAxis[0].update({max: epoch_max}, false); // Update the new data time frame and redraw the chart chart[chart_number].xAxis[0].setExtremes(epoch_min, epoch_max, true); chart[chart_number].xAxis[0].isDirty = true; } } // Retrieve initial graph data set from the past (duration set by user) function getPastDataSynchronousGraph(chart_number, series, unique_id, measure_type, measurement_id, past_seconds) { const epoch_mil = new Date().getTime(); const url = '/past/' + unique_id + '/' + measure_type + '/' + measurement_id + '/' + past_seconds; const update_id = chart_number + "-" + series + "-" + unique_id + "-" + measure_type + '-' + measurement_id; $.getJSON(url, function(data, responseText, jqXHR) { if (jqXHR.status !== 204) { let new_time; let past_data = []; for (let i = 0; i < data.length; i++) { // Push the received data to the graph let new_date = new Date(data[i][0]); new_time = new_date.getTime(); if (measure_type === 'tag') { if (!note_timestamps.includes(new_time)) { past_data.push({ x: new_time, title: data[i][1], text: data[i][2].replace(/(?:\r\n|\r|\n)/g, '
').replace(/ /g, '\u2591\u2591') }); note_timestamps.push(new_time); } } else { past_data.push([new_time, data[i][1]]); } // Store the epoch time of the last data point received if (i === data.length - 1) { if (measure_type === 'tag') last_output_time_mil[update_id] = new_time + 3000; else last_output_time_mil[update_id] = new_time; } } // Set x-axis extremes, set graph data chart[chart_number].series[series].isDirty = true; // Data may not be in order by timestamp const epoch_min = new Date().setMinutes(new Date().getMinutes() - (past_seconds / 60)) chart[chart_number].xAxis[0].setExtremes(epoch_min, epoch_mil); chart[chart_number].series[series].setData(past_data, true, false); } } ); } // Retrieve chart data for the period since the last data acquisition (refresh period set by user) function retrieveLiveDataSynchronousGraph(chart_number, series, unique_id, measure_type, measurement_id, xaxis_duration_min, xaxis_reset, refresh_seconds) { const epoch_mil = new Date().getTime(); // Determine the timestamp of the last known measurement on the graph and // calculate the number of seconds from then until now, then build the URL // to query the measurements from that time period. let url = ''; let update_id = chart_number + "-" + series + "-" + unique_id + "-" + measure_type + '-' + measurement_id; if (update_id in last_output_time_mil) { const past_seconds = Math.floor((epoch_mil - last_output_time_mil[update_id]) / 1000); // seconds (integer) url = '/past/' + unique_id + '/' + measure_type + '/' + measurement_id + '/' + past_seconds; } else { url = '/past/' + unique_id + '/' + measure_type + '/' + measurement_id + '/' + refresh_seconds; } $.getJSON(url, function(data, responseText, jqXHR) { if (jqXHR.status !== 204) { let time_point; let graph_shift = false; // The timestamp of the beginning of the graph (oldest timestamp allowed on the graph) const oldest_timestamp_allowed = epoch_mil - (xaxis_duration_min * 60 * 1000); for (let i = 0; i < data.length; i++) { let time_point_raw = new Date(data[i][0]); time_point = time_point_raw.getTime(); // If the timestamp of the last point previously added is >= the new point TS, don't add let index_last = chart[chart_number].series[series].options.data.length - 1; if (typeof chart[chart_number].series[series].options.data[index_last] !== 'undefined') { let last_meas_time = chart[chart_number].series[series].options.data[index_last][0]; if (time_point <= last_meas_time) continue; } // If the first data point is older than allowed, shift the graph if (typeof chart[chart_number].series[series].options.data[0] !== 'undefined') { let first_meas_time = chart[chart_number].series[series].options.data[0][0]; graph_shift = first_meas_time < oldest_timestamp_allowed; } if (measure_type === 'tag') { if (!note_timestamps.includes(time_point)) { chart[chart_number].series[series].addPoint({ x: time_point, title: data[i][1], text: data[i][2].replace(/(?:\r\n|\r|\n)/g, '
').replace(/ /g, '\u2591\u2591') }, false, graph_shift); note_timestamps.push(time_point); } } else { chart[chart_number].series[series].addPoint([time_point, data[i][1]], false, graph_shift); } } // Store latest point timestamp if (measure_type === 'tag') last_output_time_mil[update_id] = time_point + 3000; else last_output_time_mil[update_id] = time_point; // Finally, redraw the graph redrawGraph(chart_number, refresh_seconds, xaxis_duration_min, xaxis_reset); } } ); } // Repeat function for retrieveLiveData() function getLiveDataSynchronousGraph(chart_number, series, unique_id, measure_type, measurement_id, xaxis_duration_min, xaxis_reset, refresh_seconds) { setInterval(function () { retrieveLiveDataSynchronousGraph(chart_number, series, unique_id, measure_type, measurement_id, xaxis_duration_min, xaxis_reset, refresh_seconds); }, refresh_seconds * 1000); }