Przejdź do głównej zawartości

Wizualizacje

Wizualizacje w Overvis Cloud to niestandardowe, interaktywne strony (HTML/SVG/JavaScript), które pokazują bieżący stan urządzeń i umożliwiają zdalne sterowanie. To ta sama funkcja, którą w aplikacji oznaczono jako Wizualizacje. Overvis sam zapewnia łączność z urządzeniami, zbieranie danych i obsługę alarmów; wizualizacje dają natomiast swobodę w prezentacji tych informacji dokładnie tak, jak tego potrzebujesz.

Demo wizualizacji

Wizualizacje to kod HTML/SVG/JavaScript osadzony na stronach Overvis. Wygląd przygotowujesz w dowolnym edytorze grafiki wektorowej, eksportujesz go jako SVG, a następnie dodajesz specjalne atrybuty, które wiążą elementy grafiki z danymi z urządzeń na żywo.

Silnik wizualizacji:

  1. Ładuje Twój kod HTML/SVG i wstawia go na wybraną stronę
  2. Zbiera wszystkie powiązania danych z kodu źródłowego
  3. Odczytuje dane z podłączonych urządzeń zgodnie z powiązaniami
  4. Aktualizuje elementy wizualne wartościami na żywo
  5. Odświeża automatycznie co 10 sekund (interwał ustawia atrybut update-period-sec)
  6. Obsługuje interakcje użytkownika, takie jak edycja parametrów lub przełączniki

Zanim zaczniesz budować wizualizacje, upewnij się, że masz potrzebne narzędzia i środowisko.

  • Urządzenia powinny być już podłączone do Overvis
  • Zainstaluj edytor grafiki wektorowej z eksportem do SVG (Affinity Designer, Inkscape, Adobe Illustrator, Sketch lub SVG-Edit)
  • Użyj edytora tekstu obsługującego edycję SVG/XML (VS Code, Notepad++, Atom lub Sublime Text)
  • Podstawowa znajomość struktury SVG jest pomocna (w razie potrzeby zobacz tutorial SVG)

Ten rozdział poprowadzi Cię od otwarcia edytora do wyświetlenia prostego przykładu.

Przejdź do strony wizualizacji w menu Overvis. Jeśli nie masz jeszcze żadnej wizualizacji, lista będzie pusta.

Strona wizualizacji

Kliknij Stworzyć wizualizację, aby otworzyć edytor:

Stworzyć wizualizację

Edytor ma dwa główne pola:

  • Kod źródłowy (SVG/HTML) — Twój kod HTML/SVG/JavaScript
  • Pokaż na stronie — Która strona ma pokazywać tę wizualizację

Zacznijmy od prostego przykładu, żeby zrozumieć działanie:

Wpisany kod HTML lub SVG jest wyświetlany bez zmian.<br /><br />
Na przykład <b>ten tekst będzie pogrubiony.</b><br /><br />
Poniżej prosty obraz SVG z czerwonym kwadratem:<br />
<svg width="100px" height="100px" viewBox="0 0 100 100">
<rect fill="#FF0000" height="100" width="100" x="0" y="0" />
</svg>

Tworzenie prostej wizualizacji

Po kliknięciu „Stwórz wizualizację” zobaczysz:

Prosta wizualizacja

Możesz nawet dodać ją do Przeglądu w Overvis:

Prosta wizualizacja w Przeglądzie

Ta wizualizacja jest statyczna. Aby wyświetlić rzeczywiste dane urządzenia, musisz użyć powiązań danych — specjalnych atrybutów HTML/SVG łączących elementy wizualne z parametrami urządzenia.

Ten samouczek prowadzi przez utworzenie pełnej wizualizacji do monitorowania urządzeń chłodniczych. Dowiesz się, jak wyświetlać temperatury na żywo, dodać interaktywne sterowanie nastawami, wskaźniki alarmów i przełączniki.

Efekt końcowy

