# HG changeset patch # User Edouard Tisserant # Date 1653907444 -7200 # Node ID 4f252e8d67595d73480267184ddd95cc698dc32b # Parent 5335895ce5261dc3daa8b87740c25c35b7b8a98b SVGHMI: more fixes for XY graph + add XY graph test. diff -r 5335895ce526 -r 4f252e8d6759 svghmi/widget_xygraph.ysl2 --- a/svghmi/widget_xygraph.ysl2 Thu May 26 12:11:42 2022 +0200 +++ b/svghmi/widget_xygraph.ysl2 Mon May 30 12:44:04 2022 +0200 @@ -72,6 +72,15 @@ [this.x_axis_line_elt, this.y_axis_line_elt], [this.x_format, this.y_format]); + let max_stroke_width = 0; + for(let curve of this.curves){ + if(curve.style.strokeWidth > max_stroke_width){ + max_stroke_width = curve.style.strokeWidth; + } + } + + this.Margins=this.reference.getLengths().map(length => max_stroke_width/length); + // create path and attach it to widget let clipPath = document.createElementNS(xmlns,"clipPath"); let clipPathPath = document.createElementNS(xmlns,"path"); @@ -79,6 +88,7 @@ clipPathPathDattr.value = this.reference.getClipPathPathDattr(); clipPathPath.setAttributeNode(clipPathPathDattr); clipPath.appendChild(clipPathPath); + clipPath.id = randomId(); this.element.appendChild(clipPath); // assign created clipPath to clip-path property of curves @@ -115,7 +125,7 @@ } this.xmax = time; - let Xlength = this.xmax - this.xmin; + let Xrange = this.xmax - this.xmin; if(!this.fixed_y_range){ ymin_damaged = overflow <= this.ymin; @@ -129,7 +139,14 @@ this.ymin = value; } } - let Ylength = this.ymax - this.ymin; + let Yrange = this.ymax - this.ymin; + + 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], + [this.ymin-yMargin, this.ymax+yMargin]]; + Xrange += 2*xMargin; + Yrange += 2*yMargin; // recompute curves "d" attribute // FIXME: use SVG getPathData and setPathData when available. @@ -141,8 +158,8 @@ zip(this.curves_data, this.curves).map(([data,curve]) => { let new_d = data.map(([x,y], i) => { // compute curve point from data, ranges, and base_ref - let xv = vectorscale(xvect, (x - this.xmin) / Xlength); - let yv = vectorscale(yvect, (y - this.ymin) / Ylength); + let xv = vectorscale(xvect, (x - this.dxmin) / Xrange); + let yv = vectorscale(yvect, (y - this.dymin) / Yrange); let px = base_point.x + xv.x + yv.x; let py = base_point.y + xv.y + yv.y; if(!this.fixed_y_range){ @@ -169,8 +186,8 @@ if(this.curves_data.some(data => data.length > 1)){ // move marks and update labels - this.reference.applyRanges([[this.xmin, this.xmax], - [this.ymin, this.ymax]]); + this.reference.applyRanges([[this.dxmin, this.dxmax], + [this.dymin, this.dymax]]); // apply computed curves "d" attributes for(let [curve, d_attr] of zip(this.curves, this.curves_d_attr)){ @@ -220,9 +237,17 @@ return new DOMPoint(p2 * p1.x , p2 * p1.y); }; +function vectorLength(p1) { + return Math.sqrt(p1.x*p1.x + p1.y*p1.y); +}; + +function randomId(){ + return Date.now().toString(36) + Math.random().toString(36).substr(2); +} + function move_elements_to_group(elements) { let newgroup = document.createElementNS(xmlns,"g"); - newgroup.id = Date.now().toString(36) + Math.random().toString(36).substr(2); + newgroup.id = randomId(); for(let element of elements){ let parent = element.parentElement; @@ -308,11 +333,17 @@ this.base_ref = [base_point, xvect, yvect]; + this.lengths = [xvect,yvect].map(v => vectorLength(v)); + for(let axis of this.axes){ axis.setBasePoint(base_point); } } + getLengths(){ + return this.lengths; + } + getBaseRef(){ return this.base_ref; } @@ -372,7 +403,7 @@ for(let [elementname,element] of zip(["minor", "major", "label"],[...marks,label])){ for(let name of ["base","slide"]){ let transform = svg_root.createSVGTransform(); - element.transform.baseVal.appendItem(transform); + element.transform.baseVal.insertItemBefore(transform,0); this[elementname+"_"+name+"_transform"]=transform; }; }; @@ -395,7 +426,7 @@ this.marks_and_label_group.transform.baseVal.appendItem(this.marks_and_label_group_transform); this.duplicates = []; - this.last_mark_count = 0; + this.last_duplicate_index = 0; } setBasePoint(base_point){ @@ -445,12 +476,9 @@ // - To transform order of magnitude to an integer, floor() is used. // This results in a count of mark fluctuating in between 10 and 100. // - // - To spare resources result is better in between 5 and 50, - // and log10(5) is substracted to order of magnitude to obtain this - // log10(5) ~= 0.69897 - - - let unit = Math.pow(10, Math.floor(Math.log10(range)-0.69897)); + // - To spare resources result is better in between 3 and 30, + // and log10(3) is substracted to order of magnitude to obtain this + let unit = Math.pow(10, Math.floor(Math.log10(range)-Math.log10(3))); // TODO: for time values (ms), units may be : // 1 -> ms @@ -508,11 +536,11 @@ // base_point // move major marks and label to first positive mark position - let v = vectorscale(unit_vect, unit); - this.label_slide_transform.setTranslate(v.x, v.y); - this.major_slide_transform.setTranslate(v.x, v.y); + // let v = vectorscale(unit_vect, unit); + // this.label_slide_transform.setTranslate(v.x, v.y); + // this.major_slide_transform.setTranslate(v.x, v.y); // move minor mark to first half positive mark position - v = vectorscale(unit_vect, unit/2); + let v = vectorscale(unit_vect, unit/2); this.minor_slide_transform.setTranslate(v.x, v.y); // duplicate marks and labels as needed @@ -523,7 +551,7 @@ let transform = svg_root.createSVGTransform(); let newlabel = this.label.cloneNode(true); let newuse = document.createElementNS(xmlns,"use"); - let newuseAttr = document.createAttribute("xlink:href"); + let newuseAttr = document.createAttribute("href"); newuseAttr.value = "#"+this.marks_group.id; newuse.setAttributeNode(newuseAttr); newgroup.transform.baseVal.appendItem(transform); @@ -560,10 +588,10 @@ // X<--------->| // base_point + let duplicate_index = 0; for(let mark_index = 0; mark_index <= mark_count; mark_index++){ - let i = 0; let val = (mark_min + mark_index) * unit; - let vec = vectorscale(unit_vect, offset + val - min); + let vec = vectorscale(unit_vect, val - min); let text = this.format ? sprintf(this.format, val) : val.toString(); if(mark_index == mark_offset){ // apply offset to original marks and label groups @@ -572,7 +600,7 @@ // update original label text this.label.getElementsByTagName("tspan")[0].textContent = text; } else { - let [transform,element] = this.duplicates[i++]; + let [transform,element] = this.duplicates[duplicate_index++]; // apply unit vector*N to marks and label groups transform.setTranslate(vec.x, vec.y); @@ -581,19 +609,20 @@ element.getElementsByTagName("tspan")[0].textContent = text; // Attach to group if not already - if(i >= this.last_mark_count){ + if(element.parentElement == null){ this.group.appendChild(element); } } } + let save_duplicate_index = duplicate_index; // dettach marks and label from group if not anymore visible - for(let i = current_mark_count; i < this.last_mark_count; i++){ - let [transform,element] = this.duplicates[i]; + for(;duplicate_index < this.last_duplicate_index; duplicate_index++){ + let [transform,element] = this.duplicates[duplicate_index]; this.group.removeChild(element); } - this.last_mark_count = current_mark_count; + this.last_duplicate_index = save_duplicate_index; return vectorscale(unit_vect, offset); } diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_i18n/svghmi_0@svghmi/messages.pot --- a/tests/projects/svghmi_i18n/svghmi_0@svghmi/messages.pot Thu May 26 12:11:42 2022 +0200 +++ b/tests/projects/svghmi_i18n/svghmi_0@svghmi/messages.pot Mon May 30 12:44:04 2022 +0200 @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2021-02-15 14:45+CET\n" +"POT-Creation-Date: 2022-05-26 11:39+CEST\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/beremiz.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/beremiz.xml Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,5 @@ + + + + + diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/plc.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/plc.xml Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + trendval0 + + + + + + + + + + + trendval1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + 0 + + + + + + + 360 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + counter + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 57.2958 + + + + + + + + + + + + + + + + + + diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/svghmi_0@svghmi/baseconfnode.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/svghmi_0@svghmi/baseconfnode.xml Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,2 @@ + + diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/svghmi_0@svghmi/confnode.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/svghmi_0@svghmi/confnode.xml Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,2 @@ + + diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/svghmi_0@svghmi/fr-FR.mo Binary file tests/projects/svghmi_xy/svghmi_0@svghmi/fr-FR.mo has changed diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/svghmi_0@svghmi/fr-FR.po --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/svghmi_0@svghmi/fr-FR.po Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,21 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2022-05-13 11:27+CEST\n" +"PO-Revision-Date: 2022-05-13 11:29+0200\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: SVGHMI 1.0\n" +"X-Generator: Poedit 2.3\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Language: fr\n" + +msgid "blup" +msgstr "bloup" diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/svghmi_0@svghmi/messages.pot --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/svghmi_0@svghmi/messages.pot Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,21 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2022-05-30 12:35+CEST\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: SVGHMI 1.0\n" + + +#:svghmi.svg: blup:text73 +msgid "blup" +msgstr "" + diff -r 5335895ce526 -r 4f252e8d6759 tests/projects/svghmi_xy/svghmi_0@svghmi/svghmi.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/projects/svghmi_xy/svghmi_0@svghmi/svghmi.svg Mon May 30 12:44:04 2022 +0200 @@ -0,0 +1,585 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + 10 + + + A sophisticated meter looking like real + + + -1 + 1 + + + A sophisticated meter looking like real + + + -1 + 1 + + blup + + + + Language (Country) + + +