Aggiunta pagina con device per orario
This commit is contained in:
parent
e6a20299e0
commit
4a53471e88
|
@ -87,3 +87,106 @@ function number_format(number, decimals, dec_point, thousands_sep) {
|
||||||
}
|
}
|
||||||
return s.join(dec);
|
return s.join(dec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a helper to format timestamp data
|
||||||
|
Date.prototype.formatMMDDYYYY = function() {
|
||||||
|
return (this.getMonth() + 1) +
|
||||||
|
"/" + this.getDate() +
|
||||||
|
"/" + this.getFullYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawLineChart( id, resource ) {
|
||||||
|
$.post( reader_url, { op: resource }, function(response){
|
||||||
|
response = $.parseJSON(response);
|
||||||
|
|
||||||
|
// Split timestamp and data into separate arrays
|
||||||
|
var labels = [], data=[]
|
||||||
|
for( i=0; i<response.records.length; i++ ){
|
||||||
|
result = response.records[i];
|
||||||
|
|
||||||
|
labels.push(result.indice);
|
||||||
|
data.push(parseInt(result.valore));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the chart.js data structure using 'labels' and 'data'
|
||||||
|
var full_chart_data = {
|
||||||
|
labels : labels,
|
||||||
|
datasets : [{
|
||||||
|
fillColor : "rgba(151,187,205,0.2)",
|
||||||
|
strokeColor : "rgba(151,187,205,1)",
|
||||||
|
pointColor : "rgba(151,187,205,1)",
|
||||||
|
pointStrokeColor : "#fff",
|
||||||
|
pointHighlightFill : "#fff",
|
||||||
|
pointHighlightStroke : "rgba(151,187,205,1)",
|
||||||
|
backgroundColor : "#4e73df",
|
||||||
|
hoverBackgroundColor : "#2e59d9",
|
||||||
|
borderColor : "#4e73df",
|
||||||
|
data : data
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the context of the canvas element we want to select
|
||||||
|
var ctx = document.getElementById(id).getContext("2d");
|
||||||
|
|
||||||
|
new Chart(ctx, {
|
||||||
|
type: 'bar',
|
||||||
|
data: full_chart_data,
|
||||||
|
options: {
|
||||||
|
maintainAspectRatio: false,
|
||||||
|
layout: {
|
||||||
|
padding: {
|
||||||
|
left: 10,
|
||||||
|
right: 25,
|
||||||
|
top: 25,
|
||||||
|
bottom: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
gridLines: {
|
||||||
|
display: false,
|
||||||
|
drawBorder: false
|
||||||
|
},
|
||||||
|
ticks: {
|
||||||
|
maxTicksLimit: 6
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
ticks: {
|
||||||
|
min: 0,
|
||||||
|
maxTicksLimit: 5,
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
|
gridLines: {
|
||||||
|
color: "rgb(234, 236, 244)",
|
||||||
|
zeroLineColor: "rgb(234, 236, 244)",
|
||||||
|
drawBorder: false,
|
||||||
|
borderDash: [2],
|
||||||
|
zeroLineBorderDash: [2]
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
},
|
||||||
|
tooltips: {
|
||||||
|
titleMarginBottom: 10,
|
||||||
|
titleFontColor: '#6e707e',
|
||||||
|
titleFontSize: 14,
|
||||||
|
backgroundColor: "rgb(255,255,255)",
|
||||||
|
bodyFontColor: "#858796",
|
||||||
|
borderColor: '#dddfeb',
|
||||||
|
borderWidth: 1,
|
||||||
|
displayColors: true,
|
||||||
|
caretPadding: 10,
|
||||||
|
callbacks: {
|
||||||
|
label: function(tooltipItem, chart) {
|
||||||
|
var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
|
||||||
|
return tooltipItem.yLabel + ' devices';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
117
gui/orari.php
117
gui/orari.php
|
@ -8,20 +8,16 @@ include('parts/header.php');
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Content Row -->
|
<!-- Dispositivi per orario -->
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
<!-- Lista dispositivi -->
|
|
||||||
<div class="col-lg-9">
|
|
||||||
<div class="card shadow mb-4">
|
<div class="card shadow mb-4">
|
||||||
<div class="card-header py-3">
|
<div class="card-header py-3">
|
||||||
<h6 class="m-0 font-weight-bold text-primary">Dispositivi per orario</h6>
|
<h6 class="m-0 font-weight-bold text-primary">Dispositivi per orario</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="chart-bar">
|
<div class="chart-bar">
|
||||||
<canvas id="chart-giorni"></canvas>
|
<canvas id="chart-orari"></canvas>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -29,96 +25,29 @@ include('parts/header.php');
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Dispositivi per giorno -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card shadow mb-4">
|
||||||
|
<div class="card-header py-3">
|
||||||
|
<h6 class="m-0 font-weight-bold text-primary">Dispositivi per giorno</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="chart-bar">
|
||||||
|
<canvas id="chart-giorno"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$('#menu-orari').addClass('active');
|
$('#menu-orari').addClass('active');
|
||||||
|
|
||||||
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
drawLineChart( 'chart-orari', 'get-devices-by-hour' );
|
||||||
Chart.defaults.global.defaultFontColor = '#858796';
|
drawLineChart( 'chart-giorno', 'get-devices-by-weekday' );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Bar Chart Example
|
|
||||||
var ctx = document.getElementById("chart-giorni");
|
|
||||||
var myBarChart = new Chart(ctx, {
|
|
||||||
type: 'bar',
|
|
||||||
data: {
|
|
||||||
labels: ["January", "February", "March", "April", "May", "June"],
|
|
||||||
datasets: [{
|
|
||||||
label: "Revenue",
|
|
||||||
backgroundColor: "#4e73df",
|
|
||||||
hoverBackgroundColor: "#2e59d9",
|
|
||||||
borderColor: "#4e73df",
|
|
||||||
data: [4215, 5312, 6251, 7841, 9821, 14984],
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
layout: {
|
|
||||||
padding: {
|
|
||||||
left: 10,
|
|
||||||
right: 25,
|
|
||||||
top: 25,
|
|
||||||
bottom: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
xAxes: [{
|
|
||||||
time: {
|
|
||||||
unit: 'month'
|
|
||||||
},
|
|
||||||
gridLines: {
|
|
||||||
display: false,
|
|
||||||
drawBorder: false
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
maxTicksLimit: 6
|
|
||||||
},
|
|
||||||
maxBarThickness: 25,
|
|
||||||
}],
|
|
||||||
yAxes: [{
|
|
||||||
ticks: {
|
|
||||||
min: 0,
|
|
||||||
max: 15000,
|
|
||||||
maxTicksLimit: 5,
|
|
||||||
padding: 10,
|
|
||||||
// Include a dollar sign in the ticks
|
|
||||||
callback: function(value, index, values) {
|
|
||||||
return '$' + number_format(value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
gridLines: {
|
|
||||||
color: "rgb(234, 236, 244)",
|
|
||||||
zeroLineColor: "rgb(234, 236, 244)",
|
|
||||||
drawBorder: false,
|
|
||||||
borderDash: [2],
|
|
||||||
zeroLineBorderDash: [2]
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
display: false
|
|
||||||
},
|
|
||||||
tooltips: {
|
|
||||||
titleMarginBottom: 10,
|
|
||||||
titleFontColor: '#6e707e',
|
|
||||||
titleFontSize: 14,
|
|
||||||
backgroundColor: "rgb(255,255,255)",
|
|
||||||
bodyFontColor: "#858796",
|
|
||||||
borderColor: '#dddfeb',
|
|
||||||
borderWidth: 1,
|
|
||||||
xPadding: 15,
|
|
||||||
yPadding: 15,
|
|
||||||
displayColors: false,
|
|
||||||
caretPadding: 10,
|
|
||||||
callbacks: {
|
|
||||||
label: function(tooltipItem, chart) {
|
|
||||||
var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
|
|
||||||
return datasetLabel + ': $' + number_format(tooltipItem.yLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
119
ws/reader.php
119
ws/reader.php
|
@ -148,4 +148,123 @@ switch( $_POST['op'] ){
|
||||||
$mysqli->close();
|
$mysqli->close();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 'get-devices-by-hour':
|
||||||
|
// Connessione al database
|
||||||
|
$mysqli = mysqli_connect($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);
|
||||||
|
|
||||||
|
// Errore nella connessione a database
|
||||||
|
if (mysqli_connect_errno($mysqli)) {
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'status' => 'ERR',
|
||||||
|
'message' => mysqli_connect_error(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Lettura numero di device unico nell'intervallo di date
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
CONCAT( DATE_FORMAT(received_at, '%H'), ':00' ) AS indice,
|
||||||
|
COUNT(DISTINCT(mac)) AS valore
|
||||||
|
FROM
|
||||||
|
`logs`
|
||||||
|
GROUP BY
|
||||||
|
DATE_FORMAT(received_at, '%H')";
|
||||||
|
|
||||||
|
$stmt = $mysqli->prepare($sql);
|
||||||
|
|
||||||
|
// Errore nella preparazione query
|
||||||
|
if (!$stmt) {
|
||||||
|
$result = [
|
||||||
|
'status' => 'ERR',
|
||||||
|
'message' => $mysqli->error,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Esecuzione statement
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$rs = $stmt->get_result();
|
||||||
|
|
||||||
|
while ($row = $rs->fetch_assoc()) {
|
||||||
|
$records[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'status' => 'OK',
|
||||||
|
'records' => $records,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($result);
|
||||||
|
|
||||||
|
$stmt->close();
|
||||||
|
$mysqli->close();
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 'get-devices-by-weekday':
|
||||||
|
$weekdays = [
|
||||||
|
0 => 'domenica',
|
||||||
|
1 => 'lunedì',
|
||||||
|
2 => 'martedì',
|
||||||
|
3 => 'mercoledì',
|
||||||
|
4 => 'giovedì',
|
||||||
|
5 => 'venerdì',
|
||||||
|
6 => 'sabato',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Connessione al database
|
||||||
|
$mysqli = mysqli_connect($config['db_host'], $config['db_user'], $config['db_pass'], $config['db_name']);
|
||||||
|
|
||||||
|
// Errore nella connessione a database
|
||||||
|
if (mysqli_connect_errno($mysqli)) {
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'status' => 'ERR',
|
||||||
|
'message' => mysqli_connect_error(),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Lettura numero di device unico nell'intervallo di date
|
||||||
|
$sql = "
|
||||||
|
SELECT
|
||||||
|
DATE_FORMAT(received_at, '%w') AS indice,
|
||||||
|
COUNT(DISTINCT(mac)) AS valore
|
||||||
|
FROM
|
||||||
|
`logs`
|
||||||
|
GROUP BY
|
||||||
|
DATE_FORMAT(received_at, '%w')";
|
||||||
|
|
||||||
|
$stmt = $mysqli->prepare($sql);
|
||||||
|
|
||||||
|
// Errore nella preparazione query
|
||||||
|
if (!$stmt) {
|
||||||
|
$result = [
|
||||||
|
'status' => 'ERR',
|
||||||
|
'message' => $mysqli->error,
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Esecuzione statement
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$rs = $stmt->get_result();
|
||||||
|
|
||||||
|
while ($row = $rs->fetch_assoc()) {
|
||||||
|
$row['indice'] = $weekdays[ $row['indice'] ];
|
||||||
|
$records[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'status' => 'OK',
|
||||||
|
'records' => $records,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($result);
|
||||||
|
|
||||||
|
$stmt->close();
|
||||||
|
$mysqli->close();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue