Forum: PC-Programmierung Statusdisplay / Slideshow in HTML, PHP, Java,?


von Heinz R. (heijz)


Angehängte Dateien:

Lesenswert?

Ich habe eine Haussteuerung, bei der verschiedene Werte visualisiert 
werden.

Es sind 10 verschiedene Seiten, momentan werden diese serverseitig 
generiert,
Hierzu werden die Werte mit ImageMagik in ein bestehendes Foto 
eingefügt.
( Raspberry / simple Bash-Scripte, per Cronjob ausgelöst)

Die fertigen Bilder werden alle 3 min von Tablets abgerufen und dort 
mittels einer Slideshow gezeigt - unten ein paar Beispielbilder.

Will jetzt die ruhige Weihnachtszeit nutzen und das Ganze etwas moderner 
angehen. (In Bezug auf Umsetzung, Design soll so bleiben)

Erste Überlegung ist - ich generiere auf dem Server pro Bild eine 
HTML-Datei mit Foto , Text und Werten, überschreibe die sich 
verändernden Werte wieder mit einem Bash-Script

Es gibt dann eine übergeordnete Seite mit der Slideshow, hierfür gibts 
viele Beispiele im Netz
(Alle die ich bisher gefunden habe können aber nicht direkt beliebigen 
Text an beliebigen Positionen einblenden)

Nur, dann lädt jedes Tablett alle 5 sec jeweils die komplette Seite neu 
vom Server, obwohl sich nur ein paar Werte geändert haben?
Wie hoch wird die Last am Raspberry dadurch?

Wie würdet Ihr hier vorgehen?
Bin aber zugegeben kein Programmierer, kennt jemand gute Beispiele?

Ich brauche keine Touchfunktionalität.

So was wie z.B. hier:
https://blog.moneybag.de/wp-content/uploads/2015/11/tabletui-1-768x465.jpg
will ich ausdrücklich nicht, will beim alten übersichtlichen Konzept 
bleiben

Viele Grüße

Heinz

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Es gäbe ja da noch Ajax.
Das reduziert die Last um einiges.
Es setzt aber Programmierkenntnisse voraus.

https://www.w3schools.com/js/js_ajax_examples.asp

: Bearbeitet durch User
von bofh (Gast)


Lesenswert?

Ich würde es wie folgt machen:
- Kleiner Webserver mit CGI am Rasp
- CGI liefert bei Aufruf alle Daten als JSON
- eine HTML Seite, unterteilt in 4 Felder: Strom, Solar, Heizung, Temp
- pro Feld das jeweilige Hintergrundbild
- Texte/Werte per HTML/CSS positionieren (zB table wo es lohnt)
- JS/AJAX pullt alle n Minuten die Daten und aktualisiert

Falls es Liveupdates sein sollen: Websockets.

von DPA (Gast)


Lesenswert?

SVG und AJAX oder Websocket würde ich verwenden. Die Werte als JSON 
übertragen und mit JS ins SVG einsetzen. Entweder die Werte per 
Websocket direkt senden, oder in eine JSON Datei schreiben und die 
Pollen.

Ungetestet: (Den Abstand bei "xlink:href =" entfernen, kann der Admin 
das endlich mal beheben?)
test.svg:
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
<svg xmlns="http://www.w3.org/2000/svg"
4
    xmlns:xlink="http://www.w3.org/1999/xlink"
5
    version="1.1" baseProfile="full"
6
    viewBox="0 0 800 600">
7
  <desc>
8
    <style><![CDATA[
9
      text {
10
        font: 220px sans-serief;
11
      }
12
    ]]></style>
13
  </desc>
14
  <title>SVG Beispiel</title>
15
  <image xlink:href ="https://images.pexels.com/photos/730896/pexels-photo-730896.jpeg" x="0" y="0" width="800" height="600" />
16
  <text fill="#F00" x="450" y="180" data-value="bla">test</text>
17
  <desc>
18
    <script><![CDATA[
19
      "use strict";
20
      function update(x){ // Text update function
21
        // Search vor all text elements
22
        for(var e of Array.from(document.getElementsByTagName("text"))){
23
          // Check if it has a data-value attribute
24
          if(!e.dataset || !('value' in e.dataset))
25
            continue; // If not, check next text element
26
          let prop = e.dataset.value; // get the value of the data-value attribute
27
          // Do our datas have a property with the same name as the data-value attributes' value?
28
          if(!prop || !(prop in x))
29
            continue; // If not, check next text element
30
          // Otherwise, get the value of that property and use it as text for the text element
31
          e.textContent = x[prop] || '';
32
        }
33
      }
34
      function poll(){ // Function which loads data, and then calls the update function
35
        fetch("./my-datas.json")
36
          .then(response=>update(response.json()));
37
      }
38
      poll(); // Load data
39
      setInterval(poll, 1000 * 5); // Load data again every 5 seconds
40
    ]]></script>
41
  </desc>
42
</svg>
my-datas.json:
1
{
2
  "bla": "1 ☃"
3
}

Das tolle an SVG ist, dass es immer schön alles mit der viewbox 
skaliert, inklusive Text.

von trampi (Gast)


Lesenswert?

Ich würde dazu ein kleiner Web Server auf dem Raspberry Pi laufen 
lassen.
In python zum Beispiel so:
1
from bottle import route, request, run, static_file
2
3
@route('/', name='static')
4
def serve_index():
5
    return static_file('index.html', root='./') #root gibt pfad an
6
7
@route('/temperature', method='POST')
8
def get_temperature():
9
    return "5"
10
11
run(host='0.0.0.0', port=80)