Utwórz projekt wizualizacji w edytorze grafiki wektorowej. W tym przykładzie zrobimy rzut pomieszczenia magazynowego z agregatami chłodniczymi pokazującymi:

  • Rzut pomieszczenia
  • Wyświetlacze temperatury dla każdej lodówki
  • Sterowanie nastawami
  • Wskaźniki alarmów
  • Licznik energii
  • Przełącznik trybu odrośniania
  • Wskaźnik stanu drzwi

Rysowanie grafiki wizualizacji

Projektując wizualizację, stosuj się do tych zasad:

Używaj wartości zastępczych. Wstaw reprezentatywne wartości zastępcze dla wszystkich danych dynamicznych. Dla temperatur ujemnych z jednym miejscem po przecinku użyj „-12.3”. Ułatwia to układ i pozycjonowanie podczas projektowania.

Oddziel elementy dynamiczne od statycznych. Wartości dynamiczne i etykiety statyczne zachowaj jako osobne obiekty tekstowe. Na przykład „-12.3” i „°C” powinny być osobnymi obiektami, aby na żywo podmieniać wyłącznie liczbę.

Tekst zostaw jako tekst. Nie zamieniaj dynamicznych elementów tekstowych na krzywe ani ścieżki. Tekst statyczny można przekonwertować, aby zmniejszyć rozmiar pliku, ale elementy dynamiczne muszą pozostać edytowalnym tekstem.

Używaj kompatybilnych czcionek. Trzymaj się czcionek bezpiecznych dla sieci (Arial, Times New Roman, Courier) lub użyj Droid Sans, które Overvis dostarcza do wszystkich wizualizacji. Własne czcionki wymagają dodatkowej konfiguracji CSS.

Ułóż wszystko od razu. Narysuj wszystkie elementy w docelowych pozycjach, także te początkowo ukryte (np. wskaźniki alarmów w stanie aktywnym i normalnym lub przełączniki w obu pozycjach włącz/wyłącz).

Nazwij warstwy opisowo. Używaj czytelnych nazw warstw w edytorze. Te nazwy często stają się identyfikatorami elementów w SVG, co ułatwia znajdowanie konkretnych elementów przy dodawaniu powiązań danych.

Nazewnictwo warstw

Eksportuj projekt jako SVG z ustawieniami zachowującymi możliwość edycji:

  • Wyłącz kompresję lub minifikację
  • Zachowaj nazwy warstw i identyfikatory
  • Nie zamieniaj tekstu na krzywe/ścieżki
  • Użyj profilu formatu z najwyższą dostępnością w ustawieniach eksportu

Ustawienia eksportu

Po eksporcie otwórz plik SVG w edytorze tekstu i usuń na początku deklarację XML oraz znaczniki DOCTYPE:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

Te znaczniki trzeba usunąć, ponieważ SVG będzie osadzone bezpośrednio w stronie HTML.

Skopiuj oczyszczony kod SVG do edytora wizualizacji Overvis i zapisz:

Pierwsze wgranie wersji statycznej

Zobacz wynik, aby upewnić się, że grafika wyświetla się poprawnie:

Wyświetlona wersja statyczna

Na tym etapie wizualizacja jest tylko grafiką bez danych na żywo. Kolejne kroki dodadzą powiązania danych.

Potrzebujesz adresu MAC kontrolera sieci i adresów urządzeń, aby utworzyć powiązania danych. Znajdziesz je w ustawieniach sieci:

Urządzenia w przykładowej sieci

Ustawienia przykładowej sieci

W tym przykładzie adres MAC sieci to 11-22-33-44-55-66. Zanotuj adresy wszystkich urządzeń, z których będziesz wyświetlać dane.

Mając statyczną wizualizację, możesz połączyć ją z danymi na żywo, edytując kod SVG i dodając specjalne atrybuty.

Aby wyświetlić wartość parametru urządzenia jako tekst, dodaj atrybut param-value do elementu tekstowego. Na przykład, aby pokazać temperaturę z czujnika sterownika lodówki:

Znajdź element tekstowy w kodzie SVG (szukaj nazw warstw ustawionych wcześniej):

