diff --git a/fhem/CHANGED b/fhem/CHANGED
index 0a2c63826..a19c6f3f3 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -584,3 +584,4 @@
- feature: CUL: sendpool attribute
- feature: CUL_HOERMANN module added
- bugfix: DST change: absolute at and relative sunrise fix
+ - feature: FHEMWEB javascript additions for SVG plots (click on lines/labels)
diff --git a/fhem/webfrontend/pgm2/01_FHEMWEB.pm b/fhem/webfrontend/pgm2/01_FHEMWEB.pm
index 6b362266a..66a0debab 100755
--- a/fhem/webfrontend/pgm2/01_FHEMWEB.pm
+++ b/fhem/webfrontend/pgm2/01_FHEMWEB.pm
@@ -183,6 +183,12 @@ FW_Read($)
}
}
+ # This is a hack... Dont want to do it each time after a fork.
+ if(!$modules{SVG}{LOADED}) {
+ my $ret = CommandReload(undef, "98_SVG");
+ Log 0, $ret if($ret);
+ }
+
# Data from HTTP Client
my $buf;
my $ret = sysread($hash->{CD}, $buf, 1024);
diff --git a/fhem/webfrontend/pgm2/98_SVG.pm b/fhem/webfrontend/pgm2/98_SVG.pm
index 4a3e5363d..a8739169a 100755
--- a/fhem/webfrontend/pgm2/98_SVG.pm
+++ b/fhem/webfrontend/pgm2/98_SVG.pm
@@ -12,6 +12,7 @@ sub SVG_render($$$$$$);
sub time_to_sec($);
sub fmtTime($$);
+
my ($__lt, $__ltstr);
#####################################
@@ -51,37 +52,37 @@ SVG_render($$$$$$)
my ($w, $h) = ($ow-2*$x, $oh-2*$y); # Rect size
# Html Header
- pO "\n";
- pO "\n";
- pO "\n";
- pO "";
return;
}
@@ -209,8 +202,8 @@ SVG_render($$$$$$)
for(my $i = $fromsec+$initoffset; $i < $tosec; $i += $tstep) {
$i = time_align($i,$aligntics);
$off1 = int($x+($i-$fromsec)*$tmul);
- pO "\n";
- pO "\n";
+ pO "";
+ pO "";
}
# then the text and the grid
@@ -223,10 +216,10 @@ SVG_render($$$$$$)
for(my $i = $fromsec+$initoffset; $i < $tosec; $i += $step) {
$i = time_align($i,$aligntext);
$off1 = int($x+($i-$fromsec)*$tmul);
- pO "\n";
$t = fmtTime($tag, $i);
- pO "$t";
+ pO "$t";
+ pO " ";
}
@@ -284,7 +277,7 @@ SVG_render($$$$$$)
$tlabel =~ s/^"(.*)"$/$1/;
$off2 = int($y+($ma-$tvalue)*$hmul);
- pO "\n";
+ pO "";
$off2 += $th/4;
my $align = ($axis eq "x1y1" ? " text-anchor=\"end\"" : "");
pO "
@@ -295,10 +288,11 @@ SVG_render($$$$$$)
for(my $i = $mi; $i <= $ma; $i += $step) {
$off2 = int($y+($ma-$i)*$hmul);
- pO "\n";
+ pO " ";
if($axis eq "x1y2") {
my $o6 = $x+$w;
- pO "\n";
+ pO " "
+ if($i > $mi && $i < $ma);
}
$off2 += $th/4;
my $align = ($axis eq "x1y1" ? " text-anchor=\"end\"" : "");
@@ -313,6 +307,7 @@ SVG_render($$$$$$)
# Second loop over the data: draw the measured points
for my $idx (0..int(@hdx)-1) {
my $a = $axes[$idx];
+
next if(!defined($a));
$min = $hmin{$a};
$hmax{$a} += 1 if($min == $hmax{$a}); # Else division by 0 in the next line
@@ -321,6 +316,15 @@ SVG_render($$$$$$)
my ($dxp, $dyp) = ($hdx[$idx], $hdy[$idx]);
next if(!defined($dxp));
+ my $yh = $y+$h;
+ my $tl = $ltitle[$idx] ? $ltitle[$idx] : "";
+ my $dec = int(log($hmul*3)/log(10));
+ $dec = 0 if($dec < 0);
+ my $js_helpers = "id=\"line_$idx\" decimals=\"$dec\" ".
+ "x_off=\"$fromsec\" x_min=\"$x\" x_mul=\"$tmul\" ".
+ "y_h=\"$yh\" y_min=\"$min\" y_mul=\"$hmul\" title=\"$tl\" ".
+ "onclick=\"svg_click(evt)\"";
+
my ($lx, $ly) = (-1,-1);
if($type[$idx] eq "points" ) {
@@ -331,7 +335,7 @@ SVG_render($$$$$$)
$ly = $x1; $ly = $y1;
$ret = sprintf(" %d,%d %d,%d %d,%d %d,%d %d,%d",
$x1-3,$y1, $x1,$y1-3, $x1+3,$y1, $x1,$y1+3, $x1-3,$y1);
- pO "\n";
+ pO "";
}
} elsif($type[$idx] eq "steps" || $type[$idx] eq "fsteps" ) {
@@ -353,7 +357,7 @@ SVG_render($$$$$$)
}
}
}
- pO "\n";
+ pO "";
} elsif($type[$idx] eq "histeps" ) {
if(@{$dxp} == 1) {
@@ -370,7 +374,7 @@ SVG_render($$$$$$)
$x1,$y1, ($x1+$x2)/2,$y1, ($x1+$x2)/2,$y2, $x2,$y2);
}
}
- pO "\n";
+ pO "";
} else { # lines and everything else
foreach my $i (0..int(@{$dxp})-1) {
@@ -380,11 +384,13 @@ SVG_render($$$$$$)
$lx = $x1; $ly = $y1;
$ret .= sprintf(" %d,%d", $x1, $y1);
}
- pO "\n";
+
+ pO "";
+
}
}
- pO "\n";
+ pO "";
}
sub
diff --git a/fhem/webfrontend/pgm2/svg.js b/fhem/webfrontend/pgm2/svg.js
new file mode 100644
index 000000000..a21915988
--- /dev/null
+++ b/fhem/webfrontend/pgm2/svg.js
@@ -0,0 +1,46 @@
+var old_title;
+var old_sel;
+
+function
+svg_labelselect(evt)
+{
+ var sel = document.getElementById(evt.target.getAttribute("line_id"));
+ var tl = document.getElementById("svg_title");
+
+ if(old_sel == sel) {
+ sel.setAttribute("stroke-width", 1);
+ old_sel = null;
+ tl.firstChild.nodeValue = old_title;
+
+ } else {
+ if(old_sel == null)
+ old_title = tl.firstChild.nodeValue;
+ else
+ old_sel.setAttribute("stroke-width", 1);
+ sel.setAttribute("stroke-width", 3);
+ old_sel = sel;
+ tl.firstChild.nodeValue = evt.target.getAttribute("title");
+
+ }
+}
+
+function
+svg_click(evt)
+{
+ var t=evt.target;
+ var y_mul = parseFloat(t.getAttribute("y_mul"));
+ var y_h = parseFloat(t.getAttribute("y_h"));
+ var y_min = parseFloat(t.getAttribute("y_min"));
+ var y_fx = parseFloat(t.getAttribute("decimals"));
+ var y_org = (((y_h-evt.clientY)/y_mul)+y_min).toFixed(y_fx);
+
+ var x_mul = parseFloat(t.getAttribute("x_mul"));
+ var x_off = parseFloat(t.getAttribute("x_off"));
+ var x_min = parseFloat(t.getAttribute("x_min"));
+ var d = new Date((((evt.clientX-x_min)/x_mul)+x_off) * 1000);
+ var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
+ (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
+
+ var tl = document.getElementById('svg_title');
+ tl.firstChild.nodeValue = t.getAttribute("title")+": "+y_org+" ("+ts+")";
+}
diff --git a/fhem/webfrontend/pgm2/svg_style.css b/fhem/webfrontend/pgm2/svg_style.css
index e22f5a74e..3f80426fe 100644
--- a/fhem/webfrontend/pgm2/svg_style.css
+++ b/fhem/webfrontend/pgm2/svg_style.css
@@ -3,7 +3,7 @@ text.title { font-size:16px; }
rect.border { stroke:black; stroke-width:1px; fill:none; }
-polyline { stroke:black; stroke-width:1px; fill:none; }
+polyline { stroke:black; fill:none; }
.vgrid { stroke-dasharray:2,6; stroke:gray; }
.hgrid { stroke-dasharray:2,6; stroke:gray; }