Liste im Web zum Laufen gebracht, sieht schon ganz vernünftig aus

This commit is contained in:
Daniel Schick 2023-01-03 13:20:57 +01:00
parent 80b4a39a58
commit 85a3c3e395
4 changed files with 166 additions and 167 deletions

View File

@ -76,7 +76,7 @@ namespace bsmd.AIS2Service
foreach(AlarmAssignmentZone aazone in testDict[mmsi]) { foreach(AlarmAssignmentZone aazone in testDict[mmsi]) {
if(aazone.Zone.IsPointInPolygon4(target.Position)) if(aazone.Zone.IsPointInPolygon4(target.Position))
{ {
_log.InfoFormat("{0} is in zone {1}", target.ToString(), aazone.Zone.Name); _log.DebugFormat("{0} is in zone {1}", target.ToString(), aazone.Zone.Name);
Alarm alarm; Alarm alarm;
if (aazone.Assignment.Alarms.Count > 0) if (aazone.Assignment.Alarms.Count > 0)
{ {

View File

@ -1,22 +1,14 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<link rel="stylesheet" href="DataTables/datatables.css">
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Zonen Übersicht</title> <title>Zonen Übersicht</title>
<script type="text/javascript" src="zonen.js"></script> <script type="text/javascript" src="zonen.js"></script>
<script type="text/javascript" src="DataTables/jQuery-3.6.0/jquery-3.6.0.js"></script>
<script type="text/javascript" src="DataTables/DataTables-1.12.1/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$('#aisTable').DataTable();
});
</script>
</head> </head>
<body onload="startup()"> <body onload="createAreas()">
<div class="table_group" id="root-div" /> <div class="table_group" id="root-div" />
<div id="bottomcenter"> <div id="bottomcenter">
(c) <a href="http://www.textbausteine.net" target="#">Informatikbüro Daniel Schick</a> (c) <a href="http://www.textbausteine.net" target="#">Informatikbüro Daniel Schick</a>

View File

@ -6,127 +6,46 @@
body{ body{
font-family: Helvetica; font-family: Helvetica;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
background: rgba( 71, 147, 227, 1);
}
h2{
text-align: center;
font-size: 18px;
text-transform: uppercase;
letter-spacing: 1px;
color: white;
padding: 30px 0;
} }
/* Table Styles */ .styled-table {
.table-wrapper{
margin: 10px 70px 70px;
box-shadow: 0px 35px 50px rgba( 0, 0, 0, 0.2 );
}
.fl-table {
border-radius: 5px;
font-size: 12px;
font-weight: normal;
border: none;
border-collapse: collapse; border-collapse: collapse;
width: 100%; margin: 25px 0;
max-width: 100%; font-size: 0.9em;
white-space: nowrap; font-family: sans-serif;
background-color: white; min-width: 400px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
} }
.fl-table td, .fl-table th { .styled-table thead tr {
text-align: center; background-color: #009879;
padding: 8px;
}
.fl-table td {
border-right: 1px solid #f8f8f8;
font-size: 12px;
}
.fl-table thead th {
color: #ffffff; color: #ffffff;
background: #4FC3A1;
}
.fl-table thead th:nth-child(odd) {
color: #ffffff;
background: #324960;
}
.fl-table tr:nth-child(even) {
background: #F8F8F8;
}
/* Responsive */
@media (max-width: 767px) {
.fl-table {
display: block;
width: 100%;
}
.table-wrapper:before{
content: "Scroll horizontally >";
display: block;
text-align: right;
font-size: 11px;
color: white;
padding: 0 0 10px;
}
.fl-table thead, .fl-table tbody, .fl-table thead th {
display: block;
}
.fl-table thead th:last-child{
border-bottom: none;
}
.fl-table thead {
float: left;
}
.fl-table tbody {
width: auto;
position: relative;
overflow-x: auto;
}
.fl-table td, .fl-table th {
padding: 20px .625em .625em .625em;
height: 60px;
vertical-align: middle;
box-sizing: border-box;
overflow-x: hidden;
overflow-y: auto;
width: 120px;
font-size: 13px;
text-overflow: ellipsis;
}
.fl-table thead th {
text-align: left; text-align: left;
border-bottom: 1px solid #f7f7f9;
}
.fl-table tbody tr {
display: table-cell;
}
.fl-table tbody tr:nth-child(odd) {
background: none;
}
.fl-table tr:nth-child(even) {
background: transparent;
}
.fl-table tr td:nth-child(odd) {
background: #F8F8F8;
border-right: 1px solid #E6E4E4;
}
.fl-table tr td:nth-child(even) {
border-right: 1px solid #E6E4E4;
}
.fl-table tbody td {
display: block;
text-align: center;
}
} }
.styled-table th,
.styled-table td {
padding: 12px 15px;
}
.styled-table tbody tr {
border-bottom: 1px solid #dddddd;
}
.styled-table tbody tr:nth-of-type(even) {
background-color: #f3f3f3;
}
.styled-table tbody tr:last-of-type {
border-bottom: 2px solid #009879;
}
.styled-table tbody tr.active-row {
font-weight: bold;
color: #009879;
}
#bottomcenter { #bottomcenter {
position: fixed; position: fixed;
left: 50%; left: 50%;

View File

@ -3,72 +3,160 @@
/* startup, load groups from database */ /* startup, load groups from database */
document.addEventListener('DOMContentLoaded', function () { var groupIds = [];
let table = new DataTable('#aisTable', { var groupZones = [];
"ajax" : {
"url" : "http://192.168.2.25:9050/api/ais",
"dataSrc" : "",
"type" : "GET"
},
columns: [
{ data: 'MMSI' },
{ data: 'Name' },
{ data: 'LastUpdate' },
{ data: 'Latitude' },
{ data: 'Longitude' },
{ data: 'IMO' },
{ data: 'IsClassB' }
]
} );
setInterval( function () { async function loadAlarms(groupId)
table.ajax.reload( null, false ); // user paging is not reset on reload {
}, 30000 ); let data;
try {
const res = await fetch('http://localhost:9050/api/slr?id=' + groupId);
data = await res.json();
updateData(data, groupId);
}
catch(error) {
console.error(error);
}
}
} ); function updateData(data, groupId) {
var table = document.getElementById('table-' + groupId);
for (var i = 0; i < data.length; i++) {
let row_id = "row_" + groupId + "_" + data[i].MMSI;
row = document.getElementById(row_id);
if(row == null) { // not found, create new row
row = document.createElement('tr');
row.setAttribute("id", row_id);
// add leading cells
var td1 = document.createElement('td');
//td1.innerHTML = data[i].Name;
row.appendChild(td1);
var td2 = document.createElement('td');
row.appendChild(td2);
var td3 = document.createElement('td');
// td3.innerHTML = data[i].IMO;
row.appendChild(td3);
// create dummy cells for each zone
for(var j = 0; j < groupZones[groupId].length; j++) {
var td = document.createElement('td');
td.id = "cell_" + groupId + "_" + groupZones[groupId][j] + "_" + data[i].MMSI;
row.appendChild(td);
}
// add trailing cells
var td4 = document.createElement('td');
//td4.innerHTML = data[i].NavStatus;
row.appendChild(td4);
var td5 = document.createElement('td');
//td5.innerHTML = data[i].MMSI;
row.appendChild(td5);
var td6 = document.createElement('td');
//td6.innerHTML = data[i].Destination;
row.appendChild(td6);
table.childNodes[1].appendChild(row); // append row to tbody subelement
}
const colCount = row.childNodes.length;
row.childNodes[0].innerHTML = data[i].Name;
// TODO: incoming/outgoing symbol
row.childNodes[2].innerHTML = data[i].IMO;
// find alarm cell and set value
let cellId = "cell_" + groupId + "_" + data[i].MonitorZoneId + "_" + data[i].MMSI;
var cell = document.getElementById(cellId);
if(cell != null) {
const timestamp = Date.parse(data[i].Timestamp_First);
const d = new Date(timestamp);
cell.innerHTML = ("0" + d.getHours()).slice(-2) + ":" + ("0" + d.getMinutes()).slice(-2) + " " + d.getDate() + "." + (d.getMonth() + 1) + "." + ("" + d.getFullYear()).slice(-2);
}
row.childNodes[colCount - 3].innerHTML = data[i].NavStatus;
row.childNodes[colCount - 2].innerHTML = data[i].MMSI;
row.childNodes[colCount - 1].innerHTML = data[i].Destination;
}
// TODO: remove rows (after an interval) that are not in the result set any more
}
function update() { function update() {
fetch('http://192.168.2.25:9050/api/ais')
for(var i = 0; i < groupIds.length; i++)
{
loadAlarms(groupIds[i]);
}
}
function createAreas()
{
fetch('http://localhost:9050/api/zones')
.then(function (response) { .then(function (response) {
return response.json(); return response.json();
}) })
.then(function (data) { .then(function (data) {
updateData(data); createAreasFromData(data);
}) })
.catch(function (err) { .catch(function (err) {
console.log('error: ' + err); console.log('error: ' + err);
}); });
function updateData(data) {
var table = document.getElementById('aisTable'); function createAreasFromData(data)
{
var root_div = document.getElementById('root-div');
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
let row_id = "row_" + data[i].MMSI; groupIds.push(data[i].Id);
row = document.getElementById(row_id); groupZones[data[i].Id] = [];
var aDiv = document.createElement('div');
aDiv.className = '';
aDiv.id = 'group-' + data[i].Id;
aDiv.innerHTML = data[i].Name;
root_div.appendChild(aDiv);
if(row == null) { // not found, create new row // create table header with zones
row = document.createElement('tr'); var aTable = document.createElement('table');
row.setAttribute("id", row_id); aTable.id = 'table-' + data[i].Id;
row.innerHTML = `<td>` + data[i].MMSI + aTable.className = "styled-table";
`</td><td id="name_` + data[i].MMSI + `"/>` + var thead = document.createElement('thead');
`<td id="timestamp_` + data[i].MMSI + `"/>` + aTable.appendChild(thead);
`<td id="lat_` + data[i].MMSI + `"/>` + var tr = document.createElement('tr');
`<td id="lon_` + data[i].MMSI + `"/>` + thead.appendChild(tr);
`<td id="imo_` + data[i].MMSI + `"/>` + var th1 = document.createElement('th');
`<td>` + data[i].IsClassB + `</td>`; th1.innerHTML='Name';
table.appendChild(row); tr.appendChild(th1);
var th2 = document.createElement('th');
th2.innerHTML='E/A';
tr.appendChild(th2);
var th3 = document.createElement('th');
th3.innerHTML='IMO';
tr.appendChild(th3);
for(var j = 0; j < data[i].Zones.length; j++) {
groupZones[data[i].Id].push(data[i].Zones[j].Id);
var aTH = document.createElement('th');
aTH.id = 'zone-' + data[i].Zones[j].Id;
aTH.innerHTML = data[i].Zones[j].Name;
tr.appendChild(aTH);
} }
// update existing row var th4 = document.createElement('th');
var td = document.getElementById("name_" + data[i].MMSI); th4.innerHTML='Nav. status';
td.innerHTML = data[i].Name; tr.appendChild(th4);
td = document.getElementById("timestamp_" + data[i].MMSI); var th5 = document.createElement('th');
td.innerHTML = data[i].LastUpdate; th5.innerHTML='MMSI';
td = document.getElementById("lat_" + data[i].MMSI); tr.appendChild(th5);
td.innerHTML = data[i].Latitude; var th6 = document.createElement('th');
td = document.getElementById("lon_" + data[i].MMSI); th6.innerHTML='Destination';
td.innerHTML = data[i].Longitude; tr.appendChild(th6);
td = document.getElementById("imo_" + data[i].MMSI);
td.innerHTML = data[i].IMO; aTable.appendChild(document.createElement('tbody'));
aDiv.appendChild(aTable);
aDiv.appendChild(document.createElement('hr'));
} }
setInterval(function () { update(); }, 15000);
} }
} }