Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a re-render command? #1

Closed
ullix opened this issue Oct 26, 2021 · 8 comments
Closed

Is there a re-render command? #1

ullix opened this issue Oct 26, 2021 · 8 comments

Comments

@ullix
Copy link

ullix commented Oct 26, 2021

I am using this gauge happily for quite a while, but now had the need to modify the two threshold values during a run. Unfortunately, I didn't find a way to update the graph to reflect the new settings.

It finally worked by redoing the whole gauge with:

powerGauge = new Gauge({...all settings...});
document.getElementById("gauge").innerHTML = "";
powerGauge.render("#gauge");

It works, but it feels a bit clunky, having to manually overwrite and delete things. The .innerHTML is necessary, because otherwise I get an additional graph.

Is there no command like powerGauge.re_render("#gauge"); re-applying all the settings - unchanged and changed ?

If not, I'd suggest to put one in.

@e-tinkers
Copy link
Owner

The Gauge library(an JavaScript object) provide an API interface and methods for manipulating the object. It is however does not handling anything for the creation of an Gauge or the DOM insertion of a Gauge, it is up to the user on how to use it as shown in example.js as well as in your code.

When you the Gauge.render() method is called, it creates another JavaScript object (D3) at the DOM where the Gauge has been inserted.

For JavaScript, the garbage collection will clean up an object when it is out of scope, even though there is an Object.delete() but it does not delete an object, it is only remove the reference to the Object. So overall, it is user's responsibility to remove (put it out of scope).

If you need to dynamically create an Gauge as shown in your code, you are doing it correctly and in my opinion it is not clumsy, it is the minimum that the user of the library need to do.

Personally, I never have a use case where I need to dynamically change the thresholds, if your value spread across a wide range, you might want to consider to use log scale, Gauge supports both linear and log scale, you can see it on the example.js or demo.

@ullix
Copy link
Author

ullix commented Oct 27, 2021

Well, I do know about the log scale - remember, I contributed to it? - and this is what I am using. The app is about count rates of Geiger tubes, counting radioactive events. The thresholds separate the good, bad, and ugly portions.

Now when using different Geiger tubes you are faced with different sensitivities, and the thresholds need to be adapted when you switch display from one tube to the other.

Looking at your code - I am not very firm in d3 coding - I guess that something like d3.selectAll("svg").remove(); followed by the existing render(...) would make for a re-render command?

@ullix
Copy link
Author

ullix commented Oct 27, 2021

Indeed, this little change works beautifully!

rerender(container, newValue) {
      d3.selectAll("svg").remove();
      this.render(container, newValue);
    }

render(container, newValue) {
...unchanged...
}

and in my code I have:

if (TubeIndex != oldTubeIndex){
       makePowerGauge();                // sets the threshold changes
       powerGauge.rerender("#gauge");
 }

@ullix
Copy link
Author

ullix commented Oct 27, 2021

Another suggestion: I have to do this multiple times in my code, so why not do it once in your lib:

update(newValue) {
      if (isNaN(newValue)) newValue = this.config.minValue; // by ullix
      ...remainder unchanged...

keeps some errors away ...

@e-tinkers
Copy link
Owner

It doesn't works that way, most of the configuration are done in the Gauge construct, in order for the new configuration to take effect, part of the construct code need to be executed. You also need to remove the "text" div in addition to the "svg" object... anyway, I've come out a solution by introducing a new method setConfig( { ... }) and move part of code in the construct() to a private method so that both construct() and setConfig() will call the private method. The setConfig() method did almost what the construct() do and a little bit redundant but this will maintain the maximum backward compatibility with the origin code and allows dynamically re-config the gauge.

Please take a look at the codes at the temp branch and test it (see the README or example for the usage), let me know if it works for your use case before I merging it to the master branch.

@ullix
Copy link
Author

ullix commented Oct 28, 2021

Well, it semi-worked.
image
"Old" is my variant, "New" is your new code. First thing to note is that the scale numbers are missing in New. I looked through the code, but haven't figured it out.

The streetlight color choice red, yellow, green is probably the most chosen set of colors. Unfortunately, yellow is a poor choice when printed on light background. For me the numbers are not needed, as I am showing them below anyway (in black).

The color transition is cool, but if anything I would rather have it as a transition of the thresholds, because those limits are never precisely at one point but have an uncertainty and stretch over a range. That would actually be a proper message to convey to the user by a smooth color transition.

Perhaps since I am not using the value display my method works well. What I had not made clear is that my makePowerGauge(); includes the full powerGauge = new Gauge({set all the stuff});

One more thing: devices may not be able to deliver data when I want them, resulting in "missing values". They may be - device dependent - represented as NAN or as 0 (zero). When plotting, inparticular in log scale, you get an error on both, making the pointer flipping to mid-point and back. Quite annoying. So I check the value before updating:

  update(newValue) {
    if (isNaN(newValue)) newValue = this.config.minValue; 
    if (newValue < this.config.minValue) newValue = this.config.minValue; 
   ...

One other irritating thing in both Old an New: After changing the thresholds the pointer flips to minValue, and then to newValue. Not critical, but would be nicer if it were going directly from old to new value, without the detour over minValue.

@e-tinkers
Copy link
Owner

On missing scale, sorry I forgot to push the last changes up to the git repo. On the rest of things that you are talking about, I did not change anything in related to color, transition, etc...
I believe this should now provide a better solution for re-configure the gauge and meet your original request. Feel free to customise it, or fork and modify it to suit your needs on your end.

@ullix
Copy link
Author

ullix commented Oct 29, 2021

Thanks. After I applied my modifications I am back to a nice system!

What I don't understand is why you seem to accept errors from not preventing problems. Just try to update() with zero and NAN. log(0) and log(NAN) really do not work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants