Nob: Werte aus JSON weiterverwerten

Hallo,

ich stelle über c3.js ein Chart her, wobei ich über JSON die Daten empfange. Diese würde ich gerne außerhalb des Charts auch nochmal tabellarisch darstellen. Jetzt wärs ja kein Problem, die Daten hierzu doppelt abzufragen. Aber ich würde gerne meine DB entlasten und wenn der Client eh schonmal die ganzen Werte hat, müßte man die doch auch mehrfach clientseitig verwenden können, oder?

Um es konkret zu machen, habe ich hierzu ein Beispiel erstellt. Leider habe ich es nicht geschafft, die Key-Werte-Paare über JSON einzuspielen, aber ich hoffe, es wird auch so klar.

Ich würde nämlich gerne die Key-Value-Paare auch in meinem div id="werte" darstellen. Ist das aus meiner Funktion machbar?

function (value, ratio, id) {
                return d3.format('')(value);
            }

Norbert

  1. Hallo,

    ich stelle über c3.js ein Chart her, wobei ich über JSON die Daten empfange. Diese würde ich gerne außerhalb des Charts auch nochmal tabellarisch darstellen. Jetzt wärs ja kein Problem, die Daten hierzu doppelt abzufragen. Aber ich würde gerne meine DB entlasten und wenn der Client eh schonmal die ganzen Werte hat, müßte man die doch auch mehrfach clientseitig verwenden können, oder?

    Da machst n globales Object und gut isses.

    1. Da machst n globales Object und gut isses.

      Ich bin JS-Newbie. Kannst Du mir das etwas genauer erklären bitte?

      Norbert

      1. Ich bin JS-Newbie. Kannst Du mir das etwas genauer erklären bitte?

        Gerne. JSON ist eine Sequenz. Auf die Daten in einer solchen Datei hat ein Programm keinen wahlfreien Zugriff (Random Access). Der jedoch ist erst gegeben, wenn Daten als Array, Object, Scalar o.a. Strukturen im Hauptspeicher vorliegen.

        Die Sequenz muss dazu deserialisiert werden, Objeckt = JSON.parse(sequenz); ermöglicht so den wahlfreien Zugriff auf Daten, die in einem sogenannten JSON einfach nur trasportsicher verpackt wurden.

      2. Da machst n globales Object und gut isses.

        Ich bin JS-Newbie. Kannst Du mir das etwas genauer erklären bitte?

        Variablen in JavaScript unterliegen ihrem jeweiligen Gültigkeitsbereich, nur dort kann auf sie zugegriffen werden. Ein Gültigkeitsbereich wird durch eine Funktion gekapselt:

        function doSomething () {
           var foo = 42;
           // Hier ist foo gültig, man nennt foo auch eine lokale Variable
        }
        // Hier ist foo undefiniert
        

        Gültigkeitsbereiche können verschachtelt werden, die innere Funktion erhält dann Zugriff auf die Variablen der äußeren, aber nicht umgekehrt:

        function doSomething () {
           var foo = 42;
           function bar () {
              var baz = foo + 3; // Innerhalb dieser Funktion kann auf baz und foo zugegriffen werden
           }
           // baz ist hier undefiniert
        }
        // foo und baz sind hier undefiniert
        

        Nun kann es vorkommen, dass man eine Variable mit mehreren Funktionen teilen möchte, man definiert die Variable dann in einem gemeinsamen übergordneten Gültigkeitsbereich:

        function doSomething () {
           var foo = 42; // Sowohl bar als auch baz haben Zugriff auf foo
           function bar () {
              console.log(foo);
           }
           function baz () {
              console.log(foo);
           }
        }
        

        Es ist eine gute Faustregel beim Teilen von Variablen immer den kleinsten gemeinsamen Gültigkeitsbereich zu wählen. Anfänger fällt es häufig schwierig diesen Bereich zu finden, deshalb tendieren sie dazu, den globalen Bereich dafür zu missbrauchen. Im globalen Gültigkeitsbereich landen alle Variablen, die nicht innerhalb einer Funktion definiert wurden. Das ist problematisch, weil dann auch Funktionen Zugriff auf die geteilten Variablen erhalten, die sie gar nicht sehen sollten. Das führt über kurz oder lang zu unvorhergesehen Nebenwirkungen und Kollisionen - Fehler, die schwer zu entdecken und zu beheben sind. Selbst der JavaScript-Erfinder Brendan Eich hat den globalen Gültigkeitsbereich schon als eine seiner größten Fehlentscheidungen bedauert.

        // Schlecht, da foo global ist
        var foo = 42;
        function doSomething () {
           function bar () {
              console.log(foo);
           }
           function baz () {
              console.log(foo);
           }
        }
        

        PS: Ich habe hier den lexikalischen Gültigkeitsbereich erklärt, daneben besitzt JavaScript auch einen dynamischen Gültigkeitsbereich, der aber ungleich komplizierter ist und besser gemieden wird. Die Kontroverse hängt eng mit this-Schlüsselwort zusammen.

    2. Da machst n globales Object und gut isses.

      Gut isses nicht. Besser ist, an der Stelle, wo die JSON-Daten empfangen werden und dann in eine Funktion gesteckt werden welche ein Diagramm erzeugt, diese gleich dannach in eine 2. Funktion zu stecken welche eine Tabelle erzeugt.

      1. Hallo unknown,

        Besser ist, an der Stelle, wo die JSON-Daten empfangen werden und dann in eine Funktion gesteckt werden welche ein Diagramm erzeugt, diese gleich dannach in eine 2. Funktion zu stecken welche eine Tabelle erzeugt.

        Er ist JS-Newbie. Kannst Du ihm das etwas genauer erklären bitte?

        Bis demnächst
        Matthias

        --
        Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
        1. Er ist JS-Newbie. Kannst Du ihm das etwas genauer erklären bitte?

          Meiner Meinung nach sollte man das verstehen können. Aber ich weiß auch, daß ich nicht unbedingt der Erklärbär bin. Warten wir mal ab, ob er damit was anfangen kann, wenn nicht bin ich bereit den nächsten Brocken hinzuwerfen.
          Ist ja auch nicht so, dass hier zuwenig Leute regelmäßig vorbeikommen die gute Antworten liefern und das i.d.R besser erklären können als ich. Mehr als ein paar wenige Zeilen wirst du von mir selten zu sehen bekommen. Hier hatte ich überhaupt nur geantwortet, weil nach mehreren Stunden immer noch der Tip mit der globalen Variable unwidersprochen stand - selfhtml-untypisch.

          1. Hallo unknown,

            Meiner Meinung nach sollte man das verstehen können. Aber ich weiß auch, daß ich nicht unbedingt der Erklärbär bin. Warten wir mal ab, ob er damit was anfangen kann, wenn nicht bin ich bereit den nächsten Brocken hinzuwerfen.

            Ich bin jetzt von mir ausgegangen. Ich würde es nicht verstehen, aber ich hab mir auch nicht das Beispiel des TO angeschaut.

            Mehr als ein paar wenige Zeilen wirst du von mir selten zu sehen bekommen.

            Das ist überhaupt kein Problem.

            Bis demnächst
            Matthias

            --
            Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
            1. Hallo unknown,

              Ich bin auch kein Freund von Begrüßungsfloskeln die sich der Großteil vermutlich generieren lässt, also nicht ärgern.

              Ich bin jetzt von mir ausgegangen. Ich würde es nicht verstehen, aber ich hab mir auch nicht das Beispiel des TO angeschaut.

              Er bekommt irgendwo seine Daten, vermutlich als Callback, da er von nachladen redet. Er hat also etwas in der Art

              callback(jsonData){
              }
              

              mit jsonData als String oder schon geparst als Objekt, ich gehe mal vom Objekt aus. Im diesem Callback ruft er eine Funktion, die ihm das Diagramm erzeugt.

              callback(jsonData){
                createChart(jsonData);
              }
              

              Da kann er seine Funktion, die ihm die Tabelle erzeugt, auch aufrufen und die Daten übergeben.

              callback(jsonData){
                createChart(jsonData);
                createTable(jsonData);
              }
              

              Dann hat er die Daten in seiner Funktion als Parameter.

              function createTable(jsonData) {
                // mach was mit den Daten
              }
              
              1. Hallo unknown,

                Ich bin auch kein Freund von Begrüßungsfloskeln die sich der Großteil vermutlich generieren lässt, also nicht ärgern.

                Ich denk mal, jeder angemeldete. Aber warum sollte ich mich darüber ärgern?

                [Erklärung]

                Die Erklärung könnte ich als Arbeitsgrundlage nehmen.

                Bis demnächst
                Matthias

                --
                Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
                1. Aber warum sollte ich mich darüber ärgern?

                  Ich wollt's nur mal generell klar stellen, weil ich weiß, daß sich manche über sowas ärgern.

              2. @@unknown

                Ich bin auch kein Freund von Begrüßungsfloskeln die sich der Großteil vermutlich generieren lässt, also nicht ärgern.

                „Auf diese kann ich verzichten.“ —yours truly, 2005

                LLAP 🖖

                --
                „Wir haben deinen numidischen Schreiber aufgegriffen, o Syndicus.“
                „Hat auf dem Forum herumgelungert …“
                (Wachen in Asterix 36: Der Papyrus des Cäsar)
  2. Tach!

    ich stelle über c3.js ein Chart her, wobei ich über JSON die Daten empfange. Diese würde ich gerne außerhalb des Charts auch nochmal tabellarisch darstellen. Jetzt wärs ja kein Problem, die Daten hierzu doppelt abzufragen. Aber ich würde gerne meine DB entlasten und wenn der Client eh schonmal die ganzen Werte hat, müßte man die doch auch mehrfach clientseitig verwenden können, oder?

    Ja klar, dazu darfst du sie aber nicht direkt durchreichen, sondern musst sie erstmal entgegennehmen und in zwei weiteren Schritten erst dem einen geben und dann dem anderen.

    Um es konkret zu machen, habe ich hierzu ein Beispiel erstellt. Leider habe ich es nicht geschafft, die Key-Werte-Paare über JSON einzuspielen, aber ich hoffe, es wird auch so klar.

    Dort hast du die Daten direkt als einen der Bestandteile in einem monolithischen Objektliteral notiert und direkt an die verarbeitende Funktion übergeben. Du musst also erstmal aus diesem Monolithen die Daten herausnehmen und sie durch eine Variable ersetzen. In diese Variable müssen zuvor die Daten geschrieben werden.

    Ich würde nämlich gerne die Key-Value-Paare auch in meinem div id="werte" darstellen. Ist das aus meiner Funktion machbar?

    Die Daten in der Variable kannst du an beliebig viele Konsumenten weitergeben, indem du ihnen diese Variable übergibst.

    dedlfix.

  3. ich stelle über c3.js ein Chart her, wobei ich über JSON die Daten empfange. Diese würde ich gerne außerhalb des Charts auch nochmal tabellarisch darstellen. Jetzt wärs ja kein Problem, die Daten hierzu doppelt abzufragen. Aber ich würde gerne meine DB entlasten und wenn der Client eh schonmal die ganzen Werte hat, müßte man die doch auch mehrfach clientseitig verwenden können, oder?

    Ganz allgemein gesprochen möchtest du Zwischenergebnisse wiederverwenden ohne die gesamte Berechnung, die dafür notwendig war, wiederholen zu müssen. Unter Programmierern nennt man diesen Zwischenspeicher auch Cache. In deinem geschildeten Fall gibt es gleich mehrere Einhängepunkte dafür, die auch in Kombination funktionieren.

    Zunächst könntenst du die Antwort deines Server-Skriptes zwischenspeichern und nachfolgende Anfragen an die selbe JSON-Schnittstelle mit der Antwort aus dem Cache beantworten. Dort kannst du auch am besten entscheiden, wann eine zwischengespeicherte Antwort ungültig wird und neu berechnet werden muss.

    Weiterhin könntest du den HTTP-Client-Cache nutzen. Dazu teilst du dem Browser in den Header-Informationen deiner HTTP-Antwort mit, dass die Seite für eine bestimmte Dauer gecacht werden darf. Der Browser übernimmt dann selbst die Verwaltung des Caches.

    Als weitere Möglichkeit könntest du einen Cache in deinem clientseitigen JavaScript implementieren. Ein ganz einfacherer Cache (ohne Invalidierung ungültig gewordener Zwischenergebnisse) könnte so aussehen:

    const getData = ((cache = new Map()) => (url) => {
       if (!cache.has(url)){
          cache.set(url,fetch(url));
       }
       return cache.get(url);
    })();
    

    Wiederkehrende Aufrufe mit der selben URL würden dann keine neuen HTTP-Anfragen absetzen, sondern aus die Antwort des ersten Aufrufs wiederverwenden:

    getData('/api/version'); // Anfrage wird abgesetzt
    getData('/api/version'); // Ergebnis wird aus dem Cache geladen
    
    1. Daumen hoch!

      Außer:

      const getData;
      

      Vorsicht, zumindest für viele IEs.

      1. Daumen hoch!

        Außer:

        const getData;
        

        Vorsicht, zumindest für viele IEs.

        Nicht ner der IE dürfte mit dem Beispiel seine Schwierigkeiten haben, das Snippet benutzt eine ganze Reihe EcmaScript2015 Features: const declarations, fatarrow functions, Map datatype und default parameter. Um dennoch alle Browser zu unterstüzen, kann man den Code in einem Buildstep mit einem Compiler wie Babel oder TypeScript in plain old EcmaScript5.1 übersetzen lassen. Die neuen Sprachfeatures steigern einfach die Freude beim Entwickeln.

        1. Tach!

          Die neuen Sprachfeatures steigern einfach die Freude beim Entwickeln.

          Ja, aber …

          Um dennoch alle Browser zu unterstüzen, kann man den Code in einem Buildstep mit einem Compiler wie Babel oder TypeScript in plain old EcmaScript5.1 übersetzen lassen.

          … auch Typescript kann nicht alles in alle alten Javascript-Versionen übersetzen. Bestimmte Features sind auch da dem Schalter -target es6 vorbehalten.

          dedlfix.

          1. … auch Typescript kann nicht alles in alle alten Javascript-Versionen übersetzen. Bestimmte Features sind auch da dem Schalter -target es6 vorbehalten.

            Diese Features sind in kangax' Tabelle mit der Fußnote 7 gekennzeichnet.