Du kannst dann mit einer Website eine Anfrage an den Server schicken, 
und diese Daten empfangen (in diesem Bsp sollte das File index.html 
heissen, und an dem in root geschriebenen Pfad zu finden sein):
1
<!DOCTYPE html>
2
<html lang="en">
3
<p>Temperatur: <span id=temperature></span></p>
4
<button onclick="request()">Make request</button>
5
<script>
6
function request() {
7
var xhr = new XMLHttpRequest();
8
xhr.responseType = 'text';
9
xhr.onreadystatechange = function() {
10
  if (xhr.readyState == XMLHttpRequest.DONE) {
11
      document.getElementById(
12
        "temperature").innerHTML=xhr.response;
13
  }
14
};
15
xhr.open('POST', 'temperature'); //selber name wie in route(...) in python!
16
xhr.setRequestHeader('Content-Type', 'application/text');
17
xhr.send("Give me temperature");
18
}
19
</script>
20
</html>

Dies ist ein MWE, es kann dan entsprechend erweitert werden, und auch 
mehrere Daten auf einmal empfangen werden.

von trampi (Gast)


Lesenswert?

trampi schrieb:
> python

Getestet habe ich es unter python2.7, unter python3 weiss ich nicht ob 
es so lauffähig ist, anpassungen wären aber minimal.

von Heinz R. (heijz)


Lesenswert?

DPA schrieb:
> SVG und AJAX oder Websocket würde ich verwenden. Die Werte als JSON
> übertragen und mit JS ins SVG einsetzen. Entweder die Werte per---

Danke DPA,  das sieht schon mal sehr vielversprechend aus

Bin nur wie gesagt kein Programmierer...

Habe es geschafft das die Katze mit dem Text "test" dargestellt wird
Der Wert 1 aus der my-datas.json leider nicht?

Verstehe ich es richtig, das Hintergrundbild wird nur bei Scriptstart 
einmalig geladen, danach nur noch die Werte aktualisiert ?  Das wäre 
perfekt.


Viele Grüße

Heinz

von DPA (Gast)


Lesenswert?

Heinz R. schrieb:
> Habe es geschafft das die Katze mit dem Text "test" dargestellt wird
> Der Wert 1 aus der my-datas.json leider nicht?

Ich konnte den Teil noch nicht testen. War das Script auf einem Server, 
oder wurde wurde das Lokal von der Festplatte geöffnet? In letzterem 
fall verhindert die Same-Origin-Policy des Browsers den Zugriff. Und die 
Dateien müssen im gleichen Verzeichnis sein, damit es geht.

> Verstehe ich es richtig, das Hintergrundbild wird nur bei Scriptstart
> einmalig geladen, danach nur noch die Werte aktualisiert ?  Das wäre
> perfekt.

Genau. Das ist beim Beispiel von @trampi ebenfalls der Fall, wenn man 
dort noch ein setInterval() hinzufügt, nur dass dort HTML statt SVG, XHR 
statt fetch, und ids stat data-attribute verwendet werden.

von DPA (Gast)


Lesenswert?

PS: Wenn sonst noch was fehlschlägt, müsste in der Browserkonsole eine 
Fehlermeldung zu finden sein.

von Heinz (Gast)


Lesenswert?

Spiele gerade damit rum, habe es sowohl direkt vom Desktop getestet, 
jetzt auch vom Server - die Variable wird leider nicht geladen

Fehlermeldung kommt aber auch keine, und man sieht in Chrome in der 
Entwicklungsumgebung das alle 5 sec die my-datas.json geladen wird.

Ich suche mal weiter :-)

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

ich hatte das mal in Python implementiert um mit einer Logo zu 
kommunizieren.
Der Python-Webserver liefert eine HTML-Datei und die passenden Images 
aus.
Zusätzlich handelt das selbe Script die Abfragen und Befehle von und zur 
Logo und liefert den Status als XML.

In der Html sah das so aus.

<body onload="activate();">

function activate() {
  .init.
  showState();
}

function showState()
{
  xmlHttp=GetXmlHttpObject();
  if(xmlHttp==null) {
    alert ("Browser does not support HTTP Request");
    return;
  }
  xmlHttp.onload=stateChanged;
  xmlHttp.onerror=stateNotChanged;
  xmlHttp.open("GET","http://"+location.host+":1525",true);
  xmlHttp.send(null);
}

function stateChanged() {
  var xmlDoc=xmlHttp.responseXML;
  if(xmlDoc) {
    .......
    setTimeout(showState,1000);
  } else {
    console.log("error");
    document.getElementById("net").style["background-color"]="yellow";
    .......
    setTimeout(showState,5000);
  }
}

function stateNotChanged() {
  console.log("error");
  document.getElementById("net").style["background-color"]="yellow";
  setTimeout(showState,5000);
}

: Bearbeitet durch User
von Heinz R. (heijz)


Lesenswert?

Bin leider nicht wirklich weiter gekommen.
Versuche mich wie gesagt am Beispiel von DPA

Mir ist nicht klar wie die Werte aus dem JSON überommen werden, 
vielleicht ist dort auch ein Fehler?
Verstehe ich es richtig - die Werte liegen erst mal in Response.json?

