Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change over-time graphs from line to stacked bar representation #1098

Merged
merged 3 commits into from Dec 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 0 additions & 7 deletions api_db.php
Expand Up @@ -382,13 +382,6 @@ function parseDBData($results, $interval, $from, $until) {
// $data[timestamp] = value_in_this_interval
$data[$row[0]] = intval($row[1]);
}

// Fill the missing intervals with zero
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With bar graphs, we do not need to fill gaps (there will simply be gaps for empty days). This change enhances processing speed notably.

// Advance in steps of interval
for($i = $from; $i < $until; $i += $interval) {
if(!array_key_exists($i, $data))
$data[$i] = 0;
}
}

return $data;
Expand Down
4 changes: 2 additions & 2 deletions index.php
Expand Up @@ -82,7 +82,7 @@ function getinterval()
<div class="col-md-12">
<div class="box" id="queries-over-time">
<div class="box-header with-border">
<h3 class="box-title">Queries over last <?php echo getinterval(); ?> hours</h3>
<h3 class="box-title">Total queries over last <?php echo getinterval(); ?> hours</h3>
</div>
<div class="box-body">
<div class="chart">
Expand All @@ -107,7 +107,7 @@ function getinterval()
<div class="col-md-12">
<div class="box" id="clients">
<div class="box-header with-border">
<h3 class="box-title">Clients (over time)</h3>
<h3 class="box-title">Client activity over last <?php echo getinterval(); ?> hours</h3>
</div>
<div class="box-body">
<div class="chart">
Expand Down
100 changes: 73 additions & 27 deletions scripts/pi-hole/js/db_graph.js
Expand Up @@ -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");

Expand Down Expand Up @@ -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;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable controls how many lines will be computed. I don't think we need to make it user-defined, however, I put it in a common place so users can still modify it when they deem it appropriate. We could also make it a global variable, users could then modify this value (live) through the developer tools.

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);
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
}
Expand All @@ -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)
Expand All @@ -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
}
Expand Down
91 changes: 17 additions & 74 deletions scripts/pi-hole/js/index.js
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
}
]
},
Expand Down Expand Up @@ -785,6 +785,7 @@ $(document).ready(function() {
scales: {
xAxes: [{
type: "time",
stacked: true,
time: {
unit: "hour",
displayFormats: {
Expand All @@ -794,6 +795,7 @@ $(document).ready(function() {
}
}],
yAxes: [{
stacked: true,
ticks: {
beginAtZero: true
}
Expand All @@ -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: [] }]
Expand Down Expand Up @@ -907,6 +849,7 @@ $(document).ready(function() {
scales: {
xAxes: [{
type: "time",
stacked: true,
time: {
unit: "hour",
displayFormats: {
Expand Down