Odczyt temperatury lodówki na pojedynczym elemencie wyświetlacza

Zmodyfikuj znacznik <text>:

<text x="75.403px" y="102.037px"
style="font-family:'DroidSans', 'Droid Sans', sans-serif;font-size:30px;fill:rgb(0,197,255);"
param-value="11-22-33-44-55-66>1>101:r">-</text>

Format atrybutu param-value to: MAC>DEVICE_ADDRESS>PARAMETER_ADDRESS:OPTIONS

  • 11-22-33-44-55-66 — adres MAC kontrolera sieci
  • 1 — adres urządzenia w sieci
  • 101 — adres parametru (rejestr holdingowy)
  • :r — odczyt bezpośrednio z urządzenia (czas rzeczywisty). Pomiń, aby użyć ostatniej wartości z pamięci podręcznej bazy danych.
  • :p{{number}} — wyświetlanie z podaną precyzją (np. :p3 dla 3 miejsc po przecinku)

Zamień tekst zastępczy na myślnik lub inny tymczasowy znak widoczny do momentu załadowania danych.

Po zaktualizowaniu wszystkich wyświetlaczy temperatury wizualizacja pokazuje dane na żywo:

Wartości temperatury lodówki online na kilku elementach

Dane odświeżają się automatycznie co 10 sekund; użytkownik może też kliknąć ikonę odświeżenia, aby zaktualizować natychmiast.

Aby użytkownicy mogli zmieniać parametry urządzenia klikając wartości, połącz param-value z on-click:

Sterowanie nastawą lodówki

Zmodyfikuj element tekstowy nastawy:

<text x="135.373px" y="142.406px"
style="font-family:'DroidSans', 'Droid Sans', sans-serif;font-size:16px;fill:rgb(37,182,255);cursor:pointer;"
param-value="11-22-33-44-55-66>1>201:r"
on-click="edit-param:11-22-33-44-55-66>1>201">-</text>

Atrybut on-click="edit-param:..." po kliknięciu otwiera okno dialogowe do wprowadzenia nowej wartości. Po zapisaniu Overvis zapisuje wartość do urządzenia i odświeża wizualizację.

Wartość temperatury lodówki

Dodanie cursor:pointer do stylu zmienia kursor tak, by wskazywał, że element można kliknąć.

Użyj on-param-value, aby pokazywać lub ukrywać elementy w zależności od wartości parametru. Sprawdza się to np. przy wskaźnikach alarmów, które mają być widoczne dopiero po wystąpieniu alarmu:

Obraz alertu

Znajdź grupę wskaźnika alarmu w SVG:

Kod wskaźnika alarmu

Zmodyfikuj kontener <g>:

<g id="alarm3" serif:id="alarm"
on-param-value="11-22-33-44-55-66>1>1d:=1:display:block:none:r"
style="display:none;">

Format atrybutu on-param-value to: PARAM_REF:CONDITION:PROPERTY:VALUE_ON:VALUE_OFF:OPTIONS

  • 11-22-33-44-55-66>1>1d — referencja parametru (wejście dyskretne 1d)
  • :=1 — warunek (równa się 1)
  • :display — modyfikowana właściwość stylu
  • :block — wartość gdy warunek prawdziwy (pokaż element)
  • :none — wartość gdy warunek fałszywy (ukryj element)
  • :r — odczyt bezpośrednio z urządzenia w czasie rzeczywistym

Ustaw domyślnie style="display:none;", aby element był początkowo ukryty. Gdy parametr wynosi 1, styl display zmienia się na block, co czyni wskaźnik widocznym.

Działające alarmy

Ta sama technika on-param-value działa przy zmianie kolorów elementów. Na przykład drzwi w kolorze czerwonym, gdy są otwarte:

<rect id="door" x="464.852" y="365.301" width="5.254" height="78.242"
style="fill:none;stroke:grey;stroke-width:2px;"
on-param-value="11-22-33-44-55-66>11>500.2:=0:stroke:red:green:r" />

