mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
SVG.pm: log scale
git-svn-id: https://svn.fhem.de/fhem/trunk@11478 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
0c50026378
commit
b7481cac4b
@ -187,6 +187,17 @@ SVG_isEmbed($)
|
|||||||
# $FW_userAgent !~ m/(iPhone|iPad|iPod).*OS (8|9)/));
|
# $FW_userAgent !~ m/(iPhone|iPad|iPod).*OS (8|9)/));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub
|
||||||
|
SVG_log10($)
|
||||||
|
{
|
||||||
|
my ($n) = @_;
|
||||||
|
|
||||||
|
return 0.0000000001 if( $n <= 0 );
|
||||||
|
|
||||||
|
return log($n)/log(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
##################
|
##################
|
||||||
sub
|
sub
|
||||||
SVG_FwFn($$$$)
|
SVG_FwFn($$$$)
|
||||||
@ -292,7 +303,7 @@ SVG_cb($$$)
|
|||||||
{
|
{
|
||||||
my ($v,$t,$c) = @_;
|
my ($v,$t,$c) = @_;
|
||||||
$c = ($c ? " checked" : "");
|
$c = ($c ? " checked" : "");
|
||||||
return "<td>$t <input type=\"checkbox\" name=\"$v\" value=\"$v\"$c></td>";
|
return "$t <input type=\"checkbox\" name=\"$v\" value=\"$v\"$c>";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub
|
sub
|
||||||
@ -365,13 +376,17 @@ SVG_PEdit($$$$)
|
|||||||
$ret .= "</tr>";
|
$ret .= "</tr>";
|
||||||
$ret .= "<tr class=\"even\">";
|
$ret .= "<tr class=\"even\">";
|
||||||
$ret .= "<td>Grid aligned</td>";
|
$ret .= "<td>Grid aligned</td>";
|
||||||
$ret .= SVG_cb("gridy", "left", $conf{hasygrid});
|
$ret .= "<td>".SVG_cb("gridy", "left", $conf{hasygrid})."</td>";
|
||||||
$ret .= SVG_cb("gridy2","right",$conf{hasy2grid});
|
$ret .= "<td>".SVG_cb("gridy2","right",$conf{hasy2grid})."</td>";
|
||||||
$ret .= "</tr>";
|
$ret .= "</tr>";
|
||||||
$ret .= "<tr class=\"odd\">";
|
$ret .= "<tr class=\"odd\">";
|
||||||
$ret .= "<td>Range as [min:max]</td>";
|
$ret .= "<td>Range as [min:max]</td>";
|
||||||
$ret .= "<td>".SVG_txt("yrange", "left", $conf{yrange}, 16)."</td>";
|
$ret .= "<td>".SVG_txt("yrange", "left", $conf{yrange}, 16);
|
||||||
$ret .= "<td>".SVG_txt("y2range", "right", $conf{y2range}, 16)."</td>";
|
$ret .= " ".
|
||||||
|
SVG_cb("yscale", "log", $conf{yscale})."</td>";
|
||||||
|
$ret .= "<td>".SVG_txt("y2range", "right", $conf{y2range}, 16);
|
||||||
|
$ret .= " ".
|
||||||
|
SVG_cb("y2scale", "log", $conf{y2scale})."</td>";
|
||||||
$ret .= "</tr>";
|
$ret .= "</tr>";
|
||||||
if( $conf{xrange} ) {
|
if( $conf{xrange} ) {
|
||||||
$ret .= "<tr class=\"odd\"><td/><td>";
|
$ret .= "<tr class=\"odd\"><td/><td>";
|
||||||
@ -453,8 +468,8 @@ SVG_PEdit($$$$)
|
|||||||
$o .= $ph;
|
$o .= $ph;
|
||||||
$o .= "</td><td>";
|
$o .= "</td><td>";
|
||||||
my $v = $conf{lAxis}[$idx];
|
my $v = $conf{lAxis}[$idx];
|
||||||
$o .= SVG_sel("axes_${idx}", "left,right",
|
my $sel = ($v && $v eq "x1y1") ? "left" : "right";
|
||||||
($v && $v eq "x1y1") ? "left" : "right");
|
$o .= SVG_sel("axes_${idx}", "left,right,left log,right log", $sel );
|
||||||
$o .= SVG_sel("type_${idx}",
|
$o .= SVG_sel("type_${idx}",
|
||||||
"lines,points,steps,fsteps,histeps,bars,ibars,".
|
"lines,points,steps,fsteps,histeps,bars,ibars,".
|
||||||
"cubic,quadratic,quadraticSmooth",
|
"cubic,quadratic,quadraticSmooth",
|
||||||
@ -651,6 +666,8 @@ SVG_WriteGplot($)
|
|||||||
push @rows, "set xrange $FW_webArgs{xrange}" if($FW_webArgs{xrange});
|
push @rows, "set xrange $FW_webArgs{xrange}" if($FW_webArgs{xrange});
|
||||||
push @rows, "set yrange $FW_webArgs{yrange}" if($FW_webArgs{yrange});
|
push @rows, "set yrange $FW_webArgs{yrange}" if($FW_webArgs{yrange});
|
||||||
push @rows, "set y2range $FW_webArgs{y2range}" if($FW_webArgs{y2range});
|
push @rows, "set y2range $FW_webArgs{y2range}" if($FW_webArgs{y2range});
|
||||||
|
push @rows, "set yscale log" if($FW_webArgs{yscale});
|
||||||
|
push @rows, "set y2scale log" if($FW_webArgs{y2scale});
|
||||||
push @rows, "";
|
push @rows, "";
|
||||||
|
|
||||||
my @plot;
|
my @plot;
|
||||||
@ -1671,33 +1688,38 @@ SVG_render($$$$$$$$$$)
|
|||||||
my $dh = $hmax{$a} - $hmin{$a};
|
my $dh = $hmax{$a} - $hmin{$a};
|
||||||
my $hmul = $dh>0 ? $h/$dh : $h;
|
my $hmul = $dh>0 ? $h/$dh : $h;
|
||||||
|
|
||||||
|
my $idx = 1;
|
||||||
|
$idx = $1 if( $a =~ m/x\d+y(\d+)/ );
|
||||||
|
|
||||||
|
my $scale = "y".($idx)."scale";
|
||||||
|
$scale = "yscale" if( $idx == 1 );
|
||||||
|
my $log = "";
|
||||||
|
$log = $conf{$scale} if( $conf{$scale} );
|
||||||
|
|
||||||
# offsets
|
# offsets
|
||||||
my ($align,$display,$cll);
|
my ($align,$display,$cll);
|
||||||
if( $a =~ m/x1y(\d)/ ) {
|
if( $idx <= $use_left_axis ) {
|
||||||
my $idx = $1;
|
$off1 = $x - ($idx-1)*$axis_width-4-$th*0.3;
|
||||||
if( $idx <= $use_left_axis ) {
|
$off3 = $x - ($idx-1)*$axis_width-4;
|
||||||
$off1 = $x - ($idx-1)*$axis_width-4-$th*0.3;
|
$off4 = $off3+5;
|
||||||
$off3 = $x - ($idx-1)*$axis_width-4;
|
$align = " text-anchor=\"end\"";
|
||||||
$off4 = $off3+5;
|
$display = "";
|
||||||
$align = " text-anchor=\"end\"";
|
$cll = "";
|
||||||
$display = "";
|
} elsif( $idx <= $use_left_axis+$use_right_axis ) {
|
||||||
$cll = "";
|
$off1 = $x+4+$w+($idx-1-$use_left_axis)*$axis_width+$th*0.3;
|
||||||
} elsif( $idx <= $use_left_axis+$use_right_axis ) {
|
$off3 = $x+4+$w+($idx-1-$use_left_axis)*$axis_width-5;
|
||||||
$off1 = $x+4+$w+($idx-1-$use_left_axis)*$axis_width+$th*0.3;
|
$off4 = $off3+5;
|
||||||
$off3 = $x+4+$w+($idx-1-$use_left_axis)*$axis_width-5;
|
$align = "";
|
||||||
$off4 = $off3+5;
|
$display = "";
|
||||||
$align = "";
|
$cll = "";
|
||||||
$display = "";
|
} else {
|
||||||
$cll = "";
|
$off1 = $x-$th*0.3+30;
|
||||||
} else {
|
$off3 = $x+30;
|
||||||
$off1 = $x-$th*0.3+30;
|
$off4 = $off3+5;
|
||||||
$off3 = $x+30;
|
$align = " text-anchor=\"end\"";
|
||||||
$off4 = $off3+5;
|
$display = " display=\"none\" id=\"hline_$idx\"";
|
||||||
$align = " text-anchor=\"end\"";
|
$cll = " class=\"SVGplot l$idx\"";
|
||||||
$display = " display=\"none\" id=\"hline_$idx\"";
|
}
|
||||||
$cll = " class=\"SVGplot l$idx\"";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#-- grouping
|
#-- grouping
|
||||||
SVG_pO "<g$display>";
|
SVG_pO "<g$display>";
|
||||||
@ -1712,13 +1734,21 @@ SVG_render($$$$$$$$$$)
|
|||||||
#-- tics as in the config-file
|
#-- tics as in the config-file
|
||||||
if($tic && $tic !~ m/mirror/) {
|
if($tic && $tic !~ m/mirror/) {
|
||||||
$tic =~ s/^\((.*)\)$/$1/; # Strip ()
|
$tic =~ s/^\((.*)\)$/$1/; # Strip ()
|
||||||
|
for(my $decimal = 0;
|
||||||
|
$decimal < ($log eq 'log'?SVG_log10($hmax{$a}):1);
|
||||||
|
$decimal++ ) {
|
||||||
|
my $f = SVG_log10($hmax{$a}) / $hmax{$a};
|
||||||
foreach my $onetic (split(",", $tic)) {
|
foreach my $onetic (split(",", $tic)) {
|
||||||
$onetic =~ s/^ *(.*) *$/$1/;
|
$onetic =~ s/^ *(.*) *$/$1/;
|
||||||
my ($tlabel, $tvalue) = split(" ", $onetic);
|
my ($tlabel, $tvalue) = split(" ", $onetic);
|
||||||
$tlabel =~ s/^"(.*)"$/$1/;
|
$tlabel =~ s/^"(.*)"$/$1/;
|
||||||
$tvalue = 0 if( !$tvalue );
|
$tvalue = 0 if( !$tvalue );
|
||||||
|
$tvalue /= 10 ** $decimal;
|
||||||
|
$tlabel = $tvalue if( !$tlabel );
|
||||||
|
|
||||||
$off2 = int($y+($hmax{$a}-$tvalue)*$hmul);
|
$off2 = int($y+($hmax{$a}-$tvalue)*$hmul);
|
||||||
|
$off2 = int($y+($hmax{$a}-SVG_log10($tvalue)/$f)*$hmul)
|
||||||
|
if( $log eq 'log' );
|
||||||
#-- tics
|
#-- tics
|
||||||
SVG_pO "<polyline points=\"$off3,$off2 $off4,$off2\" $cll/>";
|
SVG_pO "<polyline points=\"$off3,$off2 $off4,$off2\" $cll/>";
|
||||||
#--grids
|
#--grids
|
||||||
@ -1732,12 +1762,20 @@ SVG_render($$$$$$$$$$)
|
|||||||
}
|
}
|
||||||
$off2 += $th/4;
|
$off2 += $th/4;
|
||||||
#-- text
|
#-- text
|
||||||
SVG_pO "<text x=\"$off1\" y=\"$off2\" class=\"ylabel\"$align>$tlabel</text>";
|
SVG_pO
|
||||||
|
"<text x=\"$off1\" y=\"$off2\" class=\"ylabel\"$align>$tlabel</text>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#-- tics automatically
|
#-- tics automatically
|
||||||
} elsif( $hstep{$a}>0 ) {
|
} elsif( $hstep{$a}>0 ) {
|
||||||
|
for(my $decimal = 0;
|
||||||
|
$decimal < ($log eq 'log'?SVG_log10($hmax{$a}):1);
|
||||||
|
$decimal++ ) {
|
||||||
|
my $f = SVG_log10($hmax{$a}) / $hmax{$a};
|
||||||
for(my $i = $hmin{$a}; $i <= $hmax{$a}; $i += $hstep{$a}) {
|
for(my $i = $hmin{$a}; $i <= $hmax{$a}; $i += $hstep{$a}) {
|
||||||
|
my $i = $i / 10 ** $decimal;
|
||||||
$off2 = int($y+($hmax{$a}-$i)*$hmul);
|
$off2 = int($y+($hmax{$a}-$i)*$hmul);
|
||||||
|
$off2 = int($y+($hmax{$a}-SVG_log10($i)/$f)*$hmul) if( $log eq 'log' );
|
||||||
#-- tics
|
#-- tics
|
||||||
SVG_pO " <polyline points=\"$off3,$off2 $off4,$off2\" $cll/>";
|
SVG_pO " <polyline points=\"$off3,$off2 $off4,$off2\" $cll/>";
|
||||||
#--grids
|
#--grids
|
||||||
@ -1753,7 +1791,9 @@ SVG_render($$$$$$$$$$)
|
|||||||
$off2 += $th/4;
|
$off2 += $th/4;
|
||||||
#-- text
|
#-- text
|
||||||
my $txt = sprintf("%g", $i);
|
my $txt = sprintf("%g", $i);
|
||||||
SVG_pO "<text x=\"$off1\" y=\"$off2\" class=\"ylabel\"$align>$txt</text>";
|
SVG_pO
|
||||||
|
"<text x=\"$off1\" y=\"$off2\" class=\"ylabel\"$align>$txt</text>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SVG_pO "</g>";
|
SVG_pO "</g>";
|
||||||
@ -1764,6 +1804,10 @@ SVG_render($$$$$$$$$$)
|
|||||||
# Second loop over the data: draw the measured points
|
# Second loop over the data: draw the measured points
|
||||||
for(my $idx=$#hdx; $idx >= 0; $idx--) {
|
for(my $idx=$#hdx; $idx >= 0; $idx--) {
|
||||||
my $a = $conf{lAxis}[$idx];
|
my $a = $conf{lAxis}[$idx];
|
||||||
|
my $scale = "y".($idx+1)."scale";
|
||||||
|
$scale = "yscale" if( $idx == 0 );
|
||||||
|
my $log = "";
|
||||||
|
$log = $conf{$scale} if( $conf{$scale} );
|
||||||
|
|
||||||
SVG_pO "<!-- Warning: No axis for data item $idx defined -->"
|
SVG_pO "<!-- Warning: No axis for data item $idx defined -->"
|
||||||
if(!defined($a));
|
if(!defined($a));
|
||||||
@ -1778,6 +1822,13 @@ SVG_render($$$$$$$$$$)
|
|||||||
SVG_pO "<!-- Warning: No data item $idx defined -->" if(!defined($dxp));
|
SVG_pO "<!-- Warning: No data item $idx defined -->" if(!defined($dxp));
|
||||||
next if(!defined($dxp));
|
next if(!defined($dxp));
|
||||||
|
|
||||||
|
if( $log eq 'log' ) {
|
||||||
|
my $f = SVG_log10($hmax{$a}) / $hmax{$a};
|
||||||
|
foreach my $i (1..int(@{$dxp})-1) {
|
||||||
|
$dyp->[$i] = SVG_log10($dyp->[$i]) / $f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $yh = $y+$h;
|
my $yh = $y+$h;
|
||||||
#-- Title attributes
|
#-- Title attributes
|
||||||
my $tl = $conf{lTitle}[$idx] ? $conf{lTitle}[$idx] : "";
|
my $tl = $conf{lTitle}[$idx] ? $conf{lTitle}[$idx] : "";
|
||||||
@ -1785,8 +1836,11 @@ SVG_render($$$$$$$$$$)
|
|||||||
my $dec = length(sprintf("%d",$hmul*3))-1;
|
my $dec = length(sprintf("%d",$hmul*3))-1;
|
||||||
$dec = 0 if($dec < 0);
|
$dec = 0 if($dec < 0);
|
||||||
my $attributes = "id=\"line_$idx\" decimals=\"$dec\" ".
|
my $attributes = "id=\"line_$idx\" decimals=\"$dec\" ".
|
||||||
"x_off=\"$fromsec\" x_min=\"$x\" x_mul=\"$tmul\" ".
|
"x_min=\"$x\" ".
|
||||||
|
($conf{xrange}?"x_off=\"$xmin\" ":"x_off=\"$fromsec\" ").
|
||||||
|
($conf{xrange}?"x_mul=\"$xmul\" ":"t_mul=\"$tmul\" ").
|
||||||
"y_h=\"$yh\" y_min=\"$min\" y_mul=\"$hmul\" title=\"$tl\" ".
|
"y_h=\"$yh\" y_min=\"$min\" y_mul=\"$hmul\" title=\"$tl\" ".
|
||||||
|
($log eq 'log'?"log_scale=\"".SVG_log10($hmax{$a})/$hmax{$a}."\" ":"").
|
||||||
"onclick=\"parent.svg_click(evt)\" $conf{lWidth}[$idx]";
|
"onclick=\"parent.svg_click(evt)\" $conf{lWidth}[$idx]";
|
||||||
my $lStyle = $conf{lStyle}[$idx];
|
my $lStyle = $conf{lStyle}[$idx];
|
||||||
my $isFill = ($conf{lStyle}[$idx] =~ m/fill/);
|
my $isFill = ($conf{lStyle}[$idx] =~ m/fill/);
|
||||||
@ -1965,7 +2019,6 @@ SVG_render($$$$$$$$$$)
|
|||||||
|
|
||||||
next if($x1 == $lx && $y1 == $ly);
|
next if($x1 == $lx && $y1 == $ly);
|
||||||
|
|
||||||
|
|
||||||
# calc ymin/ymax for points with the same x coordinates
|
# calc ymin/ymax for points with the same x coordinates
|
||||||
if($x1 == $lx && $i < $maxIdx) {
|
if($x1 == $lx && $i < $maxIdx) {
|
||||||
$ymin = $y1 if($y1 < $ymin);
|
$ymin = $y1 if($y1 < $ymin);
|
||||||
|
@ -42,7 +42,8 @@ svg_load(key, nextFn)
|
|||||||
function
|
function
|
||||||
svg_prepareHash(el)
|
svg_prepareHash(el)
|
||||||
{
|
{
|
||||||
var obj = { y_mul:0,y_h:0,y_min:0, decimals:0, x_mul:0,x_off:0,x_min:0 };
|
var obj = { y_mul:0,y_h:0,y_min:0, decimals:0,
|
||||||
|
t_mul:0,x_off:0,x_min:0, x_mul:0, log_scale:undefined };
|
||||||
for(var name in obj)
|
for(var name in obj)
|
||||||
obj[name] = parseFloat($(el).attr(name));
|
obj[name] = parseFloat($(el).attr(name));
|
||||||
return obj;
|
return obj;
|
||||||
@ -55,7 +56,7 @@ svg_click(evt)
|
|||||||
var o = svg_prepareHash(t);
|
var o = svg_prepareHash(t);
|
||||||
|
|
||||||
var y_org = (((o.y_h-evt.clientY)/o.y_mul)+o.y_min).toFixed(o.decimals);
|
var y_org = (((o.y_h-evt.clientY)/o.y_mul)+o.y_min).toFixed(o.decimals);
|
||||||
var d = new Date((((evt.clientX-o.x_min)/o.x_mul)+o.x_off) * 1000);
|
var d = new Date((((evt.clientX-o.x_min)/o.t_mul)+o.x_off) * 1000);
|
||||||
var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
|
var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
|
||||||
(d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
(d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
|
||||||
|
|
||||||
@ -254,15 +255,27 @@ sv_menu(evt, embed)
|
|||||||
var xR = (xRaw-pp.x)/(pn.x-pp.x); // Compute interim values
|
var xR = (xRaw-pp.x)/(pn.x-pp.x); // Compute interim values
|
||||||
var yRaw = pp.y+xR*(pn.y-pp.y);
|
var yRaw = pp.y+xR*(pn.y-pp.y);
|
||||||
|
|
||||||
var y = (((par.y_h-yRaw)/par.y_mul)+par.y_min).toFixed(par.decimals);
|
var y = (((par.y_h-yRaw)/par.y_mul)+par.y_min);
|
||||||
|
|
||||||
|
if( par.log_scale ) {
|
||||||
|
y *= par.log_scale;
|
||||||
|
y = Math.pow(10,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
y = y.toFixed(par.decimals);
|
||||||
|
|
||||||
|
if( par.x_mul ) {
|
||||||
|
ts = (((xRaw-par.x_min)/par.x_mul)+par.x_off).toFixed(par.decimals);
|
||||||
|
|
||||||
var d = new Date((((xRaw-par.x_min)/par.x_mul)+par.x_off) * 1000), ts;
|
|
||||||
if(par.x_mul < 0.0001) { // Year
|
|
||||||
ts = (d.getMonth()+1)+"."+pad0(d.getDate());
|
|
||||||
} else if(par.x_mul < 0.001) { // Month
|
|
||||||
ts = d.getDate()+". "+pad0(d.getHours())+":"+pad0(d.getMinutes());
|
|
||||||
} else {
|
} else {
|
||||||
ts = pad0(d.getHours())+":"+pad0(d.getMinutes());
|
var d = new Date((((xRaw-par.x_min)/par.t_mul)+par.x_off) * 1000), ts;
|
||||||
|
if(par.t_mul < 0.0001) { // Year
|
||||||
|
ts = (d.getMonth()+1)+"."+pad0(d.getDate());
|
||||||
|
} else if(par.t_mul < 0.001) { // Month
|
||||||
|
ts = d.getDate()+". "+pad0(d.getHours())+":"+pad0(d.getMinutes());
|
||||||
|
} else {
|
||||||
|
ts = pad0(d.getHours())+":"+pad0(d.getMinutes());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$(par.circle).attr("cx", xRaw).attr("cy", yRaw);
|
$(par.circle).attr("cx", xRaw).attr("cy", yRaw);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user