diff --git a/api_db.php b/api_db.php index a8309a2e..a0247402 100644 --- a/api_db.php +++ b/api_db.php @@ -372,13 +372,6 @@ if (isset($_GET['getGraphData']) && $auth) // $data[timestamp] = value_in_this_interval $data[$row[0]] = intval($row[1]); } - - // Fill the missing intervals with zero - // Advance in steps of interval - for($i = $from; $i < $until; $i += $interval) { - if(!array_key_exists($i, $data)) - $data[$i] = 0; - } } return $data; diff --git a/index.php b/index.php index a75e77ab..78c1a464 100644 --- a/index.php +++ b/index.php @@ -82,7 +82,7 @@
-

Queries over last hours

+

Total queries over last hours

@@ -107,7 +107,7 @@
-

Clients (over time)

+

Client activity over last hours

diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index 422179e8..0ce616d6 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -11,6 +11,7 @@ var start__ = moment().subtract(6, "days"); var from = moment(start__).utc().valueOf()/1000; var end__ = moment(); var until = moment(end__).utc().valueOf()/1000; +var interval = 0; var timeoutWarning = $("#timeoutWarning"); @@ -71,7 +72,35 @@ function compareNumbers(a, b) { function updateQueriesOverTime() { $("#queries-over-time .overlay").show(); timeoutWarning.show(); - $.getJSON("api_db.php?getGraphData&from="+from+"&until="+until, function(data) { + + // Compute interval to obtain about 200 values + var num = 200; + interval = (until-from)/num; + // Default displaying axis scaling + timeLineChart.options.scales.xAxes[0].time.unit="hour" + + if(num*interval >= 6*29*24*60*60) + { + // If the requested data is more than 3 months, set ticks interval to quarterly + timeLineChart.options.scales.xAxes[0].time.unit="quarter" + } + else if(num*interval >= 3*29*24*60*60) + { + // If the requested data is more than 3 months, set ticks interval to months + timeLineChart.options.scales.xAxes[0].time.unit="month" + } + if(num*interval >= 29*24*60*60) + { + // If the requested data is more than 1 month, set ticks interval to weeks + timeLineChart.options.scales.xAxes[0].time.unit="week" + } + else if(num*interval >= 6*24*60*60) + { + // If the requested data is more than 1 week, set ticks interval to days + timeLineChart.options.scales.xAxes[0].time.unit="day" + } + + $.getJSON("api_db.php?getGraphData&from="+from+"&until="+until+"&interval="+interval, function(data) { // convert received objects to arrays data.domains_over_time = objectToArray(data.domains_over_time); @@ -103,8 +132,8 @@ function updateQueriesOverTime() { // Add data for each hour that is available for (hour in dates) { if (Object.prototype.hasOwnProperty.call(dates, hour)) { - var d, dom = 0, ads = 0; - d = new Date(1000*dates[hour]); + var date, dom = 0, ads = 0; + date = new Date(1000*dates[hour]); var idx = data.domains_over_time[0].indexOf(dates[hour].toString()); if (idx > -1) @@ -118,8 +147,8 @@ function updateQueriesOverTime() { ads = data.ads_over_time[1][idx]; } - timeLineChart.data.labels.push(d); - timeLineChart.data.datasets[0].data.push(dom); + timeLineChart.data.labels.push(date); + timeLineChart.data.datasets[0].data.push(dom - ads); timeLineChart.data.datasets[1].data.push(ads); } } @@ -134,51 +163,66 @@ function updateQueriesOverTime() { $(document).ready(function() { var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); timeLineChart = new Chart(ctx, { - type: "line", + type: "bar", data: { - labels: [ 0 ], + labels: [ ], datasets: [ { - label: "Total DNS Queries", + label: "Permitted DNS Queries", fill: true, - backgroundColor: "rgba(220,220,220,0.5)", + backgroundColor: "rgba(0, 166, 90,.8)", borderColor: "rgba(0, 166, 90,.8)", pointBorderColor: "rgba(0, 166, 90,.8)", pointRadius: 1, pointHoverRadius: 5, data: [], - pointHitRadius: 5, - cubicInterpolationMode: "monotone" + pointHitRadius: 5 }, { label: "Blocked DNS Queries", fill: true, - backgroundColor: "rgba(0,192,239,0.5)", + backgroundColor: "rgba(0,192,239,1)", borderColor: "rgba(0,192,239,1)", pointBorderColor: "rgba(0,192,239,1)", pointRadius: 1, pointHoverRadius: 5, data: [], - pointHitRadius: 5, - cubicInterpolationMode: "monotone" + pointHitRadius: 5 } ] }, options: { tooltips: { enabled: true, - responsive: true, mode: "x-axis", callbacks: { title: function(tooltipItem) { var label = tooltipItem[0].xLabel; var time = new Date(label); - var date = time.getFullYear()+"-"+padNumber(time.getMonth()+1)+"-"+padNumber(time.getDate()); - var h = time.getHours(); - var m = time.getMinutes(); - var from = padNumber(h)+":"+padNumber(m)+":00"; - var to = padNumber(h)+":"+padNumber(m+9)+":59"; - return "Queries from "+from+" to "+to+" on "+date; + var from_date = time.getFullYear() + + "-" + + padNumber(time.getMonth()+1) + + "-" + + padNumber(time.getDate()) + + " " + + padNumber(time.getHours()) + + ":" + + padNumber(time.getMinutes()) + + ":" + + padNumber(time.getSeconds()); + time = new Date(time.valueOf() + 1000 * interval); + var until_date = time.getFullYear() + + "-" + + padNumber(time.getMonth()+1) + + "-" + + padNumber(time.getDate()) + + " " + + padNumber(time.getHours()) + + ":" + + padNumber(time.getMinutes()) + + ":" + + padNumber(time.getSeconds()); + return "Queries from " + from_date + " to " + until_date; }, label: function(tooltipItems, data) { if(tooltipItems.datasetIndex === 1) @@ -203,20 +247,22 @@ $(document).ready(function() { scales: { xAxes: [{ type: "time", - display: false, + stacked: true, time: { + unit: "hour", displayFormats: { "minute": "HH:mm", "hour": "HH:mm", - "day": "HH:mm", - "week": "MMM DD HH:mm", - "month": "MMM DD", - "quarter": "MMM DD", - "year": "MMM DD" + "day": "MMM DD", + "week": "MMM DD", + "month": "MMM", + "quarter": "MMM", + "year": "YYYY MMM" } } }], yAxes: [{ + stacked: true, ticks: { beginAtZero: true } diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 18b1773b..969e6cdc 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -7,8 +7,8 @@ // Define global variables /* global Chart:false, updateSessionTimer:false */ -var timeLineChart, forwardDestinationChart; -var queryTypePieChart, forwardDestinationPieChart, clientsChart; +var timeLineChart, clientsChart; +var queryTypePieChart, forwardDestinationPieChart; function padNumber(num) { return ("00" + num).substr(-2,2); @@ -166,8 +166,10 @@ function updateQueriesOverTime() { } timeLineChart.data.labels.push(d); - timeLineChart.data.datasets[0].data.push(data.domains_over_time[1][hour]); - timeLineChart.data.datasets[1].data.push(data.ads_over_time[1][hour]); + var blocked = data.ads_over_time[1][hour]; + var permitted = data.domains_over_time[1][hour] - blocked; + timeLineChart.data.datasets[0].data.push(permitted); + timeLineChart.data.datasets[1].data.push(blocked); } } $("#queries-over-time .overlay").hide(); @@ -718,33 +720,31 @@ $(document).ready(function() { var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); timeLineChart = new Chart(ctx, { - type: "line", + type: "bar", data: { - labels: [], + labels: [ ], datasets: [ { - label: "Total DNS Queries", + label: "Permitted DNS Queries", fill: true, - backgroundColor: "rgba(220,220,220,0.5)", + backgroundColor: "rgba(0, 166, 90,.8)", borderColor: "rgba(0, 166, 90,.8)", pointBorderColor: "rgba(0, 166, 90,.8)", pointRadius: 1, pointHoverRadius: 5, data: [], - pointHitRadius: 5, - cubicInterpolationMode: "monotone" + pointHitRadius: 5 }, { label: "Blocked DNS Queries", fill: true, - backgroundColor: "rgba(0,192,239,0.5)", + backgroundColor: "rgba(0,192,239,1)", borderColor: "rgba(0,192,239,1)", pointBorderColor: "rgba(0,192,239,1)", pointRadius: 1, pointHoverRadius: 5, data: [], - pointHitRadius: 5, - cubicInterpolationMode: "monotone" + pointHitRadius: 5 } ] }, @@ -785,6 +785,7 @@ $(document).ready(function() { scales: { xAxes: [{ type: "time", + stacked: true, time: { unit: "hour", displayFormats: { @@ -794,6 +795,7 @@ $(document).ready(function() { } }], yAxes: [{ + stacked: true, ticks: { beginAtZero: true } @@ -807,73 +809,13 @@ $(document).ready(function() { updateQueriesOverTime(); - // Create / load "Forward Destinations over Time" only if authorized - if(document.getElementById("forwardDestinationChart")) - { - 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) { - 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 "Forward destinations 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) { - return Math.round(value*100) + " %"; - } - }, - stacked: true - }] - }, - maintainAspectRatio: true - } - }); - } - // Create / load "Top Clients over Time" only if authorized var clientsChartEl = document.getElementById("clientsChart"); if(clientsChartEl) { ctx = clientsChartEl.getContext("2d"); clientsChart = new Chart(ctx, { - type: "line", + type: "bar", data: { labels: [], datasets: [{ data: [] }] @@ -907,6 +849,7 @@ $(document).ready(function() { scales: { xAxes: [{ type: "time", + stacked: true, time: { unit: "hour", displayFormats: {