Was bedeutet
for(var e of Array.from(document.getElementsByTagName("text"))){  ?


Hier noch mal das Beispielscript:



 <script><![CDATA[
      "use strict";
      function update(x){ // Text update function
        // Search vor all text elements
        for(var e of Array.from(document.getElementsByTagName("text"))){
          // Check if it has a data-value attribute
          if(!e.dataset || !('value' in e.dataset))
            continue; // If not, check next text element
          let prop = e.dataset.value; // get the value of the data-value 
attribute
          // Do our datas have a property with the same name as the 
data-value attributes' value?
          if(!prop || !(prop in x))
            continue; // If not, check next text element
          // Otherwise, get the value of that property and use it as 
text for the text element
          e.textContent = x[prop] || '';
        }
      }
      function poll(){ // Function which loads data, and then calls the 
update function
        fetch("./my-datas.json")
          .then(response=>update(response.json()));
      }
      poll(); // Load data
      setInterval(poll, 1000 * 5); // Load data again every 5 seconds
    ]]></script>

von Daniel A. (daniel-a)


Lesenswert?

> Mir ist nicht klar wie die Werte aus dem JSON überommen werden,
> vielleicht ist dort auch ein Fehler?

Sorry, ich bin gerade erst dazu gekommen, das auf meinen Server zu laden 
und auszuprobieren. (http://dpa.li/svg-fetch-example/test.svg) Ich hatte 
wirklich einen kleinen Fehler gemacht, die poll funktion sollte so 
aussehen:
1
function poll(){
2
  fetch("./my-datas.json")
3
    .then(response=>response.json())
4
    .then(data=>update(data));
5
}

Heinz R. schrieb:
> Verstehe ich es richtig - die Werte liegen erst mal in response.json?

Nunja, fetch() gibt ein Promise Objekt zurück, das ist ein 
"Versprechen", dass etwas passiert oder man etwas bekommt. Eine Promise 
kann erfolgreich sein, oder fehlschlagen. Mit der .then Funktion/Methode 
der Promise kann man  auf den erfolgreichen Abschluss warten, bzw. eine 
(callback) Funktion aufrufen lassen, die das Objekt dann bekommt. Bei 
fetch() ist das ein Response Objekt. Dieses beinhaltet die Header, die 
der Server gesendet hat, und bietet Funktionen und Eigenschaften, mit 
denen man auf die eigentlichen Daten zugreifen/warten kann (.body, 
.blob(), .arrayBuffer()). Die .text() Funktion interpretiert die Daten 
gleich noch als Text, und die .json() Funktion, die ich verwendete, 
nimmt einem gleich noch das Parsen der JSON Daten im Text ab.

Der Fehler von mir war, die Funktionen .json() und co. geben nicht 
direkt die Daten zurück, sondern ebenfalls ein Promise Objekt. Das muss 
so sein, weil die Daten ja noch nicht zwangsläufig alle 
gesendet/empfangen wurden, wenn die Methode aufgerufen wird. Auf die 
eigentlichen Daten muss ich also wider mit .then() warten, und das hatte 
ich vergessen zu tun.
Ich kann hier beim zweiten .then() die Rückgabe des ersten nehmen, weil 
.then() die Rückgabe der Callbackfunktion immer als Promise zurück gibt.

Die Ausdrücke wie x=>x+1 sind Arrow funktionen (aka. lambdas). x=>x+1 
ist fast das gleiche wie function(x){return x+1;}.

: Bearbeitet durch User
von Heinz (Gast)


Lesenswert?

Hallo Daniel,

vielen vielen Dank, es läuft jetzt :-)


Habe auch etwas über SVG nachgelesen, eigentlich ist es für das was ich 
brauche wohl genau das Richtige, fast genau so habe ich mir meine Seiten 
mit Imagemagick bisher zusammen gebastellt, halt an die richtigen 
Stellen Werte und Text gesetzt.

Es sollte ein Leichtes sein, so die meisten meiner Seiten neu anzulegen.


Hast Du zufällig (oder gerne auch jemand anderes) eine gute Idee, wie 
ich das dann in eine Slideshow bekomme?

Gehe ich Recht in der Annahme, wenn ich mir jetzt 10 solcher Seiten 
bastle, die dann mit einer der vielen im Web verfügbaren 
Slide-Show-Programme anlege, dann trotzdem jedes Mal die 
Hintergrundgrafik neu gelaaden wird? Vermutlich dauert es dann auch zu 
lange bis die JSON-Datei jedes Mal wieder neu eingelesen wurde?


Viele Grüße
Heinz

von Reinhard S. (rezz)


Lesenswert?

Heinz R. schrieb:
> Will jetzt die ruhige Weihnachtszeit nutzen und das Ganze etwas moderner
> angehen. (In Bezug auf Umsetzung, Design soll so bleiben)

Du willst den Unterbau ändern, aber das Sichtbare gleich lassen? Gibts 
da einen konkrete Grund für?

> Nur, dann lädt jedes Tablett alle 5 sec jeweils die komplette Seite neu
> vom Server, obwohl sich nur ein paar Werte geändert haben?
> Wie hoch wird die Last am Raspberry dadurch?

Die komplette Seite heißt, so wie ich das sehe, weniger Text wie in 
deinem Beitrag. Simples HTML, wenn du es moderner willst noch etwas CSS. 
Wenn das einen Pi schon überlastet sollte es mich wundern.

von Heinz R. (heijz)


Lesenswert?

Reinhard S. schrieb:
> Du willst den Unterbau ändern, aber das Sichtbare gleich lassen? Gibts
> da einen konkrete Grund für?


Hallo Albert,

Weil es ja irgendwie albern ist, jedes mal ein Bild zu generieren nur 
weil sich ein paar Bytes geändert haben

Ich konnte / kann es nicht besser, das Ergebnis stimmt, aber irgendwie 
ist es wie von hinten durchs Knie in die Brust...

Klar, Netzwerk, Raspberry usw geben das in Zeiten des Livestreams locker 
her, aber da mir eh langweilig war wollte ich was dazu lernen

Kenne mich leider mit dem Ganzen zu wenig aus, Daniels Vorschlag war 
schon mal die richtige Richtung, bekomme ich so hin, jetzt hapert es 
halt noch an der Slideshow, bin leider eher der Kopierer als der Coder

Mich wundert das nichts in der Richtung im Web zu finden ist, nutzt 
niemand so was?

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Du wirst an Javascript nicht vorbei kommen.
Mit Ajax ein paar DOM-Objekte aktualisieren ist nicht so wild.
Und wieso nicht mit Javascript als Programmiersprache anfangen.
Es muss auf der anderen Seite auch kein Riesiges Server-Konstrukt 
existieren.
Das kann ein Pythonscript, welches den kompletten HTTP-Server zur 
Verfügung stellt, sein oder ein XML welches einfach generiert wird und 
auf dem Apache-Server rumliegt.

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Ajax-Beispiele gibts viele

Am Anfang z.B. dieses

https://www.w3schools.com/xml/ajax_intro.asp

Die Texte würde ich einfach als benannte DOM-Objekte machen. Das klappt 
mit <.... id="dingens".....> und document.getElementById("dingens") ganz 
gut.

: Bearbeitet durch User
von M.K. B. (mkbit)


Lesenswert?

Heinz R. schrieb:
> jetzt hapert es halt noch an der Slideshow

Ich würde für jede Slide ein <div> anlegen in dem du den Inhalt jeweils 
frei gestalten kannst. Die divs liegen dann alle übereinander. Dann 
brauchst du noch ein Script, was die divs der Reihe nach anzeigt bzw. 
alle anderen ausblendet. Da müsste es aber auch fertige Bibliotheken 
geben, ich kenne aber gerade keine.

von DPA (Gast)


Lesenswert?

Heinz schrieb:
> Gehe ich Recht in der Annahme, wenn ich mir jetzt 10 solcher Seiten
> bastle, die dann mit einer der vielen im Web verfügbaren
> Slide-Show-Programme anlege, dann trotzdem jedes Mal die
> Hintergrundgrafik neu gelaaden wird?

Nicht zwangsläufig. Wenn die SVG Grafik geladen wird, werden auch darin 
enthaltene Bilder geladen. Solange sich die Datei aber nicht ändert, 
kann diese auch gecached werden. Die meisten Server haben E-Tag Cacheing 
defaultmässig aktiviert. Das geht ungefähr so:
 * Der Browser fragt nach einer Datei.
 * Der Server liefert die Datei, zusammen mit einem eindeutigen wert 
(ETag), der nur diese Datei haben kann.
 * Der Browser cached Datei und merkt sich den ETag
 * Beim nächsten mal, wenn die Datei geladen wird, sendet der Server 
mit, dass er noch die Datei mit dem alten ETag hat.
 * Wenn die Datei auf dem Server sich nicht geändert hat, liefert der 
Server nur diese Info zurück, und nicht die ganze Datei. Der Browser 
verwendet dan die letzte Version aus dem Cache.

Es gibt noch 3 weitere Cacheing varianten, bei denen der Request zum 
Server meist entfällt:
 * Zeitbasiert (Expires und/oder Cache-Control Headers, oft bei Bildern 
verwendet)
 * Application Cache: manuelles Aktualisieren in JS (Ermöglicht auch 
offline Verwendung nach erstem Seitenaufruf, komplex, selten verwendet)
 * Service Worker: Das Caching und Auflösen von Ressourcen wird in JS 
manuell gemacht (Ermöglicht auch offline Verwendung nach erstem Aufruf, 
komplex, selten verwendet)

Und falls das Slideshow Programm alle Lädt, und dann nur noch ein und 
ausblendet, wird alles nur einmal geladen. Wobei bei vielen solchen 
SVGs, die alle paar Sekunden dann alle ihre Daten aktualisieren wollen, 
das nicht unbedingt ideal wäre.

Heinz schrieb:
> Hast Du zufällig (oder gerne auch jemand anderes) eine gute Idee, wie
> ich das dann in eine Slideshow bekomme?

Die SVGs enthalten JS, deshalb sollten sie, wenn diese in einer HTML 
Seite eingebunden werden, mit einem <embed/> oder <iframe></iframe> Tag 
geladen werden. Da gibt es viele Möglichkeiten.

Wie soll die Slideshow denn reagieren? Soll das nächste Slide kommen, 
wenn man irgendwo klickt? Oder Automatisch? Braucht es noch irgendeinen 
Übergang, Miniaturansichten, oder Ähnliches?

Hier mal eins mit Überblendung (wechselt zwischen allen Elementen mit 
.slide):
https://jsfiddle.net/r12mfLk5/2/

Heinz R. schrieb:
> Was bedeutet
> for(var e of Array.from(document.getElementsByTagName("text"))){  ?

document.getElementsByTagName("text") liefert alle <text> Elemente als 
NodeList. In den meisten Browsern ist eine NodeList aber nicht 
iterierbar (in der "for( of )" schleife verwendbar). Array.from macht 
aus der NodeList ein Array, dieses ist dann iterierbar (das geht, weil 
eine NodeList  die anzahl Elemente als .length Eigenschaft hat. 
Beispiel: Array.from({0:'a',1:'b',2:'c',length:2}) ergibt ['a','b'] 
(früher musste man dafür noch Array.prototype.slice.call(objekt) 
verwenden)).
for(var e of [...]) ist einfach eine Schleife, die für jedes Element von 
etwas iterierbarem einmal durchlaufen wird, wobei e jedes mal das 
nächste Element des Iterators beinhaltet. Also "for(let x of 
[1,2,3]){f(x);}" ruft f(x) 3 mal auf, mit x=1, dann x=2, dann x=3.
var, let und const definieren Variablen mit leicht unterschiedlichen 
Geltungsbereich und Veränderbarkeit. var: in ganzer Funktion gültig. 
const und let: im momentanen block {} gültig. const: unveränderbar.

von Heinz (Gast)


Lesenswert?

Hallo Daniel,

vielen Dank, ich bin schwer beeindruckt, auch wenn ich zugegeben vieles 
auch nach 5 Mal lesen nicht verstehe :-)
Du scheinst Dich sehr gut mit so was auszukennen?