Odczytywany jest bit 2 rejestru 500 z urządzenia 11. Przy wartości 0 (drzwi otwarte) obrys jest czerwony, przy 1 (drzwi zamknięte) — zielony.

Drzwi otwarte

Połącz on-param-value z on-click dla przełączników. Zaprojektuj oba stany przełącznika, a następnie pokazuj jeden lub drugi w zależności od bieżącej wartości:

<g style="cursor:pointer;" on-click="toggle-param:11-22-33-44-55-66>20>105:0:1:g">
<g id="button-on" serif:id="button on"
on-param-value="11-22-33-44-55-66>20>105:=1:display:block:none:r"
style="display:none;">
<path d="M680.921,544.957c0,-8.316 -6.751,-15.067 -15.066,-15.067l-24.005,0c-8.315,0 -15.066,6.751 -15.066,15.067c0,8.315 6.751,15.066 15.066,15.066l24.005,0c8.315,0 15.066,-6.751 15.066,-15.066Z" style="fill:rgb(29,214,255);"/>
<circle cx="666.032" cy="544.957" r="11.536" style="fill:white;"/>
<text x="633.575px" y="549.415px" style="font-family:'DroidSans', 'Droid Sans', sans-serif;font-size:11.449px;fill:white;">ON</text>
</g>
<g id="button-off" serif:id="button off"
on-param-value="11-22-33-44-55-66>20>105:=0:display:block:none:r"
style="display:none;">
<path d="M680.921,544.957c0,-8.316 -6.751,-15.067 -15.066,-15.067l-24.005,0c-8.315,0 -15.066,6.751 -15.066,15.067c0,8.315 6.751,15.066 15.066,15.066l24.005,0c8.315,0 15.066,-6.751 15.066,-15.066Z" style="fill:rgb(134,134,134);"/>
<circle cx="641.703" cy="544.957" r="11.536" style="fill:white;"/>
<text x="655.519px" y="549.415px" style="font-family:'DroidSans', 'Droid Sans', sans-serif;font-size:11.449px;fill:white;">OFF</text>
</g>
</g>

Każdy stan ma on-param-value, który go pokazuje, gdy parametr pasuje (:=1 dla ON, :=0 dla OFF). Grupa nadrzędna ma on-click="toggle-param:PARAM_REF:DEFAULT_VALUE:VALUE_ON:OPTIONS", co przełącza parametr między 0 i 1 po kliknięciu. Opcja :g na końcu odświeża wszystkie dane wizualizacji po zmianie.

Przełącznik wyłączony Przełącznik włączony

Aby użytkownicy mogli edytować etykiety lub nazwy nieprzechowywane w rejestrach urządzenia, użyj własnej pamięci wizualizacji w bazie. Najpierw włącz tę funkcję, dodając atrybut do głównego znacznika <svg>:

<svg use-vis-data="yes" ...>

Następnie oznacz elementy tekstowe, które mają być edytowalne i zapisywane:

<text id="small-room-name" serif:id="small room name"
x="45.195px" y="550.539px"
style="font-family:'DroidSans', 'Droid Sans', sans-serif;font-size:36px;fill:rgb(211,211,211);"
text-replacement="small-room-name"
on-click="edit-visdata:small-room-name">Rental Storage Room</text>

Atrybut text-replacement określa klucz zapisu. Początkowa treść tekstu staje się wartością domyślną. Po kliknięciu elementu (przez on-click="edit-visdata:...") użytkownik może edytować i zapisać nową wartość, która trafia do bazy i tam pozostaje.

Zmiana nazwy pomieszczenia

Dokończ wizualizację, dodając pozostałe powiązania danych. Dla licznika energii wyświetl wartość z bazy zamiast odczytu bezpośrednio z urządzenia:

<text id="value" x="508.542px" y="502.132px"
style="font-family:'DroidSans', 'Droid Sans', sans-serif;font-size:30px;fill:rgb(23,23,23);"
param-value="11-22-33-44-55-66>10>1000">-</text>

