x-Achsenbeschriftung einer Grafik variabel ändern - wie?

  • Ich lese das Buch "Die elektronische Welt mit Raspberry Pi entdecken" von Erik Bartmann. Darin ist unter anderem ein Projekt beschrieben, in dem analoge Werte von einem A/D Wandler an den RasPi gehen und diese grafisch mit "Flot" (flotcharts.org) ausgewertet werden.


    Das funktioniert bei mir soweit alles genau wie vom Autor beschrieben. Mein Anwendungsfall ist aber anders gelagert, daher benötige ich nicht 50 Messwerte, sondern bei sekündlicher Abfrage und 24h Darstellung 60x60x24 = 86.400 Werte. Die Datei mit dieser Anzahl Werte kann ich erzeugen und auch im Browser darstellen. Auch die Darstellung ansich habe ich soweit angepasst. Der Browser ist damit zwar stark beschäftigt, aber durch die Änderung des Aktualisierungsintervalls auf testweise 5 Sekunden hält es sich in Grenzen.


    Die Werte werden rechts in der Grafik ergänzt und fallen dementsprechend links aus der Grafik heraus, die lediglich einen 24 stündigen Zeitraum anzeigen soll. Die beigefügte Grafik umfasst nur 3.600 Werte.


    Ich möchte auf der x-Achse die vollen Stunden (hh:mm) anzeigen, die dann mit der Grafik nach links wandern. So hat man einen groben Überblick über den zeitlichen Zusammenhang.


    Wie müsste ich das Script dazu abändern?



    [code=php]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="refresh" content="5" >
    <title>Flot Examples</title>
    <link href="layout.css" rel="stylesheet" type="text/css">
    <!--[if lte IE 8]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><![endif]-->
    <script language="javascript" type="text/javascript" src="jquery.js"></script>
    <script language="javascript" type="text/javascript" src="jquery.flot.js"></script>
    </head>
    <body>
    <h1>A/D-Wandler-Messwerte (MCP3008)</h1>
    <div id="placeholder" style="width:600px;height:300px;"></div>
    <p>In diesem Graphen werden die gemessenen analogen Werte des <i><b>MCP3008</b></i> angezeigt.</p>


    <script type="text/javascript">
    $(function () {
    var options = {
    lines: { show: true },
    points: { show: false },
    xaxis: { tickDecimals: 0, tickSize: 60 },
    grid: {hoverable: false }
    };

    <?php
    $datafilename = "channeldata.txt"; // Daten-Datei
    if(file_exists($datafilename)){ // Existiert die Datei?
    $file_handle = fopen($datafilename, "rw"); // Datei lesen
    $i = 0; // Laufvariable
    $line = ""; // Gelesener Wert
    $tupel = ""; // Tupel [x, y]
    $var = ""; // Variable
    while (!feof($file_handle)){
    $line = fgets($file_handle);
    $tupel .= "[".$i.", ".trim($line)."], ";
    $i++;
    }
    fclose($file_handle);
    $var = "var a0 = [".$tupel."];\n";
    echo $var; // Benoetigte Variable f�r Flot-Chart ausgeben
    } else{ /* ... */ }
    ?>
    // Anzeigen des Graphen
    $.plot($("#placeholder"), [{data: a0, label: "Analog/Data: <b>Kanal 0</b>", color: 2}], options);
    });
    </script>
    </body>
    </html>[/php]

  • Die Dokumentation habe ich mir schon angeschaut, aber ich verstehe nicht viel mehr als Bahnhof. Nehmen wir als Beispiel minTickSize. Dadurch wird der Abstand zwischen den Zahlen angegeben. Gebe ich zum Beispiel yaxis: { minTickSize: 50 }, ein, dann ist die y-Achse im 50er Intervall beschriftet. Wobei oberer und unterer Wert automatisch festgelegt werden.


    Ich würde nun gerne wissen, was muss ich eingeben, damit auf der y-Achse nur Werte zwischen 50 und 200 angezeigt werden.


    Mir fehlt das grundliegende Wissen um die Schreibweise dieser Werte :(

  • hi,


    eine schnelle Lösung für diese Aufgabenstellung kann ich jetzt auch nicht anbieten...


    flotcharts und jquery sind mit Sicherheit mächtige Werkzeuge!! mit mächtigen Dokus..:s


    Aber da ich derzeit auch dabei bin, Temperaturen über der Zeit darzustellen, habe ich mich entschlossen, mir selbst mit PHP und ein wenig Javaskript einen "Baukasten für Diagramme zu erstellen.


    Dadurch muss ich mich nicht durch mächtige Dokus kämpfen, und kann alles so gestalten, wie ich mir das vorstelle.


    zuerst hab ich alle Werte (Höhe, Breite. Ränder... variabel gemacht..
    dadruch kann ich sowohl am Smarty und am 22"er saubere Diagramme erstellen.


    [code=php]<html>
    <head>
    <title>Canvas aus DB</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=0.9, user-scalable=no">
    <!--http://html5-mobile.de/blog/me…rt-fuer-mobile-anpassen-->


    </head>


    <body>
    <h3>Canvas aus der Datenbank</h3>


    <?php // -------------------------------------------Werte für Canvas -
    $jahr=2014;
    $monat=05;
    $tag=14;
    $sensorID1 = '28-000005293706';
    $sensorID2 = '28-000005299f57';
    $can_Breite=320; // Breite des Diagramms in px
    $can_Hoehe=230; // Hoehe der Diagramms in px
    $can_Titel="Titel - ".$jahr."-".$monat."-".$tag; // wird oben in der Mitte angezeigt<br>
    $can_Kurve=1; // wenn mehere Kurven gezeichnet werden


    $can_Rand_oben=28; // Freiraum zwischen Canvas und Diagramm
    $can_Rand_unten=35;
    $can_Rand_rechts=20;
    $can_Rand_links=30;


    // --------------------------------------------------- Aufteilung der Zeitachse<br>
    // Überlegung: genutzt soll der max. Platz für einen Tag
    // daher ist die maximale Breite in px:
    $px_max_Zeit=$can_Breite-($can_Rand_links+$can_Rand_rechts);
    // in 24 ganszahlige Teile aufteilen
    $px_pro_Std=$px_max_Zeit/24;


    // --------------------------------------------------- Aufteilung der Temperaturachse<br>
    // flogende Rasterlinien sollen generriert werden
    // 90 Grad
    // 20 Grad
    // 0 Grad
    // -20 GrAD


    $px_max_Temp=$can_Hoehe - $can_Rand_unten - $can_Rand_oben;
    $px_pro_Grad=$px_max_Temp/130; // von 100 Grad bis -30 Grad
    $y_Raster_90=$px_pro_Grad*10+$can_Rand_oben;
    $y_Raster_40=$px_pro_Grad*60+$can_Rand_oben;
    $y_Raster_20=$px_pro_Grad*80+$can_Rand_oben;
    $y_Raster_00=$px_pro_Grad*100+$can_Rand_oben;
    $y_Raster_20minus=$px_pro_Grad*120+$can_Rand_oben;



    $l_ZeitSkala=$px_pro_Std*24; // länge der Zeitskala in px
    $y_ZeitSkala=$can_Hoehe-$can_Rand_unten;


    // ------------------------------------------------------------- Farben festlegen
    // Hintergrund mit Farbe fuellen --> http://www.w3schools.com/html/html_colornames.asp
    $can_hintergrund="WhiteSmoke";
    $can_RandFarbe="Red";
    $can_AchsenFarbe="Black";
    $raster_Farbe="#aaaaaa";
    $Kurve1_Farbe="Green";
    $Kurve2_Farbe="Blue";


    //--Werte für Canvas -


    ?>
    [/php]


    so erhalte ich z.B. in der Variable $px_pro_Std eben die Pixel an der X-Achse, die ich dann in einer Zählschleife (24x 1 Stunde durchlaufe, und den Raster zeichne)


    und die Beschriftung mache ich dann so...


    [code=php]// ---------------------------------------------------- Skala fuer Zeit
    ctx.moveTo(<?php echo $can_Rand_links;?>,<?php echo $y_ZeitSkala;?>);
    ctx.lineTo(<?php echo $can_Rand_links+$l_ZeitSkala;?>,<?php echo $y_ZeitSkala;?>);
    ctx.stroke();
    [/php]


    [code=php]// ----------------------------------------- Diagramm-Raster fuer Zeit
    ctx.beginPath();
    ctx.strokeStyle="<?php echo $raster_Farbe;?>";
    ctx.lineWidth=1;
    <?php for ($sz=1; $sz<=24; $sz++) {// -------------- Beginn for-Schleife?>
    ctx.moveTo(<?php echo (round($can_Rand_links+$px_pro_Std*$sz,0)) ;?>,<?php echo $can_Rand_oben;?>);
    ctx.lineTo(<?php echo (round($can_Rand_links+$px_pro_Std*$sz,0)) ;?>,<?php echo $y_ZeitSkala;?>);
    <?php } // ------------------------------------- Ende der for-Schleife?>
    ctx.stroke();
    [/php]


    und so beschrifte ich dann die Zeitachse... (nur alle 2 Stunden)


    [code=php]ctx.textAlign="center";


    ctx.fillText("00",<?php echo (round($can_Rand_links+$px_pro_Std*0,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("02",<?php echo (round($can_Rand_links+$px_pro_Std*2,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("04",<?php echo (round($can_Rand_links+$px_pro_Std*4,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("06",<?php echo (round($can_Rand_links+$px_pro_Std*6,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("08",<?php echo (round($can_Rand_links+$px_pro_Std*8,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("10",<?php echo (round($can_Rand_links+$px_pro_Std*10,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("12",<?php echo (round($can_Rand_links+$px_pro_Std*12,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("14",<?php echo (round($can_Rand_links+$px_pro_Std*14,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("16",<?php echo (round($can_Rand_links+$px_pro_Std*16,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("18",<?php echo (round($can_Rand_links+$px_pro_Std*18,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("20",<?php echo (round($can_Rand_links+$px_pro_Std*20,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("22",<?php echo (round($can_Rand_links+$px_pro_Std*22,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("24",<?php echo (round($can_Rand_links+$px_pro_Std*24,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    [/php]


    das hat jedoch noch eine kleine Schwachstelle, denn hier summieren sich die Rundungsfehler am rechten Rand... also zwischen der 24:00 Marke und dem rechten Rand meines Canvas...


    Live-Vorschau: mit festem Datum(wird später variabel übergeben)
    http://jm.maiparty.at/canvas_aus_mysql_02.php


    und mit großem Canvas: http://jm.maiparty.at/canvas_aus_mysql_02_xxl.php

  • Es geht mich zwar nichts an, aber solcher Code tut mir einfach weh im Kopf:


    PHP
    ctx.fillText("00",<?php echo (round($can_Rand_links+$px_pro_Std*0,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("02",<?php echo (round($can_Rand_links+$px_pro_Std*2,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("04",<?php echo (round($can_Rand_links+$px_pro_Std*4,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    ctx.fillText("06",<?php echo (round($can_Rand_links+$px_pro_Std*6,0)) ;?>,<?php echo $can_Hoehe-$can_Rand_unten+12;?>);
    .
    .
    .


    Da wird 12 mal der gleiche Wert berechnet und dann in JavaScript eingesetzt !
    -> Eine JavaScript-Variable einmal setzen und dann mehrmals verwenden, etwa so:


    PHP
    var y = <?php echo $can_Hoehe-$can_Rand_unten+12;?> ;
    ctx.fillText("00",<?php echo (round($can_Rand_links+$px_pro_Std*0,0)) ;?>, y ) ;
    ctx.fillText("02",<?php echo (round($can_Rand_links+$px_pro_Std*2,0)) ;?>, y ) ;
    ctx.fillText("04",<?php echo (round($can_Rand_links+$px_pro_Std*4,0)) ;?>, y ) ;
    ctx.fillText("06",<?php echo (round($can_Rand_links+$px_pro_Std*6,0)) ;?>, y ) ;
    .
    .
    .


    Schon mal der halbe Code weg, viel besser verstaendlich und leichter zu warten !


    - - - - -


    Dann vielleicht eine Schleife im JavaScript und JavaScript rechnen lassen ...

  • Danke für den Verbesserungsvorschlag! ..gefällt mir!!


    ..da ich noch in der Entwicklung stecke, hab ich mir bisher noch keine Gedanken zur Optimierung gemacht..


    Ich möchte das ganze Skript noch soweit erweitern, dass ich auch variable Anzahl von Kurfen in einem Diagramm erstellen kann.. und dazu will ich die Funktion nochmals durch eine Zählschleife schicken.


    mal sehen, denke ich kann diese Woche wieder an den Ding weitermachen..


    ----------
    JavaScript ----> ist (noch) nicht mein Freund. aber ich erkenne die Vorteile!!

  • Hallo
    Wie hast du eigentlich denn php code in die javascript function rein geschriben?
    Ich haber ausprobiert und bei mir funktioniert nicht.


    haber auch versugt die php code in eine andere datei zu haben und dieser datei mit javascript aufrufen aber funktioniert auch nicht :/
    irgend eine idee?