Dein Beispiel ist eigentlich genau wie es sein soll

DPA schrieb:
> Wie soll die Slideshow denn reagieren? Soll das nächste Slide kommen,
> wenn man irgendwo klickt? Oder Automatisch? Braucht es noch irgendeinen
> Übergang, Miniaturansichten, oder Ähnliches?

Genau so wie in Deinem Beispiel, einfach nach paar Sekunden überblenden, 
Interaktion braucht es keine

Die 10 Seiten sollen einfach durchlaufen, der von Dir gezeigte 
Überblend-Effekt reicht mehr als aus

Verstehe die Fiddle-Seite zugegeben nicht ganz, HTML, JavaScript und 
CSS, wie kommt das dann am Ende alles zusammen?
Das Bild mit der Katze ist weiterhin das ursprüngliche Skript, wo dann 
aus der JSON die Werte genommen werden?
Ich könnte jetzt einfach 10 solcher Seiten anlegen, die alle aus einem 
gemeinsamen JSON die jeweiligen Daten holen?
Oder besser getrente JSON-Dateien pro Bild?

Verstehe noch nicht so ganz den Unterschied zwischen embed src und image 
src

Will nicht zu viel Deiner Zeit beanspruchen, aber wenn Du magst, 
könntest Du mir evtl. so was wie in Deinem Beispiel zusammen stellen, wo 
dann einfach 3-5 Bilder hintereinander in einer Slideshow gezeigt 
werden?
Denke das entsprechend anzupassen bekomme ich hin



