lets-plot icon indicating copy to clipboard operation
lets-plot copied to clipboard

Nice to support a responsive mode.

Open alshan opened this issue 2 years ago • 5 comments

From discussion: https://github.com/JetBrains/lets-plot/discussions/897#discussioncomment-8556115

I've noticed that plots created with lets-plot do not currently support a responsive mode. This slightly cripples UX, because I am generating the plots in a web app, and it's being accessed by users on various devices, making the fixed width and height of plots inconvenient!

Are there any plans to introduce responsiveness to the plots (similar to width/height policy in Bokeh)?

alshan avatar Feb 23 '24 20:02 alshan

Hi @OSuwaidi, Agree, this is nice to have. Speaking of width/height policy in Bokeh, which one would be most applicable in your case?

alshan avatar Feb 23 '24 20:02 alshan

Hey @alshan,

So excited for this feature to be supported honestly!

And I'd say supporting responsive width is most important; width_policy="fit" is especially powerful, so is having sizing_mode='stretch/scale_width'.

OSuwaidi avatar Feb 23 '24 21:02 OSuwaidi

But AFAIU you need to fit both, width and height (and width with a slight discount BTW): LetsPlot.buildPlotFromRawSpecs(data._plot_spec_as_dict, pn_container.clientWidth-5, height, pn_container);

See https://github.com/holoviz/panel/issues/5475#issuecomment-1882851590

alshan avatar Feb 23 '24 21:02 alshan

I see.

Well, assuming the plot's container element (pn_container) is responsive, can we observe changes in its size via ResizeObserver by targeting its ID (document.getElementById('pn_container')), and then invoke a callback to dynamically update the plot's dimensions given the new container size?

(P.S., small pet peeve: why the use of & rather than && in if (state.height-5<=height & height<=state.height+5)?)

OSuwaidi avatar Feb 27 '24 11:02 OSuwaidi

HI @OSuwaidi , I've added something that would potentially allow you to make lets-plot chart reactive in your app. At least it works in my sandbox: https://codepen.io/Igor-Alshannikov/pen/PogPPYJ

When in the sandbox, II recommend you to "collapse" var plotSpec=... code-block because it takes a lot of space and doesn't contain anything interesting: image

1, LetsPlot.buildPlotFromRawSpecs() now returns a figure model object:

var figureModel = LetsPlot.buildPlotFromRawSpecs(

Note, it is possible that the figureModel object will be Undefined, i.e. in case of an error during the plot building etc.

  1. buildPlotFromRawSpecs() now have 5th parameter. You can use it to set-up the sizing policy as follows:
{
    "sizing": {
           "width_mode": "fit",
           "height_mode": "fit",
           "width_margin": 50,
           "height_margin": 0
         }
}  

The width_margin value is yours of course. The height_margin is optional as it is 0 by default.

  1. The figure model has method updateView() which you can invoke in your app to apply the sizing policy after plot container size changes.

In the sandbox you can change size of the plot container in the "CSS" panel, then press the "Refresh Plot" button to apply the sizing policy.

I hope this will work for your app.

alshan avatar Mar 07 '24 22:03 alshan