Many properties are not properly saved by the drawingJSON() function
Hi
Trying to save and restore histogram state to and from JSON, I have noticed that many properties are not correctly saved to JSON if they had been modified using interactive menus. For example for Frame, TCanvas, TPaveText, TPaveStats, TH1X, TH2X classes the following attributes:
- colour of fonts
- colour, width and style of lines
- colour and style of fills
- palettes are not taken into account. Could this be fixed?
Cheers
Thanks reporting the problem.
This function was not used much and not fully tested.
Some points already fixed - like fill color for stats box. See https://github.com/root-project/jsroot/commit/bc3d48c6c80f9fc98bae3a9354aeebccdb944c6a
Other needs more work and extending functionality of drawingJSON() function.
Many problems should be fixed now:
- Preserve histogram zooming range
- Preserve fill, line, text attributes
- Preserve title position and settings
- Preserve custom palette number selection
Please try code in master branch or from https://jsroot.gsi.de/dev
If you still see problems - please report them here.
Thank you for looking into this. I have tried the latest version from the master branch, but perhaps I did something wrong as the results are quite confusing. I can confirm that now the background colour of the StatBox is preserved, but it seems that the text colour is not. The position of the TPaveTest title box is preserved as well, but strangely enough I cannot change neither the text nor the background colour of the title. Any attempt to modify these settings are just ignored. Modifications of the line and fill of 1D histograms are not preserved (however it's not clear from you description if this was already fixed or not). But the most weird effect of switching to the master branch is that the "Palettes" item disappeared from the histogram drop-down menu. Here is the version that I have tried: [email protected] (git+ssh://[email protected]/root-project/jsroot.git#07acb8c10fa3cc8730686d7078e01975272feb74)
Please ignore my comment about the TPaveText attributes. I have realised that the background colour changes were not visible because the fill style was set t 1, which I think means transparent. When I changed this, the colours have changed as well and these changes were correctly preserved. But all the other issues seems to remain. I have also checked line and fill attributes for Frames and they seem not to be preserved.
- It is not possible to change text in the title - it is always overridden by actual histogram title
- Line and fill attributes of histogram should be preserved
- I provide special handling for frame attributes - they need to be stored in the pad as well
- I cannot reproduce problem with
Palettemenu item.
To be sure to using latest JSROOT code - always clear browser cache before.
- Actually, as I have mentioned in my last message replication works fine for the background/foreground colours of the histogram title. So this feature behaves exactly as I want.
- I have figured out what the issue is. What I'm trying to achieve is to have an HTML page that displays histograms which have been constantly updated, but preserves any visual settings that the user has modified interactively (e.g. histograms fill and line colours). To achieve this, every time a histogram visual settings are modified I save them to JSON using the drawingJSON() function. When a new updated histogram arrives I clean the canvas, draw the saved JSON and then call redraw() with the new histogram. As a result the only visual settings which are preserved are the attributes of the title and the statistics box. All others are reset to their default values. So the issue is indeed not caused by the drawingJSON()/draw() calls, but by the following redraw() one. Is there another way to achieve what I need?
- Has this been already committed to the master branch? As far as I can tell the Frame colours are not preserved even without calling the redraw() function.
- I have also figured out what the problem with the Palette is. Following your suggestion, I switched to work with histograms instead of canvases. After that the problem with the Palette has appeared. If I draw a 2D histogram object, the 'Palettes' menu item doesn't show up in the histogram drop-down menu. But if I draw a canvas object with the same histogram then everything works fine - 'Palettes' item does show up in the menu.
If you just want update histogram drawing - you can use redraw() function of JSROOT. It should preserve interactive changes done by the user and only update histogram content.
You can try to test interactive attributes changes of TH1 histogram here: https://root.cern/js/latest/demo/update_draw.htm Same approach should work with TH2
It should be also possible with canvas drawn after using drawingJSON().
It would be nice to see reproducer with Palette - I see no problem. Maybe you are using draw option where colors not used?
Thank you, I'll give it a try.
I attached HTML and JSON files which can be used to reproduce the issue with Palette. The JSON file contains the histogram object, no canvas. This object was obtained by getting .fPrimitives.arr[1] from the canvas JSON.
Now I see.
Please use "col" instead of "hist" as draw option.
I will fix this problem
Thank you, this works! Meanwhile I have managed to narrow down the problem #2. Attached files can be used to reproduce it. If I load the page and then modify some histogram properties (line or fill colour) and click "Replicate" these properties are correctly reproduced in the replica. But if I then click the "Update" button, which redraws both canvases, the properties are preserved only in the original histogram but not in the replica.
the properties are preserved only in the original histogram but not in the replica
It is intended behavior. In "replica" histogram object drawn as is. And if you try to redraw it - all graphics attributes are updated from new content.
In original drawing changes made interactively and therefore preserved also after object update.
The only solution I see - modify directly only histogram content after you got new histogram. And then do redraw.
document.getElementById('btn2').addEventListener('click', async () => {
let obj11 = await httpRequest('C11.json', 'object');
obj1.fPrimitives.arr[0].fArray = obj11.fPrimitives.arr[0].fArray;
redraw('drawing', obj1);
if (obj2) {
obj2.fPrimitives.arr[0].fArray = obj11.fPrimitives.arr[0].fArray;
redraw('replica', obj2);
}
});
Thank you again, the proposed solution works. May I ask you what's the reasoning behind treating a JSON object that was read from a file (or some remote server) and a JSON that was retrieved from the local canvas? Why do they behave different when drawn to a new canvas (ie for the former the drawing attributes are preserved at redraw while for the later not)?
Why do they behave different
While interactive changes stored in special painter objects. These painter objects did not stored in JSON with drawingJSON function - while here only plain ROOT attributes are stored. Therefore information about interactive change of some attributes is lost.
While interactive changes stored in special painter objects. These painter objects did not stored in JSON with drawingJSON function - while here only plain ROOT attributes are stored.
I think I'm still missing something. You are saying that the "painter objects are not stored in JSON", but then how the state of these attributes, which have been interactively modified is preserved when the JSON is drawn in another canvas?
but then how the state of these attributes, which have been interactively modified is preserved when the JSON is drawn in another canvas?
While each histogram has line attributes. Changing line width one changes fLineWidth member of histogram.
And this member stored in JSON. Painter object "remembers" about such interactive change - histogram not.
All mentioned improvements are now published in 7.7.0 release.
If you still see problems - you can reopen this issue or open new one