# 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 +