Zwróć uwagę, że nie ma flagi :r. Odczytywana jest ostatnia wartość z bazy (aktualizowana co 5 minut), a nie bezpośrednie odpytywanie urządzenia. To zmniejsza obciążenie sieci dla wartości, które nie wymagają aktualizacji w czasie rzeczywistym.

Ukończona wizualizacja pokazuje dane urządzeń na żywo, umożliwia interakcję i aktualizuje się automatycznie:

Wynikowa wizualizacja

Zachowanie wizualizacji ustawisz, dodając atrybuty do pierwszego znacznika <svg> lub dowolnego znacznika z klasą vis-settings:

<svg update-period-sec="5" refresh-button="yes" use-vis-data="no">
<!-- Your visualization content -->
</svg>

Dostępne ustawienia:

  • update-period-sec="{{number}}" — okres odświeżania w sekundach (domyślnie: 10). Ustaw 0, aby odświeżać natychmiast po zakończeniu każdego cyklu.
  • refresh-button="yes|no" — pokaż/ukryj przycisk odświeżania w lewym górnym rogu (domyślnie: yes).
  • use-vis-data="yes|no" — włącz ładowanie danych tabeli tekstów wizualizacji (domyślnie: no).

Domyślnie param-value odczytuje ostatnią zapisaną wartość z bazy. Dodaj opcję :r, aby odczytać bezpośrednio z urządzenia w czasie rzeczywistym. Wybierz według potrzeb:

Używaj odczytu z bazy (bez opcji :r), gdy:

  • Wartość zmienia się rzadko
  • Dokładne dane w czasie rzeczywistym nie są krytyczne
  • Chcesz zmniejszyć ruch sieciowy i przyspieszyć odświeżanie
  • Wiele wizualizacji pokazuje te same dane
  • Parametr jest śledzony w systemie

Używaj odczytu w czasie rzeczywistym (opcja :r), gdy:

  • Potrzebujesz absolutnie aktualnej wartości
  • Parametr zmienia się często
  • Interakcje użytkownika zależą od natychmiastowej informacji zwrotnej
  • Wyświetlasz stany sterowania, które użytkownik właśnie zmienił
  • Parametr nie jest śledzony w systemie

Jeśli nie można pobrać wartości parametru, wyświetlane są specjalne kody błędów:

  • NON — sieć parametru nie istnieje
  • NOP — parametr nie istnieje
  • NOLR — brak ostatniego odczytu w bazie (parametr nigdy nie był odczytany lub nie jest śledzony)
  • NOPR — nie rozwiązano parametru dla tego powiązania czasu rzeczywistego (błędna referencja)
  • NORV — odczyt w czasie rzeczywistym nie zwrócił wartości (błąd urządzenia, limit czasu lub brak ok w odpowiedzi operatora)

Te kody pomagają diagnozować problemy z powiązaniami danych i łącznością urządzeń.

Atrybut on-click obsługuje te akcje:

  • goto:param:{{paramRef}} — otwórz historię parametru
  • goto:params:{{paramRef}},{{paramRef}},... — otwórz porównanie wielu parametrów
  • goto:device:{{deviceRef}} — otwórz stronę listy parametrów urządzenia
  • goto:network:{{networkRef}} — otwórz stronę sieci
  • goto:vis:{{visualizationRef}} — otwórz inną wizualizację
  • toggle-param:{{paramRef}}:{{defaultValue}}:{{valueOn}}:{{options}} — przełącz parametr między dwoma wartościami
  • edit-param:{{paramRef}}:{{options}} — otwórz okno edycji wartości parametru
  • increment-param:{{paramRef}}:{{amount}}:{{options}} — zwiększ wartość parametru o podaną wielkość (może być ujemna)
  • edit-visdata:{{key}} — otwórz okno edycji tekstu wizualizacji

Opcję :g można dodać do dowolnej akcji, aby po zakończeniu odświeżyć wszystkie dane wizualizacji.