Viele Grüße

Heinz

von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

Heinz schrieb:
> Du scheinst Dich sehr gut mit so was auszukennen?

Ich bin Applikationsentwickler mit einem Systemtechniker Job, und wärend 
der letzten paar Jährchen hab ich, neben anderen Dingen, die meisten 
Internettechnologien und Web APIs gelernt oder zumindest mal angesehen. 
Ich mag dafür Frameworks & Libraries meist nicht so gerne.

Heinz schrieb:
> Verstehe die Fiddle-Seite zugegeben nicht ganz, HTML, JavaScript und
> CSS, wie kommt das dann am Ende alles zusammen?

Ich hab alles mal in ein tar.gz Archiv gepackt, ist im Anhang. Siehe die 
index.html Datei. (statt dem <link> tag hatte ich alles auch direkt in 
die Datei in ein <style> tag tun können, beim <script> täg genauso, wenn 
ich das src weggelassen hätte.).

> Das Bild mit der Katze ist weiterhin das ursprüngliche Skript, wo dann
> aus der JSON die Werte genommen werden?

Ja

> Ich könnte jetzt einfach 10 solcher Seiten anlegen, die alle aus einem
> gemeinsamen JSON die jeweiligen Daten holen?

Ja

> Oder besser getrente JSON-Dateien pro Bild?

Spielt keine grosse rolle. Bei einem JSON könnte man das Script noch 
anpassen, dass man die Datei nur einmal für alle Bilder holt, statt dass 
jedes Bild die neu abruft.

Heinz schrieb:
> Verstehe noch nicht so ganz den Unterschied zwischen embed src und image src

Das embed bei <embed ist der HTML Tag, es gibt an was für ein HTML 
Element man will. img ist für Bilder, video für Videos, audio für Musik, 
iframe für andere Seiten, und embed für andere aktive Inhalte, wobei das 
Browser oft nicht so eng sehen. Bei normalen, statischen SVGs könnte man 
einfach ein img verwenden. Das SVG hier enthält aber JavaScript, Browser 
sollten dieses bei reinen Bildern nicht ausführen. Damit bleiben nur 
embed und iframe dafür übrig. Ein embed verhält sich eher wie ein img, 
die Grösse des Inhalts kann auf die Grösse des Elements Einfluss nehmen, 
etc. Bei iframes hätte man dafür noch Sandboxing optionen, scroll bars 
per default, und keine content-abhängigen Änderungen der iframe-box.

Das src="..." in <embed src="url" /> ist ein Attribut des embed 
elements. Die darin enthaltene URL zeigt auf was auch immer darin 
angezeigt werden soll.

Heinz schrieb:
> Will nicht zu viel Deiner Zeit beanspruchen, aber wenn Du magst,
> könntest Du mir evtl. so was wie in Deinem Beispiel zusammen stellen, wo
> dann einfach 3-5 Bilder hintereinander in einer Slideshow gezeigt
> werden?

Für mehr Bilder kannst du einfach die <img/> oder <embed/> Zeile 
kopieren, und das src="" feld anpassen. Für das JS Script spielt es 
übrigens keine rolle, was für ein Element als Slide für die Slideshow 
verwendet wird, es schaut nur auf das class="slide" attribut, und das 
das Element mit diesem direkt in einem Element mit dem class="slideshow" 
attribut ist. Die Reihenfolge der Slides kann man ändern, indem man 
einfach die Elemente entsprechend umsortiert.

