update main graphs, live properties
This commit is contained in:
parent
1b5fa033f8
commit
4ef2fe7735
74
server.js
74
server.js
@ -50,6 +50,10 @@ async function index(req, res) {
|
|||||||
User: "Тестовое Имя",
|
User: "Тестовое Имя",
|
||||||
ifDBError: false,
|
ifDBError: false,
|
||||||
Count: "",
|
Count: "",
|
||||||
|
AlarmsLast11Days: new Array(11).fill(0),
|
||||||
|
Alarms11DaysBefore: new Array(11).fill(0),
|
||||||
|
Dates: [],
|
||||||
|
PositionsLast11Days: new Array(11).fill(0),
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const pool = new Pool({
|
const pool = new Pool({
|
||||||
@ -69,7 +73,67 @@ async function index(req, res) {
|
|||||||
|
|
||||||
templateData.Count = registrars.rows[0].count;
|
templateData.Count = registrars.rows[0].count;
|
||||||
|
|
||||||
console.log(templateData);
|
const last11DaysQuery = `
|
||||||
|
SELECT COUNT(DISTINCT evtuuid) AS count
|
||||||
|
FROM alarms
|
||||||
|
WHERE time >= NOW() - INTERVAL '10 days' + INTERVAL '3 hours'
|
||||||
|
AND time <= NOW() + INTERVAL '1 day' + INTERVAL '3 hours'
|
||||||
|
AND st IS NOT NULL
|
||||||
|
GROUP BY DATE_TRUNC('day', time)
|
||||||
|
ORDER BY DATE_TRUNC('day', time)
|
||||||
|
`;
|
||||||
|
const last11DaysAlarms = await client.query(last11DaysQuery);
|
||||||
|
const last11DaysCounts = last11DaysAlarms.rows.map(row => parseInt(row.count, 10));
|
||||||
|
for (let i = 0; i < last11DaysCounts.length; i++) {
|
||||||
|
if (last11DaysCounts[i] > 0) {
|
||||||
|
templateData.AlarmsLast11Days[i] = last11DaysCounts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const daysBeforeQuery = `
|
||||||
|
SELECT COUNT(DISTINCT evtuuid) AS count
|
||||||
|
FROM alarms
|
||||||
|
WHERE time >= NOW() - INTERVAL '21 days' + INTERVAL '3 hours'
|
||||||
|
AND time <= NOW() - INTERVAL '10 days' + INTERVAL '3 hours'
|
||||||
|
AND st IS NOT NULL
|
||||||
|
GROUP BY DATE_TRUNC('day', time)
|
||||||
|
ORDER BY DATE_TRUNC('day', time)
|
||||||
|
`;
|
||||||
|
const daysBeforeAlarms = await client.query(daysBeforeQuery);
|
||||||
|
const daysBeforeCounts = daysBeforeAlarms.rows.map(row => parseInt(row.count, 10));
|
||||||
|
for (let i = 0; i < daysBeforeCounts.length; i++) {
|
||||||
|
if (daysBeforeCounts[i] > 0) {
|
||||||
|
templateData.Alarms11DaysBefore[i] = daysBeforeCounts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создание массива дат в формате "dd.mm" за последние 11 дней
|
||||||
|
const currentDate = new Date();
|
||||||
|
const dates = [];
|
||||||
|
for (let i = 10; i >= 0; i--) {
|
||||||
|
const date = new Date(currentDate - i * 24 * 60 * 60 * 1000);
|
||||||
|
const formattedDate = date.toLocaleDateString('ru-RU', { day: '2-digit', month: '2-digit' });
|
||||||
|
dates.push(formattedDate);
|
||||||
|
}
|
||||||
|
templateData.Dates = dates;
|
||||||
|
|
||||||
|
const positionsLast11DaysQuery = `
|
||||||
|
SELECT COUNT(*) AS count
|
||||||
|
FROM geo
|
||||||
|
WHERE time >= NOW() - INTERVAL '10 days' + INTERVAL '3 hours'
|
||||||
|
AND time <= NOW() + INTERVAL '1 day' + INTERVAL '3 hours'
|
||||||
|
GROUP BY DATE_TRUNC('day', time)
|
||||||
|
ORDER BY DATE_TRUNC('day', time)
|
||||||
|
`;
|
||||||
|
const positionsLast11Days = await client.query(positionsLast11DaysQuery);
|
||||||
|
const positionsLast11DaysCounts = positionsLast11Days.rows.map(row => parseInt(row.count, 10));
|
||||||
|
for (let i = 0; i < positionsLast11DaysCounts.length; i++) {
|
||||||
|
if (positionsLast11DaysCounts[i] > 0) {
|
||||||
|
templateData.PositionsLast11Days[i] = positionsLast11DaysCounts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(templateData);
|
||||||
|
|
||||||
const source = fs.readFileSync("static/templates/index.html", "utf8");
|
const source = fs.readFileSync("static/templates/index.html", "utf8");
|
||||||
|
|
||||||
@ -87,6 +151,7 @@ async function index(req, res) {
|
|||||||
res.send(resultT);
|
res.send(resultT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function login(req, res) {
|
function login(req, res) {
|
||||||
res.sendFile(path.join(__dirname, "static/templates/login.html"));
|
res.sendFile(path.join(__dirname, "static/templates/login.html"));
|
||||||
}
|
}
|
||||||
@ -309,7 +374,7 @@ app.post("/devices-geo", async (req, res) => {
|
|||||||
.map((_, index) => `$${index + 1}`)
|
.map((_, index) => `$${index + 1}`)
|
||||||
.join(",");
|
.join(",");
|
||||||
const subquery = `
|
const subquery = `
|
||||||
SELECT g.serial, g.longitude, g.latitude, g.direction, g.speed, r.lastkeepalive
|
SELECT g.serial, g.longitude, g.latitude, g.direction, g.speed, r.lastkeepalive, r.plate, r.group
|
||||||
FROM geo g
|
FROM geo g
|
||||||
INNER JOIN (
|
INNER JOIN (
|
||||||
SELECT serial, MAX(time) AS time
|
SELECT serial, MAX(time) AS time
|
||||||
@ -340,12 +405,17 @@ pool.query(subquery, selectedDevices, (err, result) => {
|
|||||||
direction: row.direction,
|
direction: row.direction,
|
||||||
speed: row.speed,
|
speed: row.speed,
|
||||||
status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis,
|
status: Date.now() - Date.parse(row.lastkeepalive) <= minuteInMillis,
|
||||||
|
plate: row.plate,
|
||||||
|
group: row.group,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
console.log(devicesData)
|
||||||
|
|
||||||
res.json({ devicesData });
|
res.json({ devicesData });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
async function reports(req, res) {
|
async function reports(req, res) {
|
||||||
let templateData = {
|
let templateData = {
|
||||||
Organisation: "Название организации",
|
Organisation: "Название организации",
|
||||||
|
@ -2,40 +2,7 @@ Chart.defaults.color = "rgba(0, 0, 0, 0.4)";
|
|||||||
Chart.defaults.font.size = 15;
|
Chart.defaults.font.size = 15;
|
||||||
Chart.defaults.font.weight = 400;
|
Chart.defaults.font.weight = 400;
|
||||||
|
|
||||||
var warningsData = {
|
|
||||||
labels: [
|
|
||||||
"9.03",
|
|
||||||
"10.03",
|
|
||||||
"11.03",
|
|
||||||
"12.03",
|
|
||||||
"13.03",
|
|
||||||
"14.03",
|
|
||||||
"15.03",
|
|
||||||
"16.03",
|
|
||||||
"17.03",
|
|
||||||
"18.03",
|
|
||||||
"19.03",
|
|
||||||
],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Актуальный период",
|
|
||||||
backgroundColor: "rgba(235, 146, 139, 1)",
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 9,
|
|
||||||
hoverBackgroundColor: "rgba(235, 146, 139, 0.8)",
|
|
||||||
data: [1150, 1400, 2100, 900, 1200, 400, 950, 1400, 1250, 1150, 1650],
|
|
||||||
grouped: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "Предыдущий период",
|
|
||||||
backgroundColor: "rgba(235, 146, 139, 0.5)",
|
|
||||||
borderWidth: 0,
|
|
||||||
borderRadius: 9,
|
|
||||||
hoverBackgroundColor: "rgba(235, 146, 139, 0.3)",
|
|
||||||
data: [2700, 1850, 1100, 1550, 2300, 2200, 1650, 1200, 1500, 1850, 800],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
var warningsOptions = {
|
var warningsOptions = {
|
||||||
plugins: {
|
plugins: {
|
||||||
@ -66,36 +33,7 @@ new Chart("chart-warnings", {
|
|||||||
data: warningsData,
|
data: warningsData,
|
||||||
});
|
});
|
||||||
|
|
||||||
var positionsData = {
|
|
||||||
labels: [
|
|
||||||
"9.03",
|
|
||||||
"10.03",
|
|
||||||
"11.03",
|
|
||||||
"12.03",
|
|
||||||
"13.03",
|
|
||||||
"14.03",
|
|
||||||
"15.03",
|
|
||||||
"16.03",
|
|
||||||
"17.03",
|
|
||||||
"18.03",
|
|
||||||
"19.03",
|
|
||||||
],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: "Позиционирование",
|
|
||||||
borderColor: "#8086F9",
|
|
||||||
fill: false,
|
|
||||||
data: [
|
|
||||||
480000, 390000, 407000, 400000, 435000, 460000, 385000, 410000, 380000,
|
|
||||||
410000, 410000,
|
|
||||||
],
|
|
||||||
pointStyle: false,
|
|
||||||
pointRadius: 25,
|
|
||||||
pointHoverRadius: 25,
|
|
||||||
tension: 0.4,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
var positionsOptions = {
|
var positionsOptions = {
|
||||||
plugins: {
|
plugins: {
|
||||||
@ -114,7 +52,7 @@ var positionsOptions = {
|
|||||||
color: "#D9D9D9",
|
color: "#D9D9D9",
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
stepSize: 50000,
|
stepSize: 10000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
x: {
|
x: {
|
||||||
|
@ -1627,6 +1627,41 @@ video {
|
|||||||
border-radius: 29px;
|
border-radius: 29px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.properties {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 50%;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: white;
|
||||||
|
padding: 9px 11px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.properties .propert {
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.properties .propert:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.properties .propert h1 {
|
||||||
|
color: rgba(0, 0, 0, 0.95);
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0 0 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.properties .propert h2 {
|
||||||
|
color: rgba(0, 0, 0, 0.65);
|
||||||
|
font-size: 11px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.marker-name {
|
.marker-name {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: white;
|
background: white;
|
||||||
|
@ -86,6 +86,57 @@
|
|||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var warningsData = {
|
||||||
|
labels: [
|
||||||
|
{{#each Dates}}
|
||||||
|
'{{this}}',
|
||||||
|
{{/each}}
|
||||||
|
],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Актуальный период",
|
||||||
|
backgroundColor: "rgba(235, 146, 139, 1)",
|
||||||
|
borderWidth: 0,
|
||||||
|
borderRadius: 9,
|
||||||
|
hoverBackgroundColor: "rgba(235, 146, 139, 0.8)",
|
||||||
|
data: [{{AlarmsLast11Days}}],
|
||||||
|
grouped: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Предыдущий период",
|
||||||
|
backgroundColor: "rgba(235, 146, 139, 0.5)",
|
||||||
|
borderWidth: 0,
|
||||||
|
borderRadius: 9,
|
||||||
|
hoverBackgroundColor: "rgba(235, 146, 139, 0.3)",
|
||||||
|
data: [{{Alarms11DaysBefore}}],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
var positionsData = {
|
||||||
|
labels: [
|
||||||
|
{{#each Dates}}
|
||||||
|
'{{this}}',
|
||||||
|
{{/each}}
|
||||||
|
],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Позиционирование",
|
||||||
|
borderColor: "#8086F9",
|
||||||
|
fill: false,
|
||||||
|
data: [
|
||||||
|
{{PositionsLast11Days}}
|
||||||
|
],
|
||||||
|
pointStyle: false,
|
||||||
|
pointRadius: 25,
|
||||||
|
pointHoverRadius: 25,
|
||||||
|
tension: 0.4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="../scripts/graphs.js"></script>
|
<script src="../scripts/graphs.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
@ -157,6 +157,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="map">
|
<div class="map">
|
||||||
|
<div id="properties" class="properties" style="display: none;">
|
||||||
|
<div class="propert"><h1>Группа</h1><br><h2 id="propert-group">Автобусы</h2></div>
|
||||||
|
<div class="propert"><h1>Скорость</h1><br><h2 id="propert-speed"> км/ч</h2></div>
|
||||||
|
<div class="propert"><h1>Номерной знак</h1><br><h2 id="propert-plate"></h2></div>
|
||||||
|
<div class="propert"><h1>Геопозиция</h1><br><h2 id="propert-geo"></h2></div>
|
||||||
|
</div>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -418,9 +424,35 @@
|
|||||||
data.devicesData.forEach(device => {
|
data.devicesData.forEach(device => {
|
||||||
addMarker(device);
|
addMarker(device);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Поиск устройства с выбранным серийным номером
|
||||||
|
const selectedDevice = data.devicesData.find(device => device.serial === $("input[name=camera-serial]:checked").val());
|
||||||
|
|
||||||
|
// Получение ссылок на элементы для заполнения данных
|
||||||
|
const groupElement = document.getElementById('propert-group');
|
||||||
|
const speedElement = document.getElementById('propert-speed');
|
||||||
|
const plateElement = document.getElementById('propert-plate');
|
||||||
|
const geoElement = document.getElementById('propert-geo');
|
||||||
|
|
||||||
|
const propertiesDiv = document.getElementById('properties');
|
||||||
|
|
||||||
|
if (selectedDevice) {
|
||||||
|
// Вывод нужных свойств устройства в консоль
|
||||||
|
// groupElement.textContent = selectedDevice.group;
|
||||||
|
speedElement.textContent = selectedDevice.speed + ' км/ч';
|
||||||
|
plateElement.textContent = selectedDevice.plate;
|
||||||
|
geoElement.textContent = `${selectedDevice.latitude.toFixed(6)}, ${selectedDevice.longitude.toFixed(6)}`;
|
||||||
|
|
||||||
|
propertiesDiv.style.display = 'inline-flex';
|
||||||
|
} else {
|
||||||
|
console.log('Устройство с выбранным серийным номером не найдено.');
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Ошибка при получении данных:', error);
|
console.error('Ошибка при получении данных:', error);
|
||||||
|
|
||||||
|
const propertiesDiv = document.getElementById('properties');
|
||||||
|
propertiesDiv.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user