Oprócz czcionek bezpiecznych dla sieci i Droid Sans domyślnie możesz dodać własne czcionki przez wbudowany CSS:

<style>
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap");
</style>
<svg>
<text style="font-family:'Roboto', sans-serif;">Custom Font Text</text>
</svg>

Dostosuj wizualizacje do różnych rozmiarów ekranu, używając rozmiarów procentowych i atrybutu preserveAspectRatio:

<svg width="100%" height="100%" viewBox="0 0 800 600" preserveAspectRatio="xMidYMid meet">
<!-- Your content -->
</svg>

Gdy wyświetlasz wiele alarmów jednocześnie, utwórz osobne elementy wskaźników dla każdego typu alarmu i rozmieść je tak, aby się nie nakładały. Użyj osobnych powiązań on-param-value dla każdego. W złożonych scenariuszach rozważ JavaScript do dynamicznego pozycjonowania wskaźników.

Choć powiązania danych obsługują większość typowych przypadków, możesz użyć JavaScriptu do zaawansowanych funkcji. Wizualizacje działają w kontekście strony Overvis, co daje dostęp do pełnego API przeglądarki i funkcji specyficznych dla Overvis.

Aby wykonywać uwierzytelnione wywołania API z wizualizacji, musisz dołączyć token sesji. Token jest przechowywany w pamięci przeglądarki i dostępny przez JavaScript.

Użyj funkcji preInitViz(), aby wykonać kod przed inicjalizacją wizualizacji. Przydaje się do pobierania danych z API lub konfiguracji własnej logiki:

<script>
window.preInitViz = function (callback) {
// Get the authentication token from session storage
const token = sessionStorage.getItem("auth_token");
// Fetch data from Overvis API
fetch("https://ocp.overvis.com/api/v1/org/1/nets/", {
headers: {
"Content-Type": "application/json",
Authorization: "token " + token,
},
})
.then((response) => response.json())
.then((data) => {
console.log("Networks:", data);
// Process the data and update your visualization
document.getElementById("network-count").textContent = data.length;
// Always call the callback when done
callback();
})
.catch((error) => {
console.error("API error:", error);
callback();
});
};
</script>
<div>Total networks: <span id="network-count">Loading...</span></div>

Funkcja onVizUpdate() jest wywoływana przy każdym odświeżeniu wizualizacji z nowymi danymi:

<script>
window.onVizUpdate = function (data) {
// data contains all parameter values from data bindings
console.log("Visualization updated with data:", data);
// Perform custom calculations or transformations
const temp1 = parseFloat(data["12-34-56-78-90-ab>1>101"]);
const temp2 = parseFloat(data["12-34-56-78-90-ab>1>102"]);
const average = (temp1 + temp2) / 2;
// Update custom elements
document.getElementById("avg-temp").textContent = average.toFixed(1);
};
</script>
<div>Average temperature: <span id="avg-temp">-</span>°C</div>

Użyj funkcji writeParamValue(), aby wysyłać wartości do urządzeń z JavaScriptu:

<script>
function setSetpoint(value) {
writeParamValue(
"12-34-56-78-90-ab>1>201", // Parameter reference
value.toString(), // Value as string
function (result) {
// Callback
if (result.ok) {
console.log("Write successful:", result);
} else {
console.error("Write failed:", result.err);
}
},
true, // Refresh all visualization data after write
);
}
</script>
<button onclick="setSetpoint(18)">Set to 18°C</button>
<button onclick="setSetpoint(20)">Set to 20°C</button>
<button onclick="setSetpoint(22)">Set to 22°C</button>

Aby wyświetlać wykresy lub analizować trendy, pobierz historyczne odczyty z API:

<script>
window.preInitViz = function (callback) {
const token = sessionStorage.getItem("auth_token");
// Request dispersed readings for charting
fetch("https://ocp.overvis.com/api/v1/readings/dispersed/", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "token " + token,
},
body: JSON.stringify({
paramIds: [547, 545], // Parameter system IDs
from: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), // Last 24 hours
till: new Date().toISOString(),
points: 100, // 100 data points
}),
})
.then((response) => response.json())
.then((data) => {
console.log("Historical data:", data);
// Use data to render a chart
renderChart(data);
callback();
})
.catch((error) => {
console.error("Error fetching data:", error);
callback();
});
};
function renderChart(data) {
// Implement chart rendering logic here
// Can use libraries like Chart.js, D3.js, etc.
}
</script>

