Upload files to 'mysql_php'
This commit is contained in:
parent
1ade4137f8
commit
89d4df5524
144
mysql_php/README.md
Normal file
144
mysql_php/README.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# Web- und Datenbankserver
|
||||||
|
|
||||||
|
Voraussetzung: Es steht ein Webserver und ein Datenbankserver zur Verfügung.
|
||||||
|
Getestet wurde die Konfiguration mit
|
||||||
|
|
||||||
|
- MYSQL
|
||||||
|
- APACHE2
|
||||||
|
|
||||||
|
## Dateien
|
||||||
|
|
||||||
|
```
|
||||||
|
info.txt ..... diese Datei
|
||||||
|
chart.js ..... Javascriptdatei für Grafiken
|
||||||
|
dbutil.php ... Datenbankverbindung
|
||||||
|
upload.php ... php-Datei zum Eintragen eines neuen Messwertes
|
||||||
|
wetter.css ... CSS-Formatdatei
|
||||||
|
wetter.php ... Anzeigeseite
|
||||||
|
wetter.sql ... Befehle zum Anlegen der Tabellen
|
||||||
|
```
|
||||||
|
|
||||||
|
# Datenbank anlegen:
|
||||||
|
|
||||||
|
Die Datenbank 'wetter' enthält für jeden Sensor eine Tabelle, deren Aufbau
|
||||||
|
identisch ist:
|
||||||
|
|
||||||
|
```
|
||||||
|
CREATE TABLE `indoor` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`temperature` float(4,2) NOT NULL,
|
||||||
|
`pressure` float(6,2) NOT NULL,
|
||||||
|
`humidity` float(3,1) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Neue Messwerte eintragen
|
||||||
|
|
||||||
|
Das Python-Programm ruft die URL mit Parametern auf:
|
||||||
|
```
|
||||||
|
<server>/upload.php?m=table&t=temp&p=pres&h=hum
|
||||||
|
table = indoor oder outdoor (String
|
||||||
|
temp = Temperatur (double)
|
||||||
|
pres = Luftdruck (double)
|
||||||
|
hum = Luftfeuchtigkeit (double)
|
||||||
|
```
|
||||||
|
Auf dem Server fügt die Auswertung dieser URL die Daten in die Datenbank ein.
|
||||||
|
|
||||||
|
Auf diese Art werden die Daten nur lokal auf dem Server verarbeitet. Ein
|
||||||
|
externer Zugriff auf die Datenbank (direkt vom Raspberry Pi) würde ein
|
||||||
|
Sicherheitsrisiko für die Datenbank darstellen.
|
||||||
|
|
||||||
|
# Messwerte abrufen
|
||||||
|
|
||||||
|
Die grafische Anzeige basiert auf https://d3js.org/d3.v3.min.js.
|
||||||
|
In der Datei **chart.js** werden dazu zwei Funktionen definiert,
|
||||||
|
die für die Anzeige aufgerufen werden.
|
||||||
|
|
||||||
|
```
|
||||||
|
// ************************************************************
|
||||||
|
// Funktion zur Erzeugung einer Grafik (Linie)
|
||||||
|
// Die Daten müssen zwei Spalten enthalten: (zeit | value)
|
||||||
|
//
|
||||||
|
// Parameter:
|
||||||
|
// o titel Diagrammtitel oben
|
||||||
|
// o sql wird z.Zt. nicht genutzt
|
||||||
|
// o textX Beschrfitung der x-Achse
|
||||||
|
// o textY Beschriftung der y-Achse
|
||||||
|
// o breite Breite des Diagramms
|
||||||
|
// o hoehe Höhe des Diagramms
|
||||||
|
// o data Daten im JSON-Format
|
||||||
|
// o scaleY 0=automatisch skalieren, 1=Prozent 0..100
|
||||||
|
// o units Einheiten für die Tooltipps
|
||||||
|
// o id id in css-Klasse
|
||||||
|
// #id ............ Breite, Rand/farbe)
|
||||||
|
// #id .title ...... Farbe, Größe des Titels
|
||||||
|
// #id .y .......... Farbe der y-Beschriftung
|
||||||
|
// #id .linecolor .. Linienfarbe
|
||||||
|
// #id .tooltip .... Frarbe Tooltipps
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
function showDiagram1Line(titel, sql, textX, textY, breite, hoehe,
|
||||||
|
data, scaleY, units, id)
|
||||||
|
|
||||||
|
// ************************************************************
|
||||||
|
// Funktion zur Erzeugung einer Grafik (2 Linien)
|
||||||
|
// Die Daten müssen drei Spalten enthalten: (zeit | value1 | value2 )
|
||||||
|
//
|
||||||
|
// Parameter:
|
||||||
|
// o titel Diagrammtitel oben
|
||||||
|
// o data Daten im JSON-Format
|
||||||
|
// o textX Beschrfitung der x-Achse
|
||||||
|
// o textY1 Beschriftung der y1Achse (links)
|
||||||
|
// o textY2 Beschriftung der y1-Achse (rechts)
|
||||||
|
// o breite Breite des Diagramms
|
||||||
|
// o hoehe Höhe des Diagramms
|
||||||
|
// o scaleY1 0=automatisch skalieren, 1=Prozent 0..100 value1
|
||||||
|
// o scaleY2 0=automatisch skalieren, 1=Prozent 0..100 value2
|
||||||
|
// o units1 Einheiten für die Tooltipps value1
|
||||||
|
// o units2 Einheiten für die Tooltipps value2
|
||||||
|
// o id id in css-Klasse
|
||||||
|
// #id ............ Breite, Rand/farbe)
|
||||||
|
// #id .title ...... Farbe, Größe des Titels
|
||||||
|
// #id .y1 ......... Farbe der y-Beschriftung value1
|
||||||
|
// #id .y2 ......... Farbe der y-Beschriftung value2
|
||||||
|
// #id .linecolor1 . Linienfarbe value1
|
||||||
|
// #id .linecolor2 . Linienfarbe value2
|
||||||
|
// #id .tooltip .... Farbe Tooltipps
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
function showDiagram2Lines(titel, data, textX, textY1, textY2, breite,
|
||||||
|
hoehe, scaleY1, scaleY2, units1, units2, id)
|
||||||
|
```
|
||||||
|
|
||||||
|
Die Anzeige soll exemplarisch an der Temperatur (1 Linie) beschrieben werden.
|
||||||
|
Die Box um den Graphen mit farbigem Titel kann über css realisiert werden.
|
||||||
|
|
||||||
|
<div id="graphTemperature"> ... </div>
|
||||||
|
|
||||||
|
FÜr das Auslesen der Daten wird die Funktion `getJSON_Data1($sqlT)` verwendet,
|
||||||
|
die in `dbutil.php` definiert ist. Das Ergebnis wird in `'data'` gespeichert.
|
||||||
|
|
||||||
|
```
|
||||||
|
<script>
|
||||||
|
<?php
|
||||||
|
$json_data = getJSON_Data1($sqlT);
|
||||||
|
echo "data=".$json_data.";"
|
||||||
|
?>
|
||||||
|
showDiagram1Line("Temperatur (in °C)","","Zeit",
|
||||||
|
"", 600, 300, data, 0, "°C",
|
||||||
|
"#graphTemperature");
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Der SQL-Befehl zur Abfrage:
|
||||||
|
|
||||||
|
```
|
||||||
|
$sqlT = "SELECT time AS Zeit,
|
||||||
|
temperature AS value
|
||||||
|
FROM (SELECT * FROM outdoor ORDER BY time DESC) AS tab
|
||||||
|
ORDER BY Zeit";
|
||||||
|
```
|
||||||
|
|
397
mysql_php/chart.js
Normal file
397
mysql_php/chart.js
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
// ***********************************************************
|
||||||
|
//
|
||||||
|
// Globale Einstellungen
|
||||||
|
// gültig für alle Diagramme
|
||||||
|
//
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Parse the date / time
|
||||||
|
var parseDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse;
|
||||||
|
|
||||||
|
// Einstellung auf deutsche Formate
|
||||||
|
var de_DE = d3.locale({
|
||||||
|
"decimal": ",",
|
||||||
|
"thousands": ".",
|
||||||
|
"grouping": [3],
|
||||||
|
"currency": ["", "€"],
|
||||||
|
"dateTime": "%a %b %e %X %Y",
|
||||||
|
"date": "%d.%m.%Y",
|
||||||
|
"time": "%H:%M:%S",
|
||||||
|
"periods": ["AM", "PM"],
|
||||||
|
"days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
|
||||||
|
"shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
|
||||||
|
"months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "July", "August", "September", "Oktober", "November", "Dezember"],
|
||||||
|
"shortMonths": ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zeit auf deutsches Format einstellen
|
||||||
|
d3.time.format = de_DE.timeFormat;
|
||||||
|
|
||||||
|
// Benutzerdefiniertes Zeitformat
|
||||||
|
var customTimeFormat = d3.time.format.multi([
|
||||||
|
[".%L", function(d) { return d.getMilliseconds(); }],
|
||||||
|
[":%S", function(d) { return d.getSeconds(); }],
|
||||||
|
["%H:%M", function(d) { return d.getMinutes(); }],
|
||||||
|
["%H:%M", function(d) { return d.getHours(); }],
|
||||||
|
["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
|
||||||
|
["%b %d", function(d) { return d.getDate() != 1; }],
|
||||||
|
["%B", function(d) { return d.getMonth(); }],
|
||||||
|
["%Y", function() { return true; }]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Zeitformat für Tooltipps
|
||||||
|
var formatTimeTooltipp = d3.time.format("%e %B %H:%M");
|
||||||
|
|
||||||
|
// ************************************
|
||||||
|
// define grid line functions
|
||||||
|
// ************************************
|
||||||
|
function make_x_axis1(x) {
|
||||||
|
return d3.svg.axis()
|
||||||
|
.scale(x)
|
||||||
|
.orient("bottom")
|
||||||
|
.ticks(15)
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_y_axis1(yy,dir) {
|
||||||
|
return d3.svg.axis()
|
||||||
|
.scale(yy)
|
||||||
|
.orient(dir)
|
||||||
|
.ticks(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************
|
||||||
|
// Funktion zur Erzeugung einer Grafik (Linie)
|
||||||
|
// Die Daten müssen zwei Spalten enthalten: (zeit | value)
|
||||||
|
//
|
||||||
|
// Parameter:
|
||||||
|
// o titel Diagrammtitel oben
|
||||||
|
// o sql wird z.Zt. nicht genutzt
|
||||||
|
// o textX Beschrfitung der x-Achse
|
||||||
|
// o textY Beschriftung der y-Achse
|
||||||
|
// o breite Breite des Diagramms
|
||||||
|
// o hoehe Höhe des Diagramms
|
||||||
|
// o data Daten im JSON-Format
|
||||||
|
// o scaleY 0=automatisch skalieren, 1=Prozent 0..100
|
||||||
|
// o units Einheiten für die Tooltipps
|
||||||
|
// o id id in css-Klasse
|
||||||
|
// #id ............ Breite, Rand/farbe)
|
||||||
|
// #id .title ...... Farbe, Größe des Titels
|
||||||
|
// #id .y .......... Farbe der y-Beschriftung
|
||||||
|
// #id .linecolor .. Linienfarbe
|
||||||
|
// #id .tooltip .... Frarbe Tooltipps
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
function showDiagram1Line(titel, sql, textX, textY, breite, hoehe, data, scaleY, units, id) {
|
||||||
|
|
||||||
|
var margin = {top: 30, right: 55, bottom: 30, left: 60},
|
||||||
|
width = breite - margin.left - margin.right,
|
||||||
|
height = hoehe - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
document.write ("<div class='title'>" + titel + "</div>");
|
||||||
|
|
||||||
|
// specify the scales for each set of data
|
||||||
|
var x = d3.time.scale().range([0, width]);
|
||||||
|
var y = d3.scale.linear().range([height, 0]);
|
||||||
|
|
||||||
|
// dynamische Werte anzeigen
|
||||||
|
var div = d3.select("body").append("div")
|
||||||
|
.attr("class", "tooltip tooltippfarbe")
|
||||||
|
.style("opacity", 0);
|
||||||
|
|
||||||
|
|
||||||
|
// axis formatting
|
||||||
|
var xAxis = d3.svg.axis().scale(x)
|
||||||
|
.orient("bottom").ticks(6).tickFormat(customTimeFormat);;
|
||||||
|
var yAxis = d3.svg.axis().scale(y)
|
||||||
|
.tickFormat(d3.format(".1f"))
|
||||||
|
.orient("left").ticks(5);
|
||||||
|
|
||||||
|
// line functions
|
||||||
|
var valueLine = d3.svg.line()
|
||||||
|
.x(function(d) { return x(d.zeit); })
|
||||||
|
.y(function(d) { return y(d.value); });
|
||||||
|
|
||||||
|
|
||||||
|
// setup the svg area
|
||||||
|
var svg = d3.select(id)
|
||||||
|
.append("svg")
|
||||||
|
.attr("width", width + margin.left + margin.right)
|
||||||
|
.attr("height", height + margin.top + margin.bottom)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform",
|
||||||
|
"translate(" + margin.left + "," + margin.top + ")");
|
||||||
|
|
||||||
|
// wrangle the data into the correct formats and units
|
||||||
|
data.forEach(function(d) {
|
||||||
|
d.zeit = parseDate(d.zeit);
|
||||||
|
d.value = +d.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scale the range of the data
|
||||||
|
x.domain(d3.extent(data, function(d) { return d.zeit; }));
|
||||||
|
if ( scaleY == 0 ) {
|
||||||
|
y.domain([
|
||||||
|
d3.min(data, function(d) {return Math.min(d.value); })-.25,
|
||||||
|
d3.max(data, function(d) {return Math.max(d.value); })+.25]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y.domain([ 0,100 ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.append("path") // Add the value line.
|
||||||
|
.attr("class", "linecolor")
|
||||||
|
.attr("d", valueLine(data));
|
||||||
|
|
||||||
|
svg.append("g") // Add the X Axis
|
||||||
|
.attr("class", "x axis")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
.call(xAxis);
|
||||||
|
|
||||||
|
svg.append("g") // Add the value axis
|
||||||
|
.attr("class", "y axis")
|
||||||
|
//.style("fill", "steelblue")
|
||||||
|
.call(yAxis);
|
||||||
|
|
||||||
|
svg.append("text") // Add the text label for the value axis
|
||||||
|
.attr("class", "y")
|
||||||
|
.attr("transform", "rotate(-90)")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", -40)
|
||||||
|
//.style("fill", "steelblue")
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.text(textY);
|
||||||
|
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "grid")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
.call(make_x_axis1(x)
|
||||||
|
.tickSize(-height, 0, 0)
|
||||||
|
.tickFormat("")
|
||||||
|
);
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "grid")
|
||||||
|
.call(make_y_axis1(y,"left")
|
||||||
|
.tickSize(-width, 0, 0)
|
||||||
|
.tickFormat("")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// dynamische Wertanzeige
|
||||||
|
svg.selectAll("dot")
|
||||||
|
.data(data)
|
||||||
|
.enter().append("circle")
|
||||||
|
.attr("r", 2)
|
||||||
|
.attr("cx", function(d) { return x(d.zeit); })
|
||||||
|
.attr("cy", function(d) { return y(d.value); })
|
||||||
|
.on("mouseover", function(d) {
|
||||||
|
div.transition()
|
||||||
|
.duration(100)
|
||||||
|
.style("opacity", .9);
|
||||||
|
div .html(formatTimeTooltipp(d.zeit) + "<br/>" + d.value + units)
|
||||||
|
.style("left", (d3.event.pageX) + "px")
|
||||||
|
.style("top", (d3.event.pageY - 28) + "px");
|
||||||
|
})
|
||||||
|
.on("mouseout", function(d) {
|
||||||
|
div.transition()
|
||||||
|
.duration(500)
|
||||||
|
.style("opacity", 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************
|
||||||
|
// Funktion zur Erzeugung einer Grafik (2 Linien)
|
||||||
|
// Die Daten müssen drei Spalten enthalten: (zeit | value1 | value2 )
|
||||||
|
//
|
||||||
|
// Parameter:
|
||||||
|
// o titel Diagrammtitel oben
|
||||||
|
// o data Daten im JSON-Format
|
||||||
|
// o textX Beschrfitung der x-Achse
|
||||||
|
// o textY1 Beschriftung der y1Achse (links)
|
||||||
|
// o textY2 Beschriftung der y1-Achse (rechts)
|
||||||
|
// o breite Breite des Diagramms
|
||||||
|
// o hoehe Höhe des Diagramms
|
||||||
|
// o scaleY1 0=automatisch skalieren, 1=Prozent 0..100 value1
|
||||||
|
// o scaleY2 0=automatisch skalieren, 1=Prozent 0..100 value2
|
||||||
|
// o units1 Einheiten für die Tooltipps value1
|
||||||
|
// o units2 Einheiten für die Tooltipps value2
|
||||||
|
// o id id in css-Klasse
|
||||||
|
// #id ............ Breite, Rand/farbe)
|
||||||
|
// #id .title ...... Farbe, Größe des Titels
|
||||||
|
// #id .y1 ......... Farbe der y-Beschriftung value1
|
||||||
|
// #id .y2 ......... Farbe der y-Beschriftung value2
|
||||||
|
// #id .linecolor1 . Linienfarbe value1
|
||||||
|
// #id .linecolor2 . Linienfarbe value2
|
||||||
|
// #id .tooltip .... Farbe Tooltipps
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
function showDiagram2Lines(titel, data, textX, textY1, textY2, breite, hoehe, scaleY1, scaleY2, units1, units2, id) {
|
||||||
|
|
||||||
|
var margin = {top: 30, right: 65, bottom: 30, left: 60},
|
||||||
|
width = breite - margin.left - margin.right,
|
||||||
|
height = hoehe - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
document.write ("<div class='title'>" + titel + "</div>");
|
||||||
|
|
||||||
|
// specify the scales for each set of data
|
||||||
|
var x = d3.time.scale().range([0, width]);
|
||||||
|
var y = d3.scale.linear().range([height, 0]);
|
||||||
|
var y2 = d3.scale.linear().range([height, 0]);
|
||||||
|
|
||||||
|
// dynamische Werte anzeigen
|
||||||
|
var div = d3.select("body").append("div")
|
||||||
|
.attr("class", "tooltip tooltippfarbe")
|
||||||
|
.style("opacity", 0);
|
||||||
|
|
||||||
|
|
||||||
|
// axis formatting
|
||||||
|
var xAxis = d3.svg.axis().scale(x)
|
||||||
|
.orient("bottom").ticks(6).tickFormat(customTimeFormat);;
|
||||||
|
var yAxis = d3.svg.axis().scale(y)
|
||||||
|
.tickFormat(d3.format(".1f"))
|
||||||
|
.orient("left").ticks(5);
|
||||||
|
var y2Axis = d3.svg.axis().scale(y2)
|
||||||
|
.tickFormat(d3.format(".1f"))
|
||||||
|
.orient("right").ticks(5);
|
||||||
|
|
||||||
|
// line functions ^
|
||||||
|
var valueLine1 = d3.svg.line()
|
||||||
|
.x(function(d) { return x(d.zeit); })
|
||||||
|
.y(function(d) { return y(d.value1); });
|
||||||
|
// line functions 1
|
||||||
|
var valueLine2 = d3.svg.line()
|
||||||
|
.x(function(d) { return x(d.zeit); })
|
||||||
|
.y(function(d) { return y2(d.value2); });
|
||||||
|
|
||||||
|
|
||||||
|
// setup the svg area
|
||||||
|
var svg = d3.select(id)
|
||||||
|
.append("svg")
|
||||||
|
.attr("width", width + margin.left + margin.right)
|
||||||
|
.attr("height", height + margin.top + margin.bottom)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform",
|
||||||
|
"translate(" + margin.left + "," + margin.top + ")");
|
||||||
|
|
||||||
|
// wrangle the data into the correct formats and units
|
||||||
|
data.forEach(function(d) {
|
||||||
|
d.zeit = parseDate(d.zeit);
|
||||||
|
d.value1 = +d.value1;
|
||||||
|
d.value2 = +d.value2;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Scale the range of the data
|
||||||
|
x.domain(d3.extent(data, function(d) { return d.zeit; }));
|
||||||
|
if ( scaleY1 == 0 ) {
|
||||||
|
y.domain([
|
||||||
|
d3.min(data, function(d) {return Math.min(d.value1); })-.25,
|
||||||
|
d3.max(data, function(d) {return Math.max(d.value1); })+.25]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y.domain([ 0,100 ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( scaleY2 == 0 ) {
|
||||||
|
y2.domain([
|
||||||
|
d3.min(data, function(d) {return Math.min(d.value2); })-.25,
|
||||||
|
d3.max(data, function(d) {return Math.max(d.value2); })+.25]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
y2.domain([ 0,100 ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
svg.append("path") // Add the value line.1
|
||||||
|
.attr("class", "linecolor1")
|
||||||
|
.attr("d", valueLine1(data));
|
||||||
|
|
||||||
|
svg.append("path") // Add the value line 2
|
||||||
|
.attr("class", "linecolor2")
|
||||||
|
.attr("d", valueLine2(data));
|
||||||
|
|
||||||
|
svg.append("g") // Add the X Axis
|
||||||
|
.attr("class", "x axis")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
.call(xAxis);
|
||||||
|
|
||||||
|
svg.append("g") // Add the value axis
|
||||||
|
.attr("class", "y1 axis")
|
||||||
|
.call(yAxis);
|
||||||
|
svg.append("g") // Add the value axis
|
||||||
|
.attr("class", "y2 axis")
|
||||||
|
.attr("transform", "translate(" + width + " ,0)")
|
||||||
|
.call(y2Axis);
|
||||||
|
|
||||||
|
// Y-Achsen-Beschriftung
|
||||||
|
svg.append("text") // Add the text label for the value1 axis
|
||||||
|
.attr("class", "y1")
|
||||||
|
//.attr("transform", "rotate(-90)")
|
||||||
|
.attr("x", 10)
|
||||||
|
.attr("y", 0)
|
||||||
|
//.style("fill", "steelblue")
|
||||||
|
.style("text-anchor", "begin")
|
||||||
|
.text(textY1);
|
||||||
|
|
||||||
|
svg.append("text") // Add the text label for value 2
|
||||||
|
.attr("class", "y2")
|
||||||
|
//.attr("transform", "rotate(-90)")
|
||||||
|
.attr("x", width-10)
|
||||||
|
.attr("y", 0)
|
||||||
|
//.style("fill", "red")
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.text(textY2);
|
||||||
|
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "grid")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
.call(make_x_axis1(x)
|
||||||
|
.tickSize(-height, 0, 0)
|
||||||
|
.tickFormat("")
|
||||||
|
);
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "grid")
|
||||||
|
.call(make_y_axis1(y,"left")
|
||||||
|
.tickSize(-width, 0, 0)
|
||||||
|
.tickFormat("")
|
||||||
|
)
|
||||||
|
// NEU
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "grid")
|
||||||
|
.call(make_y_axis1(y,"right")
|
||||||
|
.tickSize(-width, 0, 0)
|
||||||
|
.tickFormat("")
|
||||||
|
)
|
||||||
|
|
||||||
|
// dynamische Wertanzeige
|
||||||
|
svg.selectAll("dot")
|
||||||
|
.data(data)
|
||||||
|
.enter().append("circle")
|
||||||
|
.attr("r", 2)
|
||||||
|
.attr("cx", function(d) { return x(d.zeit); })
|
||||||
|
.attr("cy", function(d) { return y(d.value1); })
|
||||||
|
.on("mouseover", function(d) {
|
||||||
|
div.transition()
|
||||||
|
.duration(100)
|
||||||
|
.style("opacity", .9);
|
||||||
|
div .html(formatTimeTooltipp(d.zeit) + "<br/>" + d.value1 + units1 + "<br/>" + d.value2 + units2)
|
||||||
|
.style("left", (d3.event.pageX) + "px")
|
||||||
|
.style("top", (d3.event.pageY - 28) + "px");
|
||||||
|
})
|
||||||
|
.on("mouseout", function(d) {
|
||||||
|
div.transition()
|
||||||
|
.duration(500)
|
||||||
|
.style("opacity", 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
230
mysql_php/dbutil.php
Normal file
230
mysql_php/dbutil.php
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Testprogramm zur Erzeugung einer Grafik
|
||||||
|
* mit der Bibliothek d3js.org
|
||||||
|
* Die Daten werden aus einer Datenbank gelesen
|
||||||
|
* DB: wetter
|
||||||
|
* Tabelle: outdoor (id, time, temperature, pressure, humidity)
|
||||||
|
*
|
||||||
|
* Die Ausgabe der Daten am oberen Rand dient nur der Kontrolle
|
||||||
|
* und kann durch auskommentieren der Zeile (direkt unterhalb von body)
|
||||||
|
* entfernt werden.
|
||||||
|
*
|
||||||
|
* Oktober2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
$hostname = 'localhost';
|
||||||
|
$username = 'xxxxxxx';
|
||||||
|
$password = 'xxxxxxx';
|
||||||
|
$table = 'outdoor';
|
||||||
|
$dbname = "wetter";
|
||||||
|
|
||||||
|
$anzahl = 48;
|
||||||
|
if (isset($_GET["dauer"])) $anzahl = $_GET["dauer"];
|
||||||
|
|
||||||
|
// Verwendete SQL-Abfragen
|
||||||
|
// aktuelle Werte
|
||||||
|
$sql1 = "SELECT * from $table ORDER BY time DESC LIMIT 1";
|
||||||
|
|
||||||
|
if ($anzahl == 0) $a =""; else $a = " limit $anzahl";
|
||||||
|
$sql = "select * from (select * from $table order by time desc $a) as tab order by time";
|
||||||
|
|
||||||
|
// Daten für tabellarische Anzeige
|
||||||
|
$sql2 = "select * from $table order by time DESC $a";
|
||||||
|
|
||||||
|
// Mittelwert für den ausgewählten Zeitraum
|
||||||
|
$sql2a = "select avg(t.temperature) as avgT, avg(t.pressure) as avgP, avg(t.humidity) as avgH from (SELECT * FROM $table ORDER BY time DESC $a) AS t";
|
||||||
|
|
||||||
|
// Zeit der letzten Messung
|
||||||
|
$sqlTime = "SELECT time FROM $table ORDER BY time DESC LIMIT 1";
|
||||||
|
|
||||||
|
|
||||||
|
function getJSON_Data() {
|
||||||
|
global $hostname;
|
||||||
|
global $username;
|
||||||
|
global $password;
|
||||||
|
global $dbname;
|
||||||
|
global $sql;
|
||||||
|
try {
|
||||||
|
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
|
||||||
|
|
||||||
|
// *** The SQL SELECT statement *** /
|
||||||
|
$sth = $dbh->prepare($sql);
|
||||||
|
$sth->execute();
|
||||||
|
|
||||||
|
// Fetch all of the remaining rows in the result set * /
|
||||||
|
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// ** close the database connection *** /
|
||||||
|
$dbh = null;
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$json_data = json_encode($result);
|
||||||
|
return $json_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getJSON_Data1($sq) {
|
||||||
|
global $hostname;
|
||||||
|
global $username;
|
||||||
|
global $password;
|
||||||
|
global $dbname;
|
||||||
|
global $sql;
|
||||||
|
try {
|
||||||
|
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
|
||||||
|
|
||||||
|
// *** The SQL SELECT statement *** /
|
||||||
|
$sth = $dbh->prepare($sq);
|
||||||
|
//$sth = $dbh->prepare("SELECT `temperatur`, `luftdruck`,`luftfeuchtigkeit`, `zeit` FROM `wetter` order by `zeit`");
|
||||||
|
$sth->execute();
|
||||||
|
|
||||||
|
// Fetch all of the remaining rows in the result set * /
|
||||||
|
$result = $sth->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// ** close the database connection *** /
|
||||||
|
$dbh = null;
|
||||||
|
}
|
||||||
|
catch(PDOException $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$json_data = json_encode($result);
|
||||||
|
return $json_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function doQuery($sql) {
|
||||||
|
global $hostname;
|
||||||
|
global $username;
|
||||||
|
global $password;
|
||||||
|
global $dbname;
|
||||||
|
$link = mysqli_connect($hostname, $username, $password, $dbname);
|
||||||
|
if (mysqli_connect_errno()) {
|
||||||
|
printf("Connect failed: %s\n", mysqli_connect_error());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
if ($result = mysqli_query($link, $sql)) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastTime() {
|
||||||
|
global $sqlTime;
|
||||||
|
$zeit = "";
|
||||||
|
$result = doQuery($sqlTime);
|
||||||
|
if ($result != null) {
|
||||||
|
$obj = mysqli_fetch_object($result);
|
||||||
|
$zeit = $obj->time;
|
||||||
|
}
|
||||||
|
mysqli_free_result($result); // free result set
|
||||||
|
return $zeit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAktuelleWerte($dauer) {
|
||||||
|
global $sql1;
|
||||||
|
global $sql2;
|
||||||
|
global $sql2a;
|
||||||
|
$html = "";
|
||||||
|
$zeit = ""; // aktuelle Zeit
|
||||||
|
$tA = ""; // aktuelle Temperatur
|
||||||
|
$pA = "";
|
||||||
|
$hA = "";
|
||||||
|
// result hat max. 1 Wert
|
||||||
|
$result = doQuery($sql1);
|
||||||
|
$dauer = $dauer / 72;
|
||||||
|
if ($dauer == 1) $dauer .= " Tag"; else $dauer .= " Tage";
|
||||||
|
|
||||||
|
if ($result != null) {
|
||||||
|
//while ($obj = mysqli_fetch_object($result)) {
|
||||||
|
$obj = mysqli_fetch_object($result);
|
||||||
|
$zeit = $obj->time;
|
||||||
|
$tA = $obj->temperature;
|
||||||
|
$pA = $obj->pressure;
|
||||||
|
$hA = $obj->humidity;
|
||||||
|
}
|
||||||
|
mysqli_free_result($result); // free result set
|
||||||
|
|
||||||
|
|
||||||
|
// Mittelwerte -- max. 1 Ergebniszeile
|
||||||
|
$result1 = doQuery($sql2a);
|
||||||
|
if ($result1 != null) {
|
||||||
|
$obj = mysqli_fetch_object($result1);
|
||||||
|
$avgT = $obj->avgT;
|
||||||
|
$avgP = $obj->avgP;
|
||||||
|
$avgH = $obj->avgH;
|
||||||
|
}
|
||||||
|
mysqli_free_result($result); // free result set
|
||||||
|
|
||||||
|
|
||||||
|
// jetzt min-max-Werte
|
||||||
|
$tmin = 100; $tmax = -100; // Temperatur
|
||||||
|
$pmin = 2000; $pmax = 0; // Luftdruck
|
||||||
|
$lmin = 100; $lmax = 0; // Luftfeuchtigkeit
|
||||||
|
$result = doQuery($sql2);
|
||||||
|
if ($result != null) {
|
||||||
|
while ($obj = mysqli_fetch_object($result)) {
|
||||||
|
if ($obj->temperature < $tmin) $tmin = $obj->temperature;
|
||||||
|
if ($obj->temperature > $tmax) $tmax = $obj->temperature;
|
||||||
|
if ($obj->pressure < $pmin) $pmin = $obj->pressure;
|
||||||
|
if ($obj->pressure > $pmax) $pmax = $obj->pressure;
|
||||||
|
if ($obj->humidity < $lmin) $lmin = $obj->humidity;
|
||||||
|
if ($obj->humidity > $lmax) $lmax = $obj->humidity;
|
||||||
|
}
|
||||||
|
mysqli_free_result($result); // free result set
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = "<p>letzter Messwert um <b>$zeit</b>";
|
||||||
|
$html .= " · Zeitraum: <b>$dauer</b></p>";
|
||||||
|
$html = "<div class='messwert'> <div class='text'>°C</div> <div class='value'>";
|
||||||
|
$html .= sprintf("<div class='aktuell'>T = %6.2f °C </div>",$tA);
|
||||||
|
$html .= sprintf("<div class='min'>min = %6.2f °C </div>",$tmin);
|
||||||
|
$html .= sprintf("<div class='max'>max = %6.2f °C </div>",$tmax);
|
||||||
|
$html .= sprintf("<div class='avg'>avg = %6.2f °C </div>",$avgT);
|
||||||
|
$html .= "</div> </div>";
|
||||||
|
|
||||||
|
$html .= "<div class='messwert'> <div class='text'>Pa</div> <div class='value'>";
|
||||||
|
$html .= sprintf("<div class='aktuell'>p = %6.2f hPa </div>",$pA);
|
||||||
|
$html .= sprintf("<div class='min'>min = %6.2f hPa </div>",$pmin);
|
||||||
|
$html .= sprintf("<div class='max'>max = %6.2f hPa </div>",$pmax);
|
||||||
|
$html .= sprintf("<div class='avg'>avg = %6.2f hPa </div>",$avgP);
|
||||||
|
$html .= "</div> </div>";
|
||||||
|
|
||||||
|
$html .= "<div class='messwert'> <div class='text'>%</div> <div class='value'>";
|
||||||
|
$html .= sprintf("<div class='aktuell'>h = %6.2f % </div>",$hA);
|
||||||
|
$html .= sprintf("<div class='min'>min = %6.1f % </div>",$lmin);
|
||||||
|
$html .= sprintf("<div class='max'>max = %6.1f % </div>",$lmax);
|
||||||
|
$html .= sprintf("<div class='avg'>avg = %6.1f % </div>",$avgH);
|
||||||
|
$html .= "</div> </div>";
|
||||||
|
$html .= "<br clear='all' />";
|
||||||
|
|
||||||
|
mysqli_close($link); // close connection
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getDaten() {
|
||||||
|
global $sql2;
|
||||||
|
$html = "";
|
||||||
|
$result = doQuery($sql2);
|
||||||
|
|
||||||
|
$html .= "<pre>";
|
||||||
|
$html .= sprintf ("%-20s %-8s %-10s %-5s (%) \n", "Zeit", "Temperatur","Luftdruck","Luftfeuchtigkeit");
|
||||||
|
$html .= "-----------------------------------------------------------------------\n";
|
||||||
|
if ($result != null) {
|
||||||
|
while ($obj = mysqli_fetch_object($result)) {
|
||||||
|
$html .= sprintf ("%s %6.2f °C %8.2f hPa %5d % \n", $obj->time, $obj->temperature, $obj->pressure, $obj->humidity);
|
||||||
|
}
|
||||||
|
mysqli_free_result($result); // free result set
|
||||||
|
} else { $html .= "NO - error bei query";}
|
||||||
|
$html .= "</pre>";
|
||||||
|
mysqli_close($link); // close connection
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
28
mysql_php/upload.php
Normal file
28
mysql_php/upload.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if ( isset($_GET["m"])) { $m = $_GET["m"]; } else { exit(); }
|
||||||
|
if ( isset($_GET["t"])) { $t = $_GET["t"]; } else { exit(); }
|
||||||
|
if ( isset($_GET["p"])) { $p = $_GET["p"]; } else { exit(); }
|
||||||
|
if ( isset($_GET["f"])) { $f = $_GET["f"]; } else { exit(); }
|
||||||
|
|
||||||
|
$link = mysqli_connect("localhost", "xxxxxxx", "xxxxxxx", "$m");
|
||||||
|
if (mysqli_connect_errno()) {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare an insert statement */
|
||||||
|
$ins = "INSERT INTO $m (time, temperature, pressure, humidity) VALUES (now(),?,?,?);";
|
||||||
|
$stmt = mysqli_prepare($link, $ins);
|
||||||
|
|
||||||
|
mysqli_stmt_bind_param($stmt, "ddd", $t, $p, $f);
|
||||||
|
|
||||||
|
/* Execute tne statement */
|
||||||
|
mysqli_stmt_execute($stmt);
|
||||||
|
|
||||||
|
/* close statement */
|
||||||
|
mysqli_stmt_close($stmt);
|
||||||
|
|
||||||
|
/* close connection */
|
||||||
|
mysqli_close($link); // close connection
|
||||||
|
|
||||||
|
?>
|
228
mysql_php/wetter.css
Normal file
228
mysql_php/wetter.css
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
|
||||||
|
body { font: 12px Arial;}
|
||||||
|
|
||||||
|
path {
|
||||||
|
stroke: steelblue;
|
||||||
|
stroke-width: 2;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.axis path,
|
||||||
|
.axis line {
|
||||||
|
fill: none;
|
||||||
|
stroke: grey;
|
||||||
|
stroke-width: 1;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.grid .tick {
|
||||||
|
stroke: lightgrey;
|
||||||
|
stroke-opacity: 0.7;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
.grid path {
|
||||||
|
stroke-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* **************************************************
|
||||||
|
* Darstellung Tooltipp Grundfarbe: lightsteelblue
|
||||||
|
* **************************************************
|
||||||
|
* */
|
||||||
|
|
||||||
|
div.tooltip {
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
width: 100px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 2px;
|
||||||
|
font: 12px sans-serif;
|
||||||
|
background: lightsteelblue;
|
||||||
|
border: 1px solid lightgray;
|
||||||
|
border-radius: 8px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* **************************************************
|
||||||
|
* Darstellung Temperatur Grundfarbe: lightsteelblue
|
||||||
|
* **************************************************
|
||||||
|
* */
|
||||||
|
#graphTemperature {
|
||||||
|
border: 3px solid #7070ED;
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperature .title {
|
||||||
|
background: #7070ED;
|
||||||
|
color: white;
|
||||||
|
font-size:2em;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperature .y {
|
||||||
|
fill: steelblue;
|
||||||
|
background: #7070ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperature .linecolor {
|
||||||
|
stroke: #7070ED;
|
||||||
|
stroke-width: 2;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperature .tooltip1 {
|
||||||
|
background: lightsteelblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* **************************************************
|
||||||
|
* Darstellung Luftdruck Grundfarbe: dunkelrot
|
||||||
|
* **************************************************
|
||||||
|
* */
|
||||||
|
#graphPressure {
|
||||||
|
border: 3px solid Gray;
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphPressure .title {
|
||||||
|
background: #BB0202;
|
||||||
|
color: white;
|
||||||
|
font-size:2em;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphPressure .y {
|
||||||
|
fill: #BB0202
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphPressure .linecolor {
|
||||||
|
stroke: #BB0202;
|
||||||
|
stroke-width: 2;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphPressure .tooltippfarbe{
|
||||||
|
background: #DCAFAF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* **************************************************
|
||||||
|
* Darstellung Luftfeuchtigkeit Grundfarbe: lindgrün
|
||||||
|
* **************************************************
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
#graphHumidity {
|
||||||
|
border: 3px solid #BDE7BD;
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphHumidity .title {
|
||||||
|
background: #BDE7BD;
|
||||||
|
color: gray;
|
||||||
|
font-size:2em;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphHumidity .y {
|
||||||
|
fill: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphHumidity .linecolor {
|
||||||
|
stroke: green;
|
||||||
|
stroke-width: 2;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphHumidity .tooltip {
|
||||||
|
background: #BDE7BD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* **************************************************
|
||||||
|
* Darstellung TT + P Grundfarbe: hellgrau
|
||||||
|
* **************************************************
|
||||||
|
* */
|
||||||
|
|
||||||
|
|
||||||
|
#graphTemperaturePressure {
|
||||||
|
border: 3px solid #BDE7BD;
|
||||||
|
width: 1220px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperaturePressure .title {
|
||||||
|
background: lightgray;
|
||||||
|
color: black;
|
||||||
|
font-size:2em;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperaturePressure .y1 {
|
||||||
|
fill: blue
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperaturePressure .y2 {
|
||||||
|
fill: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperaturePressure .linecolor1 {
|
||||||
|
stroke: lightsteelblue;
|
||||||
|
stroke-width: 2;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperaturePressure .linecolor2 {
|
||||||
|
stroke: red;
|
||||||
|
stroke-width: 2;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#graphTemperaturePressure .tooltip {
|
||||||
|
background: #BDE7BD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *************************************************
|
||||||
|
* Darstellung aktueller Werte
|
||||||
|
* *************************************************
|
||||||
|
*/
|
||||||
|
.messwert { float:left;
|
||||||
|
margin-right: 2px;
|
||||||
|
margin-left: 2px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 0px;
|
||||||
|
/* width:300px; */
|
||||||
|
/* background-image: url(celsius.png); */
|
||||||
|
height: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text { float:left;
|
||||||
|
font-size:5em;
|
||||||
|
padding-left:0;
|
||||||
|
color:lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {padding-left:85px;
|
||||||
|
margin-top:8px;
|
||||||
|
font-size:1.2em;
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.min {margin:2px; background-color:blue; color:white;}
|
||||||
|
|
||||||
|
.max {margin:2px; background-color:red; color:white;}
|
||||||
|
|
||||||
|
.avg {margin:2px; background-color:green; color:white;}
|
||||||
|
|
||||||
|
.aktuell {margin:2px; background-color:yellow; color:black;}
|
Loading…
Reference in New Issue
Block a user