diff --git a/api_FTL.php b/api_FTL.php
index 7e259a69..6f801dc0 100644
--- a/api_FTL.php
+++ b/api_FTL.php
@@ -303,5 +303,44 @@ if (isset($_GET['overTimeDataQueryTypes']) && $auth)
$data = array_merge($data, $result);
}
+if (isset($_GET['getClientNames']) && $auth)
+{
+ sendRequestFTL("client-names");
+ $return = getResponseFTL();
+ $forward_dest = array();
+ foreach($return as $line)
+ {
+ $tmp = explode(" ",$line);
+ if(count($tmp) == 4)
+ {
+ $forward_dest[$tmp[3]."|".$tmp[2]] = floatval($tmp[1]);
+ }
+ else
+ {
+ $forward_dest[$tmp[2]] = floatval($tmp[1]);
+ }
+ }
+
+ $result = array('clients' => $forward_dest);
+ $data = array_merge($data, $result);
+}
+
+if (isset($_GET['overTimeDataClients']) && $auth)
+{
+ sendRequestFTL("ClientsoverTime");
+ $return = getResponseFTL();
+ $over_time = array();
+
+ foreach($return as $line)
+ {
+ $tmp = explode(" ",$line);
+ for ($i=0; $i < count($tmp)-1; $i++) {
+ $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
+ }
+ }
+ $result = array('over_time' => $over_time);
+ $data = array_merge($data, $result);
+}
+
disconnectFTL();
?>
diff --git a/index.php b/index.php
index b97cd0bb..85e2278c 100644
--- a/index.php
+++ b/index.php
@@ -158,6 +158,25 @@
+
+
-1)
+ {
+ var idx = key.indexOf("|");
+ key = key.substr(0, idx);
+ }
+ labels.push(key);
+ }
+ // Get colors from AdminLTE
+ var colors = [];
+ $.each($.AdminLTE.options.colors, function(key, value) { colors.push(value); });
+ var v = [], c = [], k = [];
+
+ // Remove possibly already existing data
+ clientsChart.data.labels = [];
+ clientsChart.data.datasets[0].data = [];
+ for (i = 1; i < clientsChart.data.datasets.length; i++)
+ {
+ clientsChart.data.datasets[i].data = [];
+ }
+
+ // Collect values and colors, and labels
+ clientsChart.data.datasets[0].backgroundColor = colors[0];
+ clientsChart.data.datasets[0].pointRadius = 0;
+ clientsChart.data.datasets[0].pointHitRadius = 5;
+ clientsChart.data.datasets[0].pointHoverRadius = 5;
+ clientsChart.data.datasets[0].label = labels[0];
+
+ for (i = clientsChart.data.datasets.length; i < plotdata[0].length; i++)
+ {
+ clientsChart.data.datasets.push({data: [], backgroundColor: colors[i], pointRadius: 0, pointHitRadius: 5, pointHoverRadius: 5, label: labels[i]});
+ }
+
+ // Add data for each dataset that is available
+ for (j in timestamps)
+ {
+ if (!{}.hasOwnProperty.call(timestamps, j)) continue;
+ for (key in plotdata[j])
+ {
+ if (!{}.hasOwnProperty.call(plotdata[j], key)) continue;
+ clientsChart.data.datasets[key].data.push(1e-2*plotdata[j][key]);
+ }
+
+ var d = new Date(1000*parseInt(timestamps[j]));
+ clientsChart.data.labels.push(d);
+ }
+ $("#clients .overlay").hide();
+ clientsChart.update();
+ }).done(function() {
+ // Reload graph after 10 minutes
+ failures = 0;
+ setTimeout(updateClientsOverTime, 600000);
+ }).fail(function() {
+ failures++;
+ if(failures < 5)
+ {
+ // Try again after 1 minute only if this has not failed more
+ // than five times in a row
+ setTimeout(updateClientsOverTime, 60000);
+ }
+ });
+}
+
function updateForwardDestinationsPie() {
$.getJSON("api.php?getForwardDestinations=unsorted", function(data) {
@@ -625,6 +705,69 @@ $(document).ready(function() {
{
ctx = document.getElementById("forwardDestinationChart").getContext("2d");
forwardDestinationChart = new Chart(ctx, {
+ type: "line",
+ data: {
+ labels: [],
+ datasets: [{ data: [] }]
+ },
+ options: {
+ tooltips: {
+ enabled: true,
+ mode: "x-axis",
+ callbacks: {
+ title: function(tooltipItem, data) {
+ var label = tooltipItem[0].xLabel;
+ var time = label.match(/(\d?\d):?(\d?\d?)/);
+ var h = parseInt(time[1], 10);
+ var m = parseInt(time[2], 10) || 0;
+ var from = padNumber(h)+":"+padNumber(m-5)+":00";
+ var to = padNumber(h)+":"+padNumber(m+4)+":59";
+ return "Client activity from "+from+" to "+to;
+ },
+ label: function(tooltipItems, data) {
+ return data.datasets[tooltipItems.datasetIndex].label + ": " + (100.0*tooltipItems.yLabel).toFixed(1) + "%";
+ }
+ }
+ },
+ legend: {
+ display: false
+ },
+ scales: {
+ xAxes: [{
+ type: "time",
+ time: {
+ unit: "hour",
+ displayFormats: {
+ hour: "HH:mm"
+ },
+ tooltipFormat: "HH:mm"
+ }
+ }],
+ yAxes: [{
+ ticks: {
+ mix: 0.0,
+ max: 1.0,
+ beginAtZero: true,
+ callback: function(value, index, values) {
+ return Math.round(value*100) + " %";
+ }
+ },
+ stacked: true
+ }]
+ },
+ maintainAspectRatio: true
+ }
+ });
+
+ // Pull in data via AJAX
+ updateClientsOverTime();
+ }
+
+ // Create / load "Top Clients over Time" only if authorized
+ if(document.getElementById("clientsChart"))
+ {
+ ctx = document.getElementById("clientsChart").getContext("2d");
+ clientsChart = new Chart(ctx, {
type: "line",
data: {
labels: [],