Możesz osadzić interaktywne mapy Google, aby pokazywać lokalizacje urządzeń ze wskaźnikami stanu w czasie rzeczywistym.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
<div id="map" style="height: 600px;"></div>
<!-- Hidden divs for data binding -->
<div style="display:none;">
<div id="net1-conn" on-net-connection="aa-bb-cc-dd-ee-ff:opacity:1:0"></div>
<div id="net1-relay" param-value="aa-bb-cc-dd-ee-ff>111>160.0:r"></div>
<div id="net1-alarm" param-value="aa-bb-cc-dd-ee-ff>1>240.0:r"></div>
</div>
<script>
// Define marker locations and network references
const locations = [
{
lat: 40.7128,
lng: -74.006,
label: "Location 1",
netKey: "net1",
netMac: "aa-bb-cc-dd-ee-ff",
url: "/manage/network/location-1/",
},
// Add more locations...
];
let map,
markers = [];
window.preInitViz = function (callback) {
// Initialize map
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 40.7128, lng: -74.006 },
zoom: 13,
});
// Create markers
locations.forEach((loc) => {
const marker = new google.maps.Marker({
position: { lat: loc.lat, lng: loc.lng },
map: map,
title: loc.label,
label: loc.label,
});
marker.addListener("click", () => {
window.location.href = loc.url;
});
markers.push({ marker, netKey: loc.netKey });
});
callback();
};
window.onVizUpdate = function (data) {
markers.forEach((m) => {
const connected = parseInt(
data[`conn?${locations.find((l) => l.netKey === m.netKey).netMac}`],
);
const relay = parseInt(
data[`${locations.find((l) => l.netKey === m.netKey).netMac}>111>160.0:r`],
);
const alarm = parseInt(
data[`${locations.find((l) => l.netKey === m.netKey).netMac}>1>240.0:r`],
);
// Update marker color based on status
let icon = null;
if (alarm === 1) {
icon = "http://maps.google.com/mapfiles/ms/icons/red-dot.png";
} else if (relay === 1) {
icon = "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png";
} else if (connected === 1) {
icon = "http://maps.google.com/mapfiles/ms/icons/green-dot.png";
} else {
icon = "http://maps.google.com/mapfiles/ms/icons/grey-dot.png";
}
m.marker.setIcon(icon);
});
};
</script>

Przykład używa kolorowych znaczników:

  • Czerwony: alarm aktywny
  • Żółty: urządzenie pracuje (przekaźnik włączony)
  • Zielony: połączone, normalna praca
  • Szary: rozłączone

Możesz dostosować wygląd znaczników własnymi ikonami, grafiką SVG lub API personalizacji znaczników Google Maps.

Wizualizacja się nie aktualizuje

Sprawdź, czy interwał odświeżania jest poprawnie ustawiony, czy adresy parametrów zgadzają się z konfiguracją urządzeń oraz czy urządzenia są online i odpowiadają. W konsoli deweloperskiej przeglądarki (F12) zobaczysz ewentualne błędy JavaScriptu.

Dane pokazują kody błędów (NOLR, NOPR, NORV itd.)

  • NOLR (No Last Reading) — parametr nigdy nie był odczytany lub nie jest śledzony. Zaznacz „Śledzone” w ustawieniach parametru urządzenia lub dodaj opcję :r dla odczytów w czasie rzeczywistym.
  • NOPR (No Parameter for realtime) — nie udało się rozwiązać parametru dla slotu czasu rzeczywistego. Sprawdź, czy referencja parametru w wizualizacji jest prawidłowa.
  • NORV (No realtime value) — odczyt w czasie rzeczywistym nie zwrócił wartości. Sprawdź łączność z urządzeniem i spróbuj odczytać parametr na stronie parametrów urządzenia, aby zobaczyć faktyczny błąd.
  • NON (No Network) — wskazana sieć nie istnieje lub nie masz do niej dostępu.
  • NOP (No Parameter) — wskazany parametr nie istnieje w urządzeniu.

