jsroot icon indicating copy to clipboard operation
jsroot copied to clipboard

Many properties are not properly saved by the drawingJSON() function

Open SergueiEK opened this issue 1 year ago • 15 comments

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

SergueiEK avatar May 03 '24 15:05 SergueiEK

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.

linev avatar May 03 '24 15:05 linev

Many problems should be fixed now:

  1. Preserve histogram zooming range
  2. Preserve fill, line, text attributes
  3. Preserve title position and settings
  4. 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.

linev avatar May 07 '24 14:05 linev

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)

SergueiEK avatar May 09 '24 21:05 SergueiEK

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.

SergueiEK avatar May 09 '24 21:05 SergueiEK

  1. It is not possible to change text in the title - it is always overridden by actual histogram title
  2. Line and fill attributes of histogram should be preserved
  3. I provide special handling for frame attributes - they need to be stored in the pad as well
  4. I cannot reproduce problem with Palette menu item.

To be sure to using latest JSROOT code - always clear browser cache before.

linev avatar May 13 '24 11:05 linev

  1. 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.
  2. 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?
  3. 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.
  4. 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.

SergueiEK avatar May 13 '24 18:05 SergueiEK

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?

linev avatar May 14 '24 08:05 linev

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.

draw.html.txt h2.json

SergueiEK avatar May 14 '24 08:05 SergueiEK

Now I see.

Please use "col" instead of "hist" as draw option.

I will fix this problem

linev avatar May 14 '24 08:05 linev

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.

C11.json C1.json draw.html.txt

SergueiEK avatar May 14 '24 09:05 SergueiEK

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.

draw.html.txt

      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);
         }
      });

linev avatar May 14 '24 10:05 linev

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)?

SergueiEK avatar May 14 '24 11:05 SergueiEK

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.

linev avatar May 14 '24 11:05 linev

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?

SergueiEK avatar May 14 '24 12:05 SergueiEK

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.

linev avatar May 14 '24 12:05 linev

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

linev avatar May 22 '24 14:05 linev