von Heinz R. (heijz)


Lesenswert?

Ich bin schon fleissig am Seiten zusammenstellen, mit Deinem beigefügtem 
Beispiel sieht das schon mal sehr vielversprechend aus

Kurze Frage, habe schon nach einigen Beispielen gesucht, leider bislang 
erfolglos

Wie muss ich die Zeile
<text fill="black" x="150" y="400" class="big" 
data-value="min">test</text>

ändern, so das hinter dem min-Wert noch ein Text stehen kann?
Wie müsste die Zeile aussehen um zu schreiben " Es hat "$min" Grad"?
Oder brauche ich für " Es hat", "$min" und "Grad" jeweils einen neuen 
Befehl?

Wenn ich noch das Grad-Zeichen haben will (°), muss ich das wohl als 
Ascii-Zeichen einfügen?

Viele Grüße

Klaus

von Daniel A. (daniel-a)


Lesenswert?

Im moment ersetzt das Script einfach den Inhalt von Text-elementen mit 
dem data-value Attribut. Mit einer leichten anpassung kann man das auf 
beliebige Elemente anwenden:

Die Zeile:
1
// Search vor all text elements
2
for(var e of Array.from(document.getElementsByTagName("text"))){

Ersetzen durch:
1
// For all elements with a data-value attribute
2
for(var e of Array.from(document.querySelectorAll("[data-value]"))){


Danach kann man z.B. ein tspan Element im text Element verwenden, um 
darin den Wert anzuzeigen:
1
<text fill="#F00" x="0" y="180">The <tspan data-value="bla"></tspan></text>

von Heinz R. (heijz)


Angehängte Dateien:

Lesenswert?

Hallo Daniel,

vielen Dank,  es funktioniert :-)

hätte noch eine Frage:
WIe stelle ich es am Besten an, das die Slides Bildschirmfüllend sind?

Habe jetzt bei der jeweiligen SVG-Seite
  viewBox="0 0 800 450">

Die Hintergrundbilder lade ich mit

  <image x="0" y="0" width="800px" height="450px"
    xlink:href ="../media/thermometer_roh.jpg">
  </image>

positioniere dann entsprechend die Texte

Je nach Display habe ich ja jetzt verschiedene Seitenverhältnisse, 16:9, 
16:10, 4:3...

Meine Bilder haben alle einen weissen Hintergrund - geht es irgendwie 
das jetzt graue auch entsprechend einzufärben?

Oder mus ich die Viewbox so groß machen das es auf alle Fälle immer 
reicht?
Also z.B. 1920 x 1200?

von Daniel A. (daniel-a)


Angehängte Dateien:

Lesenswert?

Heinz R. schrieb:
> Meine Bilder haben alle einen weissen Hintergrund - geht es irgendwie
> das jetzt graue auch entsprechend einzufärben?

Im css file (css/style.css), in der css rule mit dem selector ".slide", 
ist die Hintergrundfarbe mit "background-color" angegeben. Weiss wäre 
#FFF

Heinz R. schrieb:
> WIe stelle ich es am Besten an, das die Slides Bildschirmfüllend sind?

Im css file (css/style.css), in der css rule mit dem selector ".slide", 
ist das Skalierverhalten mit der "object-fit" Eigenschaft festgelegt.

https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

Wobei "object-fit: fill;" aber bei SVGs in einem embed Element nicht 
funktioniert, und bei "object-fit: cover;" zwar immer der ganze 
Bildschirm ausgefüllt ist, aber eventuell der Text ausserhalb des Bildes 
liegen könnte.

Oder mus ich die Viewbox so groß machen das es auf alle Fälle immer
reicht?

Eigentlich sollten nur die width und height Parameter eine rolle 
spielen. Diese sollen idealerweise das gleiche Seitenverhältnis wie die 
Viewbox haben. Man kann aber eigentlich das SVG so nicht bei 
verschiedenen Seitenverhältnissen garantiert den ganzen Bildschirm 
füllen lassen. Es gibt aber noch den Hack, width="100%" height="100%" zu 
setzen, und die viewBox wegzulassen. Dann füllt es den ganzen 
Bildschirm. Wenn man darin trotzdem noch eine Box mit bekanntem 
Seitenverältnis braucht, kann man ein svg Element mit width="100%" 
height="100%" und einer viewBox hin einpacken. Beispiel im Anhang. Das 
hatte ich früher mal bei meinem bubble-background verwendet: 
https://old.danielabrecht.ch/css/bubbles/images/bg.svg

von Heinz R. (heijz)


Lesenswert?

Danke Daniel,
der Hintergrund weiss sieht gut aus, reicht vollkommen :-)

Meine ersten Versuche:

http://kr-server.de:88/test

Woher kommst Du? Würde Dir gerne mal ein Bier ausgeben :-)
Freue mich das mein seit 3 Jahre vor mir her geschobenes 
Weihnachtsprojekt endlich mal was wird

Falls Du noch nicht genervt bist:
Versuche mich jetzt daran, eine Uhr einzubinden

Habe hier ein Tutorial gefunden:

https://www.bitsarefun.com/tutorials/create-animate-clock-css3/

wie schaffe ich es, diese zentriert einzubinden?
Die geben den Hintergrund relativ mit 350 x 350 Pixel an, kann ich da 
irgendwie einen Offset vorgeben?
Kann ich diese auch irgendwie dynamisch skalieren? Also das sie beim 
Fenster verkleinern auch kleiner wird?

: Bearbeitet durch User
von Reinhard S. (rezz)