Elementy interaktywne nie działają

Zweryfikuj składnię on-click zgodnie z dokumentacją. Upewnij się, że cursor:pointer jest w atrybucie stylu. Sprawdź, czy inny element nie zasłania klikalnego elementu (kolejność warstw SVG ma znaczenie).

Styl wygląda źle

Upewnij się, że eksport SVG nie zamienił tekstu na krzywe. Używaj stylów wbudowanych w elementach SVG, aby uniknąć konfliktów z CSS strony. Zweryfikuj strukturę SVG narzędziem walidacji SVG.

Odświeżanie jest wolniejsze niż oczekiwane

Jeśli odczytujesz wiele parametrów z opcją :r (odczyty w czasie rzeczywistym), każdy wymaga zapytania do urządzenia. Kolejny cykl odświeżania nie startuje, dopóki poprzedni się nie zakończy. Dla wartości mniej istotnych w czasie rzeczywistym użyj odczytów z bazy (bez :r), aby skrócić czas cyklu odświeżania, lub zwiększ ustawienie update-period-sec.

Czy mogę używać zewnętrznych bibliotek JavaScript, np. Chart.js lub D3.js?

Tak. Dołącz je przez CDN w znaczniku <script> na początku kodu źródłowego wizualizacji. Pamiętaj jednak, że duże biblioteki mogą spowolnić ładowanie strony.

Czy mogę tworzyć wielostronicowe wizualizacje?

Wizualizacje z założenia są jednostronicowe, ale możesz symulować wiele stron używając JavaScriptu do pokazywania/ukrywania sekcji albo utworzyć kilka osobnych wizualizacji i linkować między nimi przez on-click="goto:vis:...".

Jak debugować JavaScript wizualizacji?

Użyj narzędzi deweloperskich przeglądarki (F12). Logi konsoli, punkty przerwania i inspekcja sieci działają normalnie. Sprawdź konsolę pod kątem błędów wywołań API lub powiązań danych.

Czy wizualizacje mogą odczytywać dane z wielu organizacji?

Nie. Każda wizualizacja należy do jednej organizacji i może uzyskiwać dane tylko z sieci i urządzeń w tej organizacji. API wymusza to przez tokeny uwierzytelniania.

Jaka jest różnica między identyfikatorem systemowym parametru a adresem parametru?

Adres parametru to adres rejestru Modbus na urządzeniu (np. 101). Identyfikator systemowy to wewnętrzny identyfikator bazy Overvis dla tego parametru. Używaj adresów w referencjach postaci 12-34-56-78-90-ab>1>101 albo identyfikatorów systemowych z prefiksem #: #1234567.

Czy mogę stylować wizualizacje własnymi frameworkami CSS?

Tak, ale dołącz plik CSS frameworka w <style> lub <link>. Pamiętaj, że strona Overvis ma własne style, które mogą kolidować. Używaj konkretnych selektorów lub stylów wbudowanych, aby uniknąć problemów.

Jak obsługiwać strefy czasowe?

Wszystkie daty z API Overvis są w UTC. Użyj obiektu Date w JavaScript i toLocaleString(), aby przeliczyć na lokalną strefę użytkownika, lub podaj konkretną strefę, jeśli to potrzebne.

Pełne szczegóły techniczne wszystkich dostępnych atrybutów, formatów referencji parametrów i opcji zaawansowanych:

Jeśli potrzebujesz wsparcia przy tworzeniu wizualizacji Overvis, napisz na support@overvis.com. Chętnie pomożemy przy niestandardowych wizualizacjach, odpowiemy na pytania o funkcje zaawansowane lub doprecyzujemy dokumentację.