JpGraph und MariaDB - Richtiger Wert der x-Achse

  • Guten Tag, ich habe das Problem, dass ich nicht genau weiß, was mir jpGraph auf der X-Achse zeigen möchte. Ich denke, er wertet die id der Datenbank aus, allerdings möchte ich dort die Uhrzeit angezeigt bekommen.

    Folgender Code wurde verwendet:

    Spoiler anzeigen

    <?php // content="text/plain; charset=utf-8"

    define('__ROOT__', dirname(dirname(__FILE__)));

    require_once ('src/jpgraph.php');

    require_once ('src/jpgraph_line.php');

    require_once ('src/jpgraph_error.php');


    $x_axis = array();

    $y_axis = array();

    $i = 0;

    $con=mysqli_connect("localhost","root","raspberry","stall");

    // Check connection

    if (mysqli_connect_errno()) {

    echo "Failed to connect to MySQL: " . mysqli_connect_error();

    }

    $result = mysqli_query($con,"SELECT `uhrzeit`, `lux` FROM lux_log ");


    while($row = mysqli_fetch_array($result)) {

    $x_axis[$i] = $row["uhrzeit"];

    $y_axis[$i] = $row["lux"];

    $i++;

    }


    mysqli_close($con);


    $graph = new Graph(800,500);

    $graph->img->SetMargin(40,40,40,40);

    $graph->img->SetAntiAliasing();

    $graph->SetScale("textlin");

    $graph->SetShadow();

    $graph->title->Set("Helligkeitsverlauf");

    $graph->title->SetFont(FF_FONT1,FS_BOLD);


    // Use 20% "grace" to get slightly larger scale then min/max of

    // data

    $graph->yscale->SetGrace(0);


    $p1 = new LinePlot($y_axis);

    $p1->mark->SetType(MARK_FILLEDCIRCLE);

    $p1->mark->SetFillColor("red");

    $p1->mark->SetWidth(4);

    $p1->SetColor("blue");

    $p1->SetCenter();

    $graph->Add($p1);

    $graph->Stroke();

    ?>

    Kann mir einer Helfen? Das ist wahrscheinlich eine Kleinigkeit...

    Vielen Dank :)

  • Das habe ich gesehen, nur leider wurde ich da nicht schlau drauß. Ich habe in meiner Datenbank ja Datum und Zeit enthalten, das möchte ich gerne auf der X-Achse anzeigen und am besten nur für einen Tag.

  • Ich bin bis jetzt noch nicht weiter gekommen, bis auf, dass ich den Fehler lokalisieren konnte. Es muss sich irgendwie um die Schleife bei der Abfrage handeln. Die X-Achse zählt immer einer Wert hoch. Vielleicht kann mir einer ja einen guten Tipp geben.

  • Eigentlich genau an dem Part:

    $result = mysqli_query($con,"SELECT `uhrzeit`, `lux` FROM lux_log ");


    while($row = mysqli_fetch_array($result)) {

    $x_axis[$i] = $row["uhrzeit"];

    $y_axis[$i] = $row["lux"];

    $i++;

    Dort setze ich doch die Schleife ein mit der Uhrzeit und mit dem luxwert, oder nicht?

  • Ja, da setzt Du die Elemente des Arrays $x_axis auf die Uhrzeiten aus Deiner Datenbank. Den Array verwendest Du danach aber nie wieder. Ich kenne PHP nicht, aber daß es Variablennamen interpretieren und daraus auf die gewünschte Verwendung schließen würde, kann ich mir nicht vorstellen.

    • Offizieller Beitrag

    Das ist das Beispiel von der Seite.

    PHP
    $line = new LinePlot($data,$xdata);

    So werden die Graphen generiert. Lineplot (y-achse, x-achse) Und jetzt bastelst du dir das mit deinen arrays zusammen

    • Offizieller Beitrag

    Also prügelst du das als Strings in die db? Das kann wirklich zu Problemen bei der Darstellung führen, da Strings nun mal was ganz anderes als timestamps sind. Wobei man letztere super einfach auch zu nem normalen Datum konvertieren kann.

    Ich hab aber auf irgendeiner Kiste auf Arbeit noch ein ewig altes Projekt von mir, wo ich genau diesen Fehler auch gemacht habe. (Strings statt timestamps). die Grafische Auswertung lief auch über jpgraph. Ich schau nachher mal ob ich das finde.

  • Da deine Werte jede Viertelstunde ermittelt werden und die zeitliche Differenz zwischen zwei Datenpunkten quasi immer identisch ist, könntest du als einfachsten Weg die Werte für die X-Achse direkt setzen.

    Code
    $graph->xaxis->SetTickLabels($x_axis);

    Beim Instanziieren des Lineplots dürfen dann aber keine Werte für die X-Achse übergeben werden, da JpGraph dort kein Stringwerte erlaubt (und den Error 25070 generiert). Dort also nur das eine Array mit den Werten der Y-Achse übergeben.

    Code
    new LinePlot($y_axis);

    Schöner ist natürlich der Ansatz mit dem Code von dbv. Dort wird ein Callback zur Ausgabe der Beschriftung für die X-Achse aufgerufen (Funktion TimeCallback()). Dazu müssen deine Zeitangaben in der DB aber in Integer konvertiert werden, um das Array mit den Daten der X-Achse korrekt zu füttern. SetTickLabels() wird dann nicht verwendet und bei new LinePlot() eben beide Arrays mit den Daten für Y- und X-Achse übergeben.

    Dann entspricht die Skalierung der X-Achse auch den korrekten Datumswerten, was im oberen Fall mit SetTickLabels() natürlich nicht gegeben ist, wenn bei der Datenerfassung Lücken vorliegen.

    Am sinnvollsten verwendet man in der DB nur ein Feld mit dem Datentyp DATETIME für Datum/Uhrzeit. Bei der Abfrage via SQL kann dann einfach via

    SQL
    SELECT UNIX_TIMESTAMP(`zeit`) AS zeit ... 

    der Feldinhalt in einen Zeitstempel (Sekunden seit 01.01.1970) konvertiert werden.

    Mit folgenden SQL-Statements kannst du deine DB-Tabelle bearbeiten. Zunächst wird ein echtes Datumsfeld zugefügt, dann die Kombination deiner Datums- und Zeitwerte in die neue Spalte übernommen. Lege zuvor eine Sicherungskopie deiner Tabelle an.

    Code
    ALTER TABLE `lux_log` ADD `zeit` DATETIME NOT NULL AFTER `uhrzeit`;
    UPDATE `lux_log` SET `zeit` = CONCAT(`datum`, " ", `uhrzeit`)

    Wenn die Werte in der neuen Spalte richtig gesetzt werden, kann du deinen Programmcode anpassen und Teile der Vorlage von dbv integrieren. Wenn alles klappt, musst du letztlich deine Datenerfassung modifzieren (Datumswerte in die neue Spalte übernehmen, lässt sich bequem mittels NOW() erreichen) und kannst die nicht mehr benötigten Spalten in der Tabelle entfernen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!