From ed13254433bda78b5462c89790ef57e931b68046 Mon Sep 17 00:00:00 2001 From: Tomas Kulhanek Date: Thu, 20 Jan 2022 15:34:49 +0100 Subject: [PATCH] ADD binding to another component,attribute, range inputs and hashparams fix --- docs/usersguide/range.md | 26 ++++++++++++++----- src/elements/animate-adobe.js | 17 ++++++++++++- src/elements/bind2previous.js | 16 +++++++++--- src/elements/chartjs-time.js | 18 +------------ src/elements/chartjs.js | 20 +++++++++++++++ src/elements/fmi.js | 7 +++++ src/elements/markdown-book.js | 12 ++++++--- src/elements/markdown-book2.html | 2 +- src/elements/markdown-book2.js | 9 +++++-- src/elements/markdown-top-nav.html | 2 +- src/elements/markdown-top-nav.js | 13 ++++++++++ src/elements/value.js | 41 +++++++++++++++++++++++++----- 12 files changed, 142 insertions(+), 41 deletions(-) diff --git a/docs/usersguide/range.md b/docs/usersguide/range.md index e512159..98b7117 100644 --- a/docs/usersguide/range.md +++ b/docs/usersguide/range.md @@ -17,12 +17,26 @@ Example: E.g. setting range 1 will change range 2 and range 3 so the sum is constant: ```xml -O2: -N: -other: +tkan1: + + tkan2: + + tkan3: + + tkan4: + + tkan5: ``` -O2: -N: -other: +tkan1: + +tkan2: + +tkan3: + +tkan4: + +tkan5: + + diff --git a/src/elements/animate-adobe.js b/src/elements/animate-adobe.js index 102454d..5a74f5e 100644 --- a/src/elements/animate-adobe.js +++ b/src/elements/animate-adobe.js @@ -104,6 +104,7 @@ export class AnimateAdobe { } handleResize() { + console.log('animateadobe handleResize()'); //do not run if ani.lib is not defined - no adobe component is available if (!window.ani.lib) return; let w = window.ani.lib.properties.width; let h = window.ani.lib.properties.height; @@ -164,7 +165,7 @@ export class AnimateAdobe { } destroyAdobe() { - //console.log('animate adobe destroy()'); + console.log('animate adobe destroy()'); if (window.stage) { window.stage.enableMouseOver(-1); window.stage.enableDOMEvents(false); @@ -249,6 +250,7 @@ export class AnimateAdobe { //this is called after animate script is loaded into DOM, so global AdobeAn is available initAdobe() { + console.log('animateadobe initAdobe()'); //take the first composition if (!window.ani.cid) { window.ani.cid = Object.keys(window.AdobeAn.compositions)[0]; //get the first composition @@ -306,9 +308,12 @@ export class AnimateAdobe { window.ani.stopAllAnimation(); //disable animation ticker window.ani.disableAnimation(); + //TODO fix bug - model in different md not //sent ready signal - fmu may make step if oneshot let event = new CustomEvent('fmiregister'); document.dispatchEvent(event); + //workaround after resize the artifacts are updated + //window.ani.handleResize(); } }, 1000); } @@ -318,6 +323,7 @@ export class AnimateAdobe { * @param objname */ startAnimation(objname) { + console.log('animateadobe startAnimation() of object'); const resolvePath = (object, path, defaultValue) => path .split('.') .reduce((o, p) => o ? o[p] : defaultValue, object); @@ -336,6 +342,7 @@ export class AnimateAdobe { * @param objname */ stopAnimation(objname) { + console.log('animateadobe stopAnimation() of object'); const resolvePath = (object, path, defaultValue) => path .split('.') .reduce((o, p) => o ? o[p] : defaultValue, object); @@ -352,6 +359,7 @@ export class AnimateAdobe { */ setAnimationValue(objname, value) { + console.log('animateadobe setAnimationValue',value); //console.log('adobe-animate() setting window.ani.exportRoot.children[0][' + objname + '].gotoAndStop(' + value + ')'); if (window.ani.exportRoot) { //resolve path from string @@ -371,12 +379,14 @@ export class AnimateAdobe { * stops all animation */ stopAllAnimation() { + console.log('animateadobe stopAllAnimation'); if (window.ani.stage) { window.ani.stage.stop(); } } disableAnimation() { + console.log('animateadobe disableAnimation'); if (window.ani) { window.ani.animationstarted = false; if (window.ani.stage) { @@ -386,6 +396,7 @@ export class AnimateAdobe { } enableAnimation() { + console.log('animateadobe enableAnimation'); if (window.ani.stage) {window.createjs.Ticker.addEventListener('tick', window.ani.stage);} window.ani.animationstarted = true; } @@ -418,6 +429,7 @@ export class AnimateAdobe { * starts animation for 20 ms and stops it again */ stepAllAnimation() { + console.log('animateadobe stepAnimation, stop after 20ms'); if (window.ani.stage) { window.ani.stage.play(); setTimeout(()=>{window.ani.stage.stop();}, 20); @@ -430,6 +442,7 @@ export class AnimateAdobe { * @param textvalue */ setText(objname, textvalue) { + console.log('animateadobe set text:',textvalue); if (window.ani.exportRoot) { const resolvePath = (object, path, defaultValue) => path .split('.') @@ -447,6 +460,8 @@ export class AnimateAdobe { * @param e */ handleData(e) { + //disable fix, fmi sends startevent if oneshot after registering input again issue when one shot mode sends data - but no animation is performed e.g. in editor (oneshot do not send start signal) + //if (window.ani && !window.ani.animationstarted) window.ani.enableAnimation() let bindings = window.animatebindings; //const eps = 1e-12; if (!bindings) return; diff --git a/src/elements/bind2previous.js b/src/elements/bind2previous.js index 138681e..24d0a42 100644 --- a/src/elements/bind2previous.js +++ b/src/elements/bind2previous.js @@ -9,6 +9,7 @@ import {bindable} from 'aurelia-framework'; */ export class Bind2previous { @bindable fromid; + @bindable event = 'input' @bindable toid; @bindable toattribute; @@ -19,13 +20,22 @@ export class Bind2previous { }*/ this.handleValueChange = e => { //console.log('handleValueChange, e,fromid,toid', e); - if (this.toattribute) document.getElementById(this.toid)[this.toattribute] = e.target.value; - else document.getElementById(this.toid).value = e.target.value; + let value = e.detail ? e.detail.value : e.target.value; + if (this.toattribute) { + let el = document.getElementById(this.toid); + el.setAttribute(this.toattribute, value); + //fix setting depended input attributes -e.g. in + let inputs = el.getElementsByTagName('input'); + if (inputs.length > 0) { + for (let input of inputs) input.setAttribute(this.toattribute,value); + } + } + else document.getElementById(this.toid).value = value; }; } attached() { - document.getElementById(this.fromid).addEventListener('input', this.handleValueChange); + document.getElementById(this.fromid).addEventListener(this.event, this.handleValueChange); } detached() { if (document.getElementById(this.fromid)) document.getElementById(this.fromid).removeEventListener('input', this.handleValueChange); diff --git a/src/elements/chartjs-time.js b/src/elements/chartjs-time.js index be7cee6..1e19325 100644 --- a/src/elements/chartjs-time.js +++ b/src/elements/chartjs-time.js @@ -87,23 +87,7 @@ export class ChartjsTime extends Chartjs { }; if (this.verticalline) this.type = 'LineWithLine'; else this.type = 'line'; - if (this.min) { - //sets yscale min - if (!this.options) this.options = {}; - if (!this.options.scales) this.options.scales = {}; - if (!this.options.scales.yAxes) this.options.scales.yAxes = [{}]; //chartjs 2.9.4 - if (!this.options.scales.yAxes[0].ticks) this.options.scales.yAxes[0].ticks = {}; //chartjs 2.9.4 - this.options.scales.yAxes[0].ticks.min = parseFloat(this.min); - } - if (this.max) { - //sets yscale max - if (!this.options) this.options = {}; - if (!this.options.scales) this.options.scales = {}; - if (!this.options.scales.yAxes) this.options.scales.yAxes = [{}]; //chartjs 2.9.4 - if (!this.options.scales.yAxes[0].ticks) this.options.scales.yAxes[0].ticks = {}; //chartjs 2.9.4 - this.options.scales.yAxes[0].ticks.max = parseFloat(this.max); - //if (this.min) this.options.scales.yAxes[0].ticks.stepSize = (this.options.scales.yAxes[0].ticks.max - this.options.scales.yAxes[0].ticks.min) / 10; - } + } resetdata() { diff --git a/src/elements/chartjs.js b/src/elements/chartjs.js index b713213..02021c1 100644 --- a/src/elements/chartjs.js +++ b/src/elements/chartjs.js @@ -32,6 +32,8 @@ export class Chartjs { @bindable canvasobj; @bindable throttle=200; //time to throttle chart update, if it is too much at once @bindable precision=4; + @bindable min; //min for y axis - if chart has this axis + @bindable max; //max for y axis - if chart has this axis indexsection=0; datalabels=false; //may be configured by subclasses @@ -265,6 +267,24 @@ export class Chartjs { this.options.section = []; } + if (this.min) { + //sets yscale min + if (!this.options) this.options = {}; + if (!this.options.scales) this.options.scales = {}; + if (!this.options.scales.yAxes) this.options.scales.yAxes = [{}]; //chartjs 2.9.4 + if (!this.options.scales.yAxes[0].ticks) this.options.scales.yAxes[0].ticks = {}; //chartjs 2.9.4 + this.options.scales.yAxes[0].ticks.min = parseFloat(this.min); + } + if (this.max) { + //sets yscale max + if (!this.options) this.options = {}; + if (!this.options.scales) this.options.scales = {}; + if (!this.options.scales.yAxes) this.options.scales.yAxes = [{}]; //chartjs 2.9.4 + if (!this.options.scales.yAxes[0].ticks) this.options.scales.yAxes[0].ticks = {}; //chartjs 2.9.4 + this.options.scales.yAxes[0].ticks.max = parseFloat(this.max); + //if (this.min) this.options.scales.yAxes[0].ticks.stepSize = (this.options.scales.yAxes[0].ticks.max - this.options.scales.yAxes[0].ticks.min) / 10; + } + this.tooltips = ['mousemove', 'touchstart', 'touchmove', 'click']; } diff --git a/src/elements/fmi.js b/src/elements/fmi.js index fc5b01f..092dddc 100644 --- a/src/elements/fmi.js +++ b/src/elements/fmi.js @@ -108,6 +108,13 @@ export class Fmi { document.getElementById(target).addEventListener('fmiinput', this.handleDetailChange); } } + //if oneshot - do step + if (this.isOneshot) { + //console.log('oneshot scheduling startevent in promise() to do step()') + setTimeout(this.sendStartEvent.bind(this),1000); //TODO may cause problems sync when animation not yet loaded + console.log('oneshot scheduling promise() to do step()') + setTimeout(this.step.bind(this),1500); + } //do simulation step after 100 ms } deregisterInputs() { diff --git a/src/elements/markdown-book.js b/src/elements/markdown-book.js index 4bfdc8c..5715740 100644 --- a/src/elements/markdown-book.js +++ b/src/elements/markdown-book.js @@ -9,14 +9,14 @@ export class MarkdownBook extends WatchHashCore { constructor() { super(); - this.params = 'showmenu,2;base,3'; + this.params = 'shownav,2;showmenu,3;base,4'; + this.shownav = true; + this.showmenu = true; } bind() { //this.value=this.params;//'index,0;summary,1;shownav,2'; console.log('bdlmarkdownbook index:', this.index, 'summary:', this.summary); - this.shownav = true; - this.showmenu = true; super.bind(); this.previoustitle = 'previous chapter'; this.previoustitleshort = 'prev ...'; @@ -26,6 +26,7 @@ export class MarkdownBook extends WatchHashCore { /*attached() { this.disablenav = !((this.summary) && ((this.summary.length > 0) && (this.summary !== 'false'))); }*/ + //is called if the watchhash attribute is used changesrc(...args) { /*if (name === 'summary') this.summary = index; @@ -34,7 +35,10 @@ export class MarkdownBook extends WatchHashCore { //if (name === 'base') this.base = index; console.log('bdlmarkdownbook changesrc called, args:', args); //TODO - hack - first arg is showmenu - if (args[0]) this.showmenu = (args[0] !== 'false'); + if (args[0]) this.shownav = (args[0] !== 'false'); + if (args['shownav'])this.shownav = (args['shownav'] !== 'false'); + if (args[1]) this.showmenu = (args[1] !== 'false'); + if (args['showmenu'])this.showmenu = (args['showmenu'] !== 'false'); //console.log('bdlmarkdownbook changesrc shownav', this.shownav); } diff --git a/src/elements/markdown-book2.html b/src/elements/markdown-book2.html index 22e4cf8..215b18b 100644 --- a/src/elements/markdown-book2.html +++ b/src/elements/markdown-book2.html @@ -25,7 +25,7 @@ - + diff --git a/src/elements/markdown-book2.js b/src/elements/markdown-book2.js index 36d771b..599d717 100644 --- a/src/elements/markdown-book2.js +++ b/src/elements/markdown-book2.js @@ -13,12 +13,13 @@ export class MarkdownBook2 extends MarkdownBook { constructor() { super(); + this.params = 'shownav,1;showmenu,2;base,3'; + this.shownav = true; + this.showtoc = true; } bind() { super.bind(); - this.shownav = true; - this.showtoc = true; //console.log('markdownbook bind shownav', this.shownav); } @@ -38,4 +39,8 @@ export class MarkdownBook2 extends MarkdownBook { el.scrollIntoView(); // document.getElementById(id).scrollIntoView(); } + + changesrc(...args) { + super.changesrc(...args); + } } diff --git a/src/elements/markdown-top-nav.html b/src/elements/markdown-top-nav.html index 4749c0b..5b5b8da 100644 --- a/src/elements/markdown-top-nav.html +++ b/src/elements/markdown-top-nav.html @@ -1,7 +1,7 @@ diff --git a/src/elements/markdown-top-nav.js b/src/elements/markdown-top-nav.js index 67c43c9..b179405 100644 --- a/src/elements/markdown-top-nav.js +++ b/src/elements/markdown-top-nav.js @@ -81,6 +81,19 @@ export class MarkdownTopNav { showhidenav() { this.nav = ! this.nav; + if (! this.nav) { + if (document.documentElement.requestFullscreen) { + document.documentElement.requestFullscreen(); + } else if (document.documentElement.webkitRequestFullscreen) { /* Safari */ + document.documentElement.webkitRequestFullscreen(); + } + } else { + if (document.exitFullscreen) { + document.exitFullscreen(); + } else if (document.webkitExitFullscreen) { /* Safari */ + document.webkitExitFullscreen(); + } + } } showhidetoc() { diff --git a/src/elements/value.js b/src/elements/value.js index 615820d..3a9cbe5 100644 --- a/src/elements/value.js +++ b/src/elements/value.js @@ -1,14 +1,18 @@ import {bindable} from 'aurelia-templating'; import _ from 'lodash'; +import {inject} from 'aurelia-framework'; +@inject(Element) export class Value { @bindable fromid; @bindable refindex; - @bindable convertors; + @bindable convertor; @bindable precision=4; @bindable throttle=500; + @bindable dataevent=false; - constructor() { + constructor(element) { + this.element = element; //create lambda function which is added as listener later this.handleValueChange = e => { //e.detail do not reallocate - using same buffer, thus slicing to append to data array @@ -18,17 +22,31 @@ export class Value { // _.throttle(()=> this.updateValue(e.detail.data[this.refindex]), this.throttle)(); //call throttled function with args this.myupdatevalue(e.detail.data[this.refindex]) + + }; + this.handleFMIAttached = e => { + const fromel = document.getElementById(this.fromid); + if (fromel) { + fromel.addEventListener('fmidata', this.handleValueChange); + } else { + console.warn('fmi attached, but no element with id found:',this.fromid); + } + } + } bind() { //register throttled update function if (typeof this.throttle === 'string') this.throttle = parseInt(this.throttle, 10); + if (typeof this.dataevent === 'string') this.dataevent = this.dataevent === 'true'; if (typeof this.precision === 'string') this.precision = parseInt(this.precision, 10); this.myupdatevalue = _.throttle(this.updateValue, this.throttle); //configure convertors - used to convert units received from fmi - if (this.convertors) { - let convertvalues = this.convertors.split(';'); + if (this.convertor) { + //used code from fmi component + //TODO change to custom attribute + let convertvalues = [this.convertor]; let identity = x => x; this.operation = []; for (let i = 0; i < convertvalues.length; i++) { @@ -48,7 +66,7 @@ export class Value { else { // for eval() security filter only allowed characters: // algebraic, digits, e, dot, modulo, parenthesis and 'x' and 'e' is allowed - let expression = convertvalues[i].replace(/[^-\d/*+.()%xe]/g, ''); + let expression = convertvalues[i].replace(/[^-\d/*+.()%xeMathroundsic]/g, ''); console.log('chartjs bind(), evaluating expression:' + convertvalues[i] + ' securely filtered to :' + expression); // eslint-disable-next-line no-eval this.operation.push(x => eval(expression)); @@ -60,7 +78,14 @@ export class Value { attached() { //listening to custom event fmidata - document.getElementById(this.fromid).addEventListener('fmidata', this.handleValueChange); + //listening to custom event fmidata and fmireset + const fromel = document.getElementById(this.fromid); + if (fromel) { + fromel.addEventListener('fmidata', this.handleValueChange); + } else { + console.warn('chartjs, null fromid element, waiting to be attached'); + document.addEventListener('fmiattached',this.handleFMIAttached); + } } @@ -71,5 +96,9 @@ export class Value { updateValue(rawvalue) { if (this.operation) this.value = this.operation[0](rawvalue).toPrecision(this.precision); // * this.numerator / this.denominator + this.addconst; else this.value = rawvalue.toPrecision(this.precision); + if (this.dataevent) { + let c = new CustomEvent('fmivalue', {detail: {value: this.value}}); + this.element.dispatchEvent(c); + } } }