mirror of
https://github.com/pi-hole/web.git
synced 2026-04-23 02:09:58 +01:00
@@ -1,66 +1,97 @@
|
||||
/* Pi-hole: A black hole for Internet advertisements
|
||||
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
||||
* Network-wide ad blocking via your own hardware.
|
||||
*
|
||||
* This file is copyright under the latest version of the EUPL.
|
||||
* Please see LICENSE file for your rights under this license. */
|
||||
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
|
||||
* Network-wide ad blocking via your own hardware.
|
||||
*
|
||||
* This file is copyright under the latest version of the EUPL.
|
||||
* Please see LICENSE file for your rights under this license. */
|
||||
|
||||
/* global Chart:false, moment:false */
|
||||
|
||||
var start__ = moment().subtract(6, "days");
|
||||
var from = moment(start__).utc().valueOf()/1000;
|
||||
var from =
|
||||
moment(start__)
|
||||
.utc()
|
||||
.valueOf() / 1000;
|
||||
var end__ = moment();
|
||||
var until = moment(end__).utc().valueOf()/1000;
|
||||
var until =
|
||||
moment(end__)
|
||||
.utc()
|
||||
.valueOf() / 1000;
|
||||
var interval = 0;
|
||||
|
||||
var timeoutWarning = $("#timeoutWarning");
|
||||
|
||||
var dateformat = "MMMM Do YYYY, HH:mm";
|
||||
|
||||
$(function () {
|
||||
$("#querytime").daterangepicker(
|
||||
$(function() {
|
||||
$("#querytime").daterangepicker(
|
||||
{
|
||||
timePicker: true, timePickerIncrement: 15,
|
||||
timePicker: true,
|
||||
timePickerIncrement: 15,
|
||||
locale: { format: dateformat },
|
||||
startDate: start__, endDate: end__,
|
||||
startDate: start__,
|
||||
endDate: end__,
|
||||
ranges: {
|
||||
"Today": [moment().startOf("day"), moment()],
|
||||
"Yesterday": [moment().subtract(1, "days").startOf("day"), moment().subtract(1, "days").endOf("day")],
|
||||
Today: [moment().startOf("day"), moment()],
|
||||
Yesterday: [
|
||||
moment()
|
||||
.subtract(1, "days")
|
||||
.startOf("day"),
|
||||
moment()
|
||||
.subtract(1, "days")
|
||||
.endOf("day")
|
||||
],
|
||||
"Last 7 Days": [moment().subtract(6, "days"), moment()],
|
||||
"Last 30 Days": [moment().subtract(29, "days"), moment()],
|
||||
"This Month": [moment().startOf("month"), moment()],
|
||||
"Last Month": [moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month")],
|
||||
"Last Month": [
|
||||
moment()
|
||||
.subtract(1, "month")
|
||||
.startOf("month"),
|
||||
moment()
|
||||
.subtract(1, "month")
|
||||
.endOf("month")
|
||||
],
|
||||
"This Year": [moment().startOf("year"), moment()],
|
||||
"All Time": [moment(0), moment()]
|
||||
},
|
||||
"opens": "center", "showDropdowns": true,
|
||||
"autoUpdateInput": false
|
||||
opens: "center",
|
||||
showDropdowns: true,
|
||||
autoUpdateInput: false
|
||||
},
|
||||
function (startt, endt) {
|
||||
from = moment(startt).utc().valueOf()/1000;
|
||||
until = moment(endt).utc().valueOf()/1000;
|
||||
});
|
||||
|
||||
function(startt, endt) {
|
||||
from =
|
||||
moment(startt)
|
||||
.utc()
|
||||
.valueOf() / 1000;
|
||||
until =
|
||||
moment(endt)
|
||||
.utc()
|
||||
.valueOf() / 1000;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function padNumber(num) {
|
||||
return ("00" + num).substr(-2,2);
|
||||
return ("00" + num).substr(-2, 2);
|
||||
}
|
||||
|
||||
// Helper function needed for converting the Objects to Arrays
|
||||
|
||||
function objectToArray(p){
|
||||
var keys = Object.keys(p);
|
||||
keys.sort(function(a, b) {
|
||||
return a - b;
|
||||
});
|
||||
function objectToArray(p) {
|
||||
var keys = Object.keys(p);
|
||||
keys.sort(function(a, b) {
|
||||
return a - b;
|
||||
});
|
||||
|
||||
var arr = [], idx = [];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
arr.push(p[keys[i]]);
|
||||
idx.push(keys[i]);
|
||||
}
|
||||
return [idx,arr];
|
||||
var arr = [],
|
||||
idx = [];
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
arr.push(p[keys[i]]);
|
||||
idx.push(keys[i]);
|
||||
}
|
||||
|
||||
return [idx, arr];
|
||||
}
|
||||
|
||||
var timeLineChart;
|
||||
@@ -70,229 +101,238 @@ function compareNumbers(a, b) {
|
||||
}
|
||||
|
||||
function updateQueriesOverTime() {
|
||||
$("#queries-over-time .overlay").show();
|
||||
timeoutWarning.show();
|
||||
$("#queries-over-time .overlay").show();
|
||||
timeoutWarning.show();
|
||||
|
||||
// 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"
|
||||
// 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"
|
||||
}
|
||||
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";
|
||||
}
|
||||
|
||||
$.getJSON("api_db.php?getGraphData&from="+from+"&until="+until+"&interval="+interval, function(data) {
|
||||
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";
|
||||
}
|
||||
|
||||
// convert received objects to arrays
|
||||
data.domains_over_time = objectToArray(data.domains_over_time);
|
||||
data.ads_over_time = objectToArray(data.ads_over_time);
|
||||
// Remove possibly already existing data
|
||||
timeLineChart.data.labels = [];
|
||||
timeLineChart.data.datasets[0].data = [];
|
||||
timeLineChart.data.datasets[1].data = [];
|
||||
$.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);
|
||||
data.ads_over_time = objectToArray(data.ads_over_time);
|
||||
// Remove possibly already existing data
|
||||
timeLineChart.data.labels = [];
|
||||
timeLineChart.data.datasets[0].data = [];
|
||||
timeLineChart.data.datasets[1].data = [];
|
||||
|
||||
var dates = [], hour;
|
||||
var dates = [],
|
||||
hour;
|
||||
|
||||
for (hour in data.domains_over_time[0]) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.domains_over_time[0], hour)) {
|
||||
dates.push(parseInt(data.domains_over_time[0][hour]));
|
||||
}
|
||||
for (hour in data.domains_over_time[0]) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.domains_over_time[0], hour)) {
|
||||
dates.push(parseInt(data.domains_over_time[0][hour]));
|
||||
}
|
||||
}
|
||||
|
||||
for (hour in data.ads_over_time[0]) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.ads_over_time[0], hour)) {
|
||||
if(dates.indexOf(parseInt(data.ads_over_time[0][hour])) === -1)
|
||||
{
|
||||
dates.push(parseInt(data.ads_over_time[0][hour]));
|
||||
}
|
||||
}
|
||||
for (hour in data.ads_over_time[0]) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.ads_over_time[0], hour)) {
|
||||
if (dates.indexOf(parseInt(data.ads_over_time[0][hour])) === -1) {
|
||||
dates.push(parseInt(data.ads_over_time[0][hour]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dates.sort(compareNumbers);
|
||||
dates.sort(compareNumbers);
|
||||
|
||||
// Add data for each hour that is available
|
||||
for (hour in dates) {
|
||||
if (Object.prototype.hasOwnProperty.call(dates, hour)) {
|
||||
var date, dom = 0, ads = 0;
|
||||
date = new Date(1000*dates[hour]);
|
||||
// Add data for each hour that is available
|
||||
for (hour in dates) {
|
||||
if (Object.prototype.hasOwnProperty.call(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)
|
||||
{
|
||||
dom = data.domains_over_time[1][idx];
|
||||
}
|
||||
var idx = data.domains_over_time[0].indexOf(dates[hour].toString());
|
||||
if (idx > -1) {
|
||||
dom = data.domains_over_time[1][idx];
|
||||
}
|
||||
|
||||
idx = data.ads_over_time[0].indexOf(dates[hour].toString());
|
||||
if (idx > -1)
|
||||
{
|
||||
ads = data.ads_over_time[1][idx];
|
||||
}
|
||||
idx = data.ads_over_time[0].indexOf(dates[hour].toString());
|
||||
if (idx > -1) {
|
||||
ads = data.ads_over_time[1][idx];
|
||||
}
|
||||
|
||||
timeLineChart.data.labels.push(date);
|
||||
timeLineChart.data.datasets[0].data.push(dom - ads);
|
||||
timeLineChart.data.datasets[1].data.push(ads);
|
||||
}
|
||||
timeLineChart.data.labels.push(date);
|
||||
timeLineChart.data.datasets[0].data.push(dom - ads);
|
||||
timeLineChart.data.datasets[1].data.push(ads);
|
||||
}
|
||||
}
|
||||
|
||||
timeLineChart.options.scales.xAxes[0].display=true;
|
||||
$("#queries-over-time .overlay").hide();
|
||||
timeoutWarning.hide();
|
||||
timeLineChart.update();
|
||||
});
|
||||
timeLineChart.options.scales.xAxes[0].display = true;
|
||||
$("#queries-over-time .overlay").hide();
|
||||
timeoutWarning.hide();
|
||||
timeLineChart.update();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
var ctx = document.getElementById("queryOverTimeChart").getContext("2d");
|
||||
timeLineChart = new Chart(ctx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: [ ],
|
||||
datasets: [
|
||||
{
|
||||
label: "Permitted DNS Queries",
|
||||
fill: true,
|
||||
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
|
||||
},
|
||||
{
|
||||
label: "Blocked DNS Queries",
|
||||
fill: true,
|
||||
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
|
||||
}
|
||||
]
|
||||
var ctx = document.getElementById("queryOverTimeChart").getContext("2d");
|
||||
timeLineChart = new Chart(ctx, {
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [
|
||||
{
|
||||
label: "Permitted DNS Queries",
|
||||
fill: true,
|
||||
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
|
||||
},
|
||||
options: {
|
||||
tooltips: {
|
||||
enabled: true,
|
||||
mode: "x-axis",
|
||||
callbacks: {
|
||||
title: function(tooltipItem) {
|
||||
var label = tooltipItem[0].xLabel;
|
||||
var time = new Date(label);
|
||||
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)
|
||||
{
|
||||
var percentage = 0.0;
|
||||
var total = parseInt(data.datasets[0].data[tooltipItems.index]);
|
||||
var blocked = parseInt(data.datasets[1].data[tooltipItems.index]);
|
||||
if(total > 0)
|
||||
{
|
||||
percentage = 100.0*blocked/total;
|
||||
}
|
||||
return data.datasets[tooltipItems.datasetIndex].label + ": " + tooltipItems.yLabel + " (" + percentage.toFixed(1) + "%)";
|
||||
}
|
||||
|
||||
return data.datasets[tooltipItems.datasetIndex].label + ": " + tooltipItems.yLabel;
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
type: "time",
|
||||
stacked: true,
|
||||
time: {
|
||||
unit: "hour",
|
||||
displayFormats: {
|
||||
"minute": "HH:mm",
|
||||
"hour": "HH:mm",
|
||||
"day": "MMM DD",
|
||||
"week": "MMM DD",
|
||||
"month": "MMM",
|
||||
"quarter": "MMM",
|
||||
"year": "YYYY MMM"
|
||||
}
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
},
|
||||
maintainAspectRatio: false
|
||||
{
|
||||
label: "Blocked DNS Queries",
|
||||
fill: true,
|
||||
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
|
||||
}
|
||||
});
|
||||
]
|
||||
},
|
||||
options: {
|
||||
tooltips: {
|
||||
enabled: true,
|
||||
mode: "x-axis",
|
||||
callbacks: {
|
||||
title: function(tooltipItem) {
|
||||
var label = tooltipItem[0].xLabel;
|
||||
var time = new Date(label);
|
||||
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) {
|
||||
var percentage = 0.0;
|
||||
var total = parseInt(data.datasets[0].data[tooltipItems.index]);
|
||||
var blocked = parseInt(data.datasets[1].data[tooltipItems.index]);
|
||||
if (total > 0) {
|
||||
percentage = (100.0 * blocked) / total;
|
||||
}
|
||||
|
||||
return (
|
||||
data.datasets[tooltipItems.datasetIndex].label +
|
||||
": " +
|
||||
tooltipItems.yLabel +
|
||||
" (" +
|
||||
percentage.toFixed(1) +
|
||||
"%)"
|
||||
);
|
||||
}
|
||||
|
||||
return data.datasets[tooltipItems.datasetIndex].label + ": " + tooltipItems.yLabel;
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
scales: {
|
||||
xAxes: [
|
||||
{
|
||||
type: "time",
|
||||
stacked: true,
|
||||
time: {
|
||||
unit: "hour",
|
||||
displayFormats: {
|
||||
minute: "HH:mm",
|
||||
hour: "HH:mm",
|
||||
day: "MMM DD",
|
||||
week: "MMM DD",
|
||||
month: "MMM",
|
||||
quarter: "MMM",
|
||||
year: "YYYY MMM"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxes: [
|
||||
{
|
||||
stacked: true,
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
maintainAspectRatio: false
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#querytime").on("apply.daterangepicker", function(ev, picker) {
|
||||
$(this).val(picker.startDate.format(dateformat) + " to " + picker.endDate.format(dateformat));
|
||||
$("#queries-over-time").show();
|
||||
updateQueriesOverTime();
|
||||
$(this).val(picker.startDate.format(dateformat) + " to " + picker.endDate.format(dateformat));
|
||||
$("#queries-over-time").show();
|
||||
updateQueriesOverTime();
|
||||
});
|
||||
|
||||
$("#queryOverTimeChart").click(function(evt){
|
||||
var activePoints = timeLineChart.getElementAtEvent(evt);
|
||||
if(activePoints.length > 0)
|
||||
{
|
||||
//get the internal index in the chart
|
||||
var clickedElementindex = activePoints[0]._index;
|
||||
$("#queryOverTimeChart").click(function(evt) {
|
||||
var activePoints = timeLineChart.getElementAtEvent(evt);
|
||||
if (activePoints.length > 0) {
|
||||
//get the internal index in the chart
|
||||
var clickedElementindex = activePoints[0]._index;
|
||||
|
||||
//get specific label by index
|
||||
var label = timeLineChart.data.labels[clickedElementindex];
|
||||
//get specific label by index
|
||||
var label = timeLineChart.data.labels[clickedElementindex];
|
||||
|
||||
//get value by index
|
||||
var from = label/1000;
|
||||
var until = label/1000 + 600;
|
||||
window.location.href = "db_queries.php?from="+from+"&until="+until;
|
||||
}
|
||||
return false;
|
||||
//get value by index
|
||||
var from = label / 1000;
|
||||
var until = label / 1000 + 600;
|
||||
window.location.href = "db_queries.php?from=" + from + "&until=" + until;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user