# HG changeset patch
# User Edouard Tisserant
# Date 1654067659 -7200
# Node ID a27b5862e36394243e70356c9cce019013aeb607
# Parent 9d895a1030190297d10fc1b4edc40ef0e1a56b45
SVGHMI: Add support for fixed X range (duration) on XY garph.
diff -r 9d895a103019 -r a27b5862e363 svghmi/widget_xygraph.ysl2
--- a/svghmi/widget_xygraph.ysl2 Wed Jun 01 09:12:59 2022 +0200
+++ b/svghmi/widget_xygraph.ysl2 Wed Jun 01 09:14:19 2022 +0200
@@ -22,20 +22,35 @@
path name="value" count="1+" accepts="HMI_INT,HMI_REAL" > value
- arg name="size" accepts="int" > buffer size
+ arg name="xrange" accepts="int,time" > X axis range expressed either in samples or duration.
arg name="xformat" count="optional" accepts="string" > format string for X label
arg name="yformat" count="optional" accepts="string" > format string for Y label
- arg name="ymin" count="optional" accepts="int,real" > minimum value foe Y axis
- arg name="ymax" count="optional" accepts="int,real" > maximum value for Y axis
}
widget_class("XYGraph") {
||
frequency = 1;
init() {
- [this.x_size,
+ let x_duration_s;
+ [x_duration_s,
this.x_format, this.y_format] = this.args;
+ let timeunit = x_duration_s.slice(-1);
+ let factor = {
+ "s":1,
+ "m":60,
+ "h":3600,
+ "d":86400}[timeunit];
+ if(factor == undefined){
+ this.max_data_length = Number(x_duration_s);
+ this.x_duration = undefined;
+ }else{
+ let duration = factor*Number(x_duration_s.slice(0,-1));
+ this.max_data_length = undefined;
+ this.x_duration = duration*1000;
+ }
+
+
// Min and Max given with paths are meant to describe visible range,
// not to clip data.
this.clip = false;
@@ -97,7 +112,6 @@
}
this.curves_data = this.curves.map(_unused => []);
- this.max_data_length = this.args[0];
}
dispatch(value,oldval, index) {
@@ -114,13 +128,24 @@
let ymax_damaged = false;
let overflow;
- if(data_length > this.max_data_length){
- // remove first item
- [this.xmin, overflow] = this.curves_data[index].shift();
- data_length = data_length - 1;
+ if(this.max_data_length == undefined){
+ let peremption = time - this.x_duration;
+ let oldest = this.curves_data[index][0][0]
+ this.xmin = peremption;
+ if(oldest < peremption){
+ // remove first item
+ overflow = this.curves_data[index].shift()[1];
+ data_length = data_length - 1;
+ }
} else {
- if(this.xmin == undefined){
- this.xmin = time;
+ if(data_length > this.max_data_length){
+ // remove first item
+ [this.xmin, overflow] = this.curves_data[index].shift();
+ data_length = data_length - 1;
+ } else {
+ if(this.xmin == undefined){
+ this.xmin = time;
+ }
}
}
@@ -141,6 +166,7 @@
}
let Yrange = this.ymax - this.ymin;
+ // apply margin by moving min and max to enlarge range
let [xMargin,yMargin] = zip(this.Margins, [Xrange, Yrange]).map(([m,l]) => m*l);
[[this.dxmin, this.dxmax],[this.dymin,this.dymax]] =
[[this.xmin-xMargin, this.xmax+xMargin],
@@ -163,6 +189,7 @@
let px = base_point.x + xv.x + yv.x;
let py = base_point.y + xv.y + yv.y;
if(!this.fixed_y_range){
+ // update min and max from curve data if needed
if(ymin_damaged && y < this.ymin) this.ymin = y;
if(ymax_damaged && y > this.ymax) this.ymax = y;
}
diff -r 9d895a103019 -r a27b5862e363 tests/projects/svghmi_xy/svghmi_0@svghmi/svghmi.svg
--- a/tests/projects/svghmi_xy/svghmi_0@svghmi/svghmi.svg Wed Jun 01 09:12:59 2022 +0200
+++ b/tests/projects/svghmi_xy/svghmi_0@svghmi/svghmi.svg Wed Jun 01 09:14:19 2022 +0200
@@ -306,13 +306,13 @@
inkscape:window-height="836"
id="namedview4"
showgrid="false"
- inkscape:zoom="2.6222222"
- inkscape:cx="138.92196"
- inkscape:cy="243.43713"
+ inkscape:zoom="0.32777778"
+ inkscape:cx="-105.99939"
+ inkscape:cy="106.14218"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
- inkscape:current-layer="g2776" />
+ inkscape:current-layer="hmi0" />
-
-
-
-
-
-
- 10
-
-
-
- 10
-
-
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#00b4cf;stroke-width:1.74884677;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:url(#marker19820-3);marker-end:url(#marker25117-7);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
1
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ff0000;stroke-width:1.74884677;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:url(#marker19820-3);marker-end:url(#marker25117-7);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
blup
+ x="603.72882"
+ y="663.89832">blup
+
+
+
+
+
+
+
+ 10
+
+
+
+ 10
+
+
+
+
+
+
+
+
+ 10
+
+
+
+ 10
+
+
+
+
+
+
+
+
+ 10
+
+
+
+ 10
+
+
+
+
+
+
+
+
+ 10
+
+
+
+ 10
+