Lesenswert?

Dennis H. schrieb:
> Du wirst an Javascript nicht vorbei kommen.

Bin ich zu altmodisch, das ich sowas mit einem meta-refresh gelöst 
hätte? Klar, defintiv nicht das neuste. Aber genauso funktional, würde 
ich sagen.

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Reinhard S. schrieb:
> Dennis H. schrieb:
>> Du wirst an Javascript nicht vorbei kommen.
>
> Bin ich zu altmodisch, das ich sowas mit einem meta-refresh gelöst
> hätte? Klar, defintiv nicht das neuste. Aber genauso funktional, würde
> ich sagen.

Kommt immer auf den Traffic an den man auslösen möchte.

Eine XML/Text-Datei vom Server holen und Javascript den Rest machen 
lassen im aktuellen Bild geht genauso gut wie ein MJPEG-Stream direkt 
abspielen oder einen XServer als Display nehmen.

Und so wie ich das am Anfang gelesen habe wollte der Threaderöffner über 
die Refresh-Schöpfungshöhe hinaus.

Mal ne Frage.
Ich hatte mal vor kurzen SVG in Verbindung mit Javascript genutzt um 
Abläufe in einer Anlage als Animation darzustellen.
Wie weit kann ich das Javascript in einem SVG denn in Richtung AJAX 
nutzen ?

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Dennis H. schrieb:
> Mal ne Frage.
> Ich hatte mal vor kurzen SVG in Verbindung mit Javascript genutzt um
> Abläufe in einer Anlage als Animation darzustellen.
> Wie weit kann ich das Javascript in einem SVG denn in Richtung AJAX
> nutzen ?

Habs mir selbst beantwortet.
Geht.
In Verbindung mit Inkscape und Notepad++ für das Erstellen.
window.requestAnimationFrame + XMLHttpRequest und Apache2
Funktioniert direkt in Firefox beim Aufruf vom SVG (mit externen *.JS)

: Bearbeitet durch User
von DPA (Gast)


Angehängte Dateien:

Lesenswert?

Heinz R. schrieb:
> Woher kommst Du? Würde Dir gerne mal ein Bier ausgeben :-)

Arlesheim, Basel Landschaft, Schweiz.

Heinz R. schrieb:
> wie schaffe ich es, diese zentriert einzubinden?

Seit Flex boxen geht das noch relativ einfach, gibt aber viele 
Möglichkeiten:
https://jsfiddle.net/g2xmho35/2/

Heinz R. schrieb:
> Kann ich diese auch irgendwie dynamisch skalieren? Also das sie beim
> Fenster verkleinern auch kleiner wird?

Das geht momentan nur mit JavaScript, und ist etwas aufwendiger.

Ich würde die Uhr halt auch einfach in SVG umsetzen. Hab mal schnell 
eine geschrieben, siehe Anhang.

von Heinz R. (heijz)


Angehängte Dateien:

Lesenswert?

Hallo Daniel,

Basel ist gar nicht mal so weit, komme aus der Stuttgarter Gegend

Du bist echt ein Genie, kurz mal so ne Uhr zu zaubern :-)

Wie immer habe ich noch ein paar Fragen:
- Die Uhr geht eine Stunde hinterher, wo kann ich das anpassen?
Vermutlich muss ich nur irgendwo noch 30° für den Stundenzeiger 
hinzufügen?

-Ich habe eine Seite für Wetter, anbei ein Screenshot
Hier fehlt mir noch die richtige Idee, was ich statt dessen nehmen kann
Alle Beispiele, die ich so im Netz finde, sind nicht wirklich gut aus 
der Ferne ablesbar
Momentan kopiere ich in Deinem Script einfach mit
<embed src="media/wetter.jpg" class="slide" />
jeweils das Bild ein
Wie schaffe ich es, dass das Bild z.B. stündlich neu geladen wird?

Das Wetterbild wird über ein php-script generiert, habe ich vor vielen 
Jahren mal im Netz gefunden und etwas angepasst, vielleicht lässt es 
sich ja auch einfach direkt als php einbinden?

Viele Grüße

Klaus

von Dennis H. (c-logic) Benutzerseite


Lesenswert?

eine HTML bauen die dieses Bild enthält und mit Meta refresh alle Stunde 
refreshed

von Dennis H. (c-logic) Benutzerseite


Angehängte Dateien:

Lesenswert?

Das Script in der SVG von UTC auf Lokale Zeit geht mit

let s = Date.now()/60000-(new Date()).getTimezoneOffset();

: Bearbeitet durch User
von Heinz R. (heijz)


Lesenswert?

Vielen Dank, jetzt passt es auch mit der Uhrzeit

Mit der Wetterkarte komme ich auch voran, hänge gerade an folgendem:

Mit
<text fill="black" x="400" y="280" class="big" ><tspan 
data-value="wert1"></tspan></text>

Kann ich die Variable "wert 1" aus der JSON als Text einfügen


Mit
<image x="10" y="20" width="280" height="280" xlink:href 
="../media/wetter_icons/cloudy.svg" />

kann ich ein hinterlegtes Bild einfügen

Wie schaffe ich es / wie ist die Syntax, um das "cloudy" in dieser Zeile 
mit einem Wert "wert2" aus der JSON zu ersetzen?

von Heinz (Gast)


Lesenswert?

Eine Alternative die ich hin bekomme wäre evtl. die 4 Bilder für die 
Wetteranzeige bereits serverseitig bereit zu stellen

Bisherige Idee war, dem Browser über die JSON zu sagen wie das Wetter 
wird, er dann das entsprechende Bild lädt
in der JSON steht z.B. "Tag1" "sunny.svg", er lädt es dann


