2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

98_SVG.pm: rewrite the log scale version (Forum #112509)

git-svn-id: https://svn.fhem.de/fhem/trunk@22349 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2020-07-05 13:08:43 +00:00
parent 2b91cc4245
commit 0b5da07c22
3 changed files with 63 additions and 64 deletions

View File

@ -959,7 +959,7 @@ RESCAN:
}
next if(!defined($val) || $val !~ m/^-?[.\d]+$/o);
next if(!defined($val) || $val !~ m/^-?[.0-9]+(e[-+0-9]+)?$/i);
if($val < $min[$i]) {
$min[$i] = $val;
$mind[$i] = $dte;

View File

@ -203,9 +203,15 @@ SVG_log10($)
{
my ($n) = @_;
return 0.0000000001 if( $n <= 0 );
$n = 0.0000000001 if($n <= 0);
return log($n)/log(10);
}
return log(1+$n)/log(10);
sub
SVG_exp10($)
{
my ($n) = @_;
return 10**$n;
}
@ -766,7 +772,7 @@ SVG_readgplotfile($$$)
{
return "%$_[0]%" if(!$pr);
my $v = $pr->{$_[0]};
return "%$_[0]%" if(!$v);
return "%$_[0]%" if(!defined($v));
if($v =~ m/^{.*}$/) {
$cmdFromAnalyze = $v;
return eval $v;
@ -1760,6 +1766,12 @@ SVG_render($$$$$$$$$$)
$htics{$a} = defined($conf{$yt}) ? $conf{$yt} : "";
#-- Round values, compute a nice step
my $scale = $conf{"y".($idx ? $idx+1:"")."scale"};
$scale = "" if(!defined($scale));
if($scale eq "log") {
$hmax{$a} = SVG_log10($hmax{$a});
$hmin{$a} = SVG_log10($hmin{$a});
}
($hstep{$a}, $hmin{$a}, $hmax{$a}) =
SVG_getSteps($conf{$yra},$hmin{$a},$hmax{$a});
@ -1772,25 +1784,15 @@ SVG_render($$$$$$$$$$)
next if(!defined($hmin{$a})); # Bogus case
#-- safeguarding against pathological data
if( !$hstep{$a} ){
$hmax{$a} = $hmin{$a}+1;
$hstep{$a} = 1;
}
my $axis = 1;
$axis = $1 if( $a =~ m/x\d+y(\d+)/ );
my $scale = $conf{"y".($axis==1?"":$axis)."scale"};
$scale = "" if(!defined($scale));
#-- Draw the y-axis values and grid
my $dh = $hmax{$a} - $hmin{$a};
my $hmul = $dh>0 ? $h/$dh : $h;
my $axis = 1;
$axis = $1 if( $a =~ m/x\d+y(\d+)/ );
my $scale = "y".($axis)."scale"; $scale = "yscale" if( $axis == 1 );
my $log = ""; $log = $conf{$scale} if( $conf{$scale} );
my $f_log = (int($hmax{$a}) && $dh > 0) ?
((SVG_log10($hmax{$a})-SVG_log10($hmin{$a})) / $dh) :
1;
# offsets
my ($align,$display,$cll);
if( $axis <= $use_left_axis ) {
@ -1827,23 +1829,18 @@ SVG_render($$$$$$$$$$)
#-- tics handling
my $tic = $htics{$a};
#-- tics as in the config-file
if($tic && $tic !~ m/mirror/) {
if($tic) {
$tic =~ s/^\((.*)\)$/$1/; # Strip ()
for(my $decimal = 0;
$decimal <($log eq 'log'?SVG_log10($hmax{$a})-SVG_log10($hmin{$a}):1);
$decimal++) {
foreach my $onetic (split(",", $tic)) {
last if($onetic eq "nomirror");
$onetic =~ s/^ *(.*) *$/$1/;
my ($tlabel, $tvalue) = split(" ", $onetic);
$tlabel =~ s/^"(.*)"$/$1/;
$tvalue = 0 if( !$tvalue );
$tvalue /= 10 ** $decimal;
$tlabel = $tvalue if( !$tlabel );
$tvalue = SVG_log10($tvalue) if($scale eq "log");
$off2 = int($y+($hmax{$a}-$tvalue)*$hmul);
$off2 = int($y+($hmax{$a}-
(SVG_log10($tvalue)-SVG_log10($hmin{$a}))/$f_log)*$hmul)
if( $log eq 'log' );
#-- tics
SVG_pO "<polyline points=\"$off3,$off2 $off4,$off2\" $cll/>";
#--grids
@ -1860,22 +1857,11 @@ SVG_render($$$$$$$$$$)
SVG_pO
"<text x=\"$off1\" y=\"$off2\" class=\"ylabel\"$align>$tlabel</text>";
}
}
#-- tics automatically
} elsif( $hstep{$a}>0 ) {
for(my $decimal = 0;
$decimal <($log eq 'log'?SVG_log10($hmax{$a})-SVG_log10($hmin{$a}):1);
$decimal++) {
for(my $i = ($log eq 'log' ? 0 : $hmin{$a});
$i <= $hmax{$a}; $i += $hstep{$a}) {
my $i = $i / 10 ** $decimal;
if( $log eq 'log' ) {
next if( $i < $hmin{$a} );
$off2 = int($y + ($hmax{$a} -
(SVG_log10($i) - SVG_log10($hmin{$a})) / $f_log) * $hmul);
} else {
$off2 = int($y+($hmax{$a}-$i)*$hmul);
}
} elsif( $hstep{$a}>0 ) {
for(my $i = $hmin{$a}; $i <= $hmax{$a}; $i += $hstep{$a}) {
$off2 = int($y+($hmax{$a}-$i)*$hmul);
#-- tics
SVG_pO " <polyline points=\"$off3,$off2 $off4,$off2\" $cll/>";
#--grids
@ -1891,11 +1877,12 @@ SVG_render($$$$$$$$$$)
$off2 += $th/4;
#-- text
my $name = ($axis==1 ? "y":"y$axis")."sprintf"; # Forum #88460
my $txt = sprintf($conf{$name} ? $conf{$name} : "%g", $i);
my $txt = sprintf($conf{$name} ? $conf{$name} :
($scale eq "log" ? "%0.0e" : "%g"),
($scale eq "log" ? SVG_exp10($i) : $i));
SVG_pO
"<text x=\"$off1\" y=\"$off2\" class=\"ylabel\"$align>$txt</text>";
}
}
}
SVG_pO "</g>";
@ -1911,8 +1898,8 @@ SVG_render($$$$$$$$$$)
next if(!defined($a));
my $axis = 1; $axis = $1 if( $a =~ m/x\d+y(\d+)/ );
my $scale = "y".($axis)."scale"; $scale = "yscale" if( $axis == 1 );
my $log = ""; $log = $conf{$scale} if( $conf{$scale} );
my $scale = $conf{"y".($axis==1?"":$axis)."scale"};
$scale = "" if(!defined($scale));
$min = $hmin{$a};
$hmax{$a} += 1 if($min == $hmax{$a}); # Else division by 0 in the next line
@ -1925,11 +1912,9 @@ SVG_render($$$$$$$$$$)
SVG_pO "<!-- Warning: No data item $idx defined -->" if(!defined($dxp));
next if(!defined($dxp));
my $f_log = int($hmax{$a}) ? ((SVG_log10($hmax{$a}) -
SVG_log10($hmin{$a})) / ($hmax{$a}-$hmin{$a})) : 1;
if( $log eq 'log' ) {
if($scale eq 'log') {
foreach my $i (0..int(@{$dyp})-1) {
$dyp->[$i] = (SVG_log10($dyp->[$i])-SVG_log10($hmin{$a})) / $f_log;
$dyp->[$i] = SVG_log10($dyp->[$i]);
}
}
@ -1945,7 +1930,7 @@ SVG_render($$$$$$$$$$)
($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\" ".
($log eq 'log'?"log_scale=\"$f_log\" ":"").
"scale=\"$scale\" ".
"onclick=\"parent.svg_click(evt)\"";
my $lStyle = $conf{lStyle}[$idx];
my $isFill = ($conf{lStyle}[$idx] =~ m/fill/);

View File

@ -53,10 +53,12 @@ function
svg_prepareHash(el)
{
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 };
t_mul:0,x_off:0,x_min:0, x_mul:0, scale:"" };
for(var name in obj) {
var n = $(el).attr(name);
if(n)
if(name == "scale" && n)
obj[name] = n;
else if(n)
obj[name] = parseFloat(n);
}
return obj;
@ -76,7 +78,12 @@ svg_click(evt)
y -= off.top;
}
var y_org = (((o.y_h-y)/o.y_mul)+o.y_min).toFixed(o.decimals);
var y_org = (((o.y_h-y)/o.y_mul)+o.y_min);
if(o.scale == "log")
y_org = Math.pow(10,y_org);
else
y_org = y_org.toFixed(o.decimals);
var d = new Date((((x-o.x_min)/o.t_mul)+o.x_off) * 1000);
var ts = (d.getHours() < 10 ? '0' : '') + d.getHours() + ":"+
(d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
@ -119,6 +126,12 @@ sv_menu(evt, embed)
return { x:parseFloat(xy[0]), y:parseFloat(xy[1]) };
}
}
var embedOffsetY = 0;
if(embed) {
var name = $(evt.target).parent("svg").attr("id").substr(8);
embedOffsetY = $("div.SVGplot.SVG_"+name).offset().top;
}
function
showValOff() {
@ -251,7 +264,6 @@ sv_menu(evt, embed)
$(svg).append(par.circle);
par.div = $('<div id="svgmarker">');
par.divoffY = -50;
var parent = (embed ? $(embed).parent() : $(svg).parent());
$(parent).append(par.div);
@ -300,14 +312,10 @@ sv_menu(evt, embed)
var y = (((par.y_h-yRaw)/par.y_mul)+par.y_min);
if( par.log_scale ) {
y *= par.log_scale;
if( par.y_min )
y += Math.log(par.y_min)/Math.log(10);
if(par.scale == "log")
y = Math.pow(10,y);
}
y = y.toFixed(par.decimals);
else
y = y.toFixed(par.decimals);
if(selNode.isInt) {
if(selNode.clicked) {
@ -347,7 +355,13 @@ sv_menu(evt, embed)
}
$(par.circle).attr("cx", xRaw).attr("cy", yRaw);
var yd = Math.floor((yRaw+par.divoffY) / 20)*20;
var yd = Math.floor(yRaw / 20)*20;
if(embed)
yd += embedOffsetY-90;
else
yd += $(svg).offset().top-90;
$(par.div).html(ts+" "+y)
.css({ left:xRaw-20, top:yd });
}
@ -380,8 +394,8 @@ sv_menu(evt, embed)
function
animateVisibility(sel, currval, maxval)
{
var h = parseFloat(sel.attr("y_h"));
sel.attr("transform", "translate(0,"+h*(1-currval)+") "+
var h = parseFloat(sel.attr("y_h"));
sel.attr("transform", "translate(0,"+h*(1-currval)+") "+
"scale(1,"+currval+")");
if(currval != maxval) {