Neue Idee wäre, es gibt nur noch Bild1.svg bis Bild4.svg , diese werden 
auf dem Server bereits erstellt / kopiert

Nur, wie bekomme ich es hin das die Bilder regelmäßig neu geladen 
werden?
Diese liegen ja im Browser-cache und werden erst mal nicht automatisch 
neu geladen?

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

> Eine alternative Methode ist die Verwendung einer Technik wie Ajax,
> um eine Website (oder Teile) zu aktualisieren, ohne dass eine
> vollständige Aktualisierung der Seite erforderlich ist, aber dies würde
> auch erfordern, dass der Benutzer JavaScript in seinem Browser aktiviert.
Siehe https://en.wikipedia.org/wiki/Meta_refresh und
https://de.wikipedia.org/wiki/Ajax_(Programmierung)

: Bearbeitet durch User
von Dennis H. (c-logic) Benutzerseite


Lesenswert?

Die SVGs können natürlich auch Javascript enthalten :)

von Heinz (Gast)


Angehängte Dateien:

Lesenswert?

oh je, ich verstehe es immer weniger :-)

Es gibt ja scheinbar zig Wege, Programmiersprachen, Möglichkeiten, Werte
Und ich bin zugegeben kein Programmierer

Habe mich auf das Beispiel von Daniel konzentriert, klappt soweit gut, 
alle Seiten sind fertig bis auf die eine mit dem Wetter

Falls mir noch jemand helfen mag, habe mal die SVG und die JSON 
angehängt

Es geht jetzt eigentlich nur noch darum - wie schaffe ich es, die in der 
JSON bei "icon1" bis "icon4" genannten Namen dynamisch entsprechend  den 
folgenden Zeilen zu laden:

<image x="10" y="50" width="220" height="220" xlink:href 
="../media/wetter_icons/test123.svg" />
<image x="210" y="50" width="230" height="220" xlink:href 
="../media/wetter_icons/cloudy-day-1.svg" />
<image x="410" y="50" width="230" height="220" xlink:href 
="../media/wetter_icons/cloudy-day-1.svg" />
<image x="610" y="50" width="230" height="220" xlink:href 
="../media/wetter_icons/snowy-5.svg" />


Viele Grüße

Klaus

von DPA (Gast)


Lesenswert?

Das ist alles noch ungetestet.

Classe oder sonstigen Identifier hinzufügen:
1
<image x="10" y="50" width="220" height="220" xlink:href 
2
="../media/wetter_icons/test123.svg" class="weather" />
3
<image x="210" y="50" width="230" height="220" xlink:href 
4
="../media/wetter_icons/cloudy-day-1.svg" class="weather" />
5
<image x="410" y="50" width="230" height="220" xlink:href 
6
="../media/wetter_icons/cloudy-day-1.svg" class="weather" />
7
<image x="610" y="50" width="230" height="220" xlink:href 
8
="../media/wetter_icons/snowy-5.svg" class="weather" />

Und dann am entprechenden Ort xlink:href setzen:
1
// What are the URLs for the images?
2
var weatherNameImageMap = {
3
  "rainsnow": "../media/wetter_icons/snowy-5.svg",
4
  "cloudy": "../media/wetter_icons/cloudy-day-1.svg",
5
  "404": "../media/wetter_icons/test123.svg"
6
};
7
8
function update(x){
9
  let weatherimages = Array.from(document.querySelectorAll("image.weather")); // Get all image elements with the weather class
10
  // Set the xlink:href attribute of each image to the url for the image or to the "404" image if there is no url for that image specified in weatherNameImageMap 
11
  weatherimages[0].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon1] || weatherNameImageMap["404"]);
12
  weatherimages[1].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon2] || weatherNameImageMap["404"]);
13
  weatherimages[2].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon3] || weatherNameImageMap["404"]);
14
  weatherimages[3].setAttributeNS( document.lookupNamespaceURI("xlink"), "xlink:href", weatherNameImageMap[x.icon4] || weatherNameImageMap["404"]);
15
  // Rest des Codes wie vorher lassen

von Heinz R. (heijz)


Lesenswert?

Hallo Daniel,

versuche mich gerade daran, haut noch nicht ganz hin
Ich glaube der 3. Abschnitt bei Dir - function update(x){ beisst sich 
irgendwie mit dem bisherigen Inhalt?

Sobald ich das einfüge, werden die bisherigen Text-Werte nicht mehr 
angezeigt

Viele Grüße und vielen Dank für Deine Unterstützung

von DPA (Gast)


Angehängte Dateien:

Lesenswert?

Ungetestet, siehe Anhang.

von Heinz (Gast)


Lesenswert?

Hallo Daniel,


vielen vielen Dank, es scheint zu funktionieren, zumindest das was ich 
bislang testen konnte

Leider ein anderes kleines Problem - generiere die Daten mit FHEM, und 
genau jetzt, als ich damit rum spielen wollte:

Important EOL Notice: As of Thursday, Jan. 3, 2019, the YQL service at 
query.yahooapis.com will be retired. This will impact users of 
datatables.org as well as developers who creates features using this YQL 
service.
To continue using our free Yahoo Weather APIs, use 
https://weather-ydn-yql.media.yahoo.com/forecastrss as your new API 
endpoint. Contact yahoo-weather-ydn-api@oath.com for credentials to 
onboard to this free Yahoo Weather API service. Other YQL based services 
that use query.yahooapis.com will no longer operate.

Muss erst mal das wieder umstellen :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.