-
-
Notifications
You must be signed in to change notification settings - Fork 531
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
WIP adding React Grid Layout Template #1530
Conversation
update fork
this is the firs try to perform a template for React grid layout in a panel holoviz template
@nghenzi . This is such a nice template! Thanks for contributing. |
One question @nghenzi . I can see on the Github page that the cards actually can have a "maximize" button in the upper right corner. Do you know if that can be (easily) done in Panel also? I've had on my todo list for a long time that I would like to enable maximizing my plots. |
Another question. Is it possible to use the template with just one plot that should be maximized? I guess the x, y and h and w are some relative sizes? Another question. Would it be possible to extend the template to provide functionality to dynamically add and remove cards? For example if I click a button I add a new cell. Of as the result of a lengthy calculation I might end up with 2 or 3 new plots that I want to display in seperate cards? |
Another question @nghenzi . I've been writing the awesome-panel-extensions guide at https://awesome-panel.readthedocs.io/en/latest/guides/awesome-panel-extensions-guide/index.html. One of the things I have not yet described is Template extensions. I would like to either link to the code of this template or include it in the docs one day. Would that be ok? Another thing I would like to do is describe how to create bokeh extensions based on React or Vue. I have never used React so getting started I've not been able to do yet. If you have some time and energy it would be awesome if you could contribute a small example or describe how to do it. You can do so in a post on discourse, contribute and example notebook to the Panel gallery, contribute a widget or Panel to Panel or maybe do a PR to the Awesome Panel Extensions guide. |
One more question. Can you actually fix the layout. So that you can actually use the React grid based for static layouts and layouts that the user can drag+drop or resize? |
This is looking fabulous. I'm going to have to spend some time playing around here but at first glance I love it!
That would be fabulous along with the ability to persist the layout. So you could lay things out, export the layout and then freeze it. |
I suppose my other question is: "Can this grid can automatically reflow based on screen size?", e.g. on a mobile device it shows 1 card per row but on a desktop machine it'll have 3. |
Thanks for your answers, the idea of showing the template was to discuss the implementation for easy use of the template. I answer below the quoted question
Yes, I am going to add the maximize button. I think it is easy
The size and position are based in somed parameters inside the template. Now the template has 12 columns with a heigth of 30 px each column. These numbers can be exposed in the initialization of the template
but they are a lot of parameters to configure and the notion of easy-to-use template is lost.
Yes, in the examples sections of the react grid layout template they dynamically add and remove elements. I'm not sure how it can be done, but I am going to watch it.
You can add the code or add a link wherever you want. Once the template is fully working, I can write some docs for the template. I love the awesome-panel-extensions-guide, it is helping me a lot to learn to write bokeh extensions.
I am not an expert in React or Vue, so writing a guide how to use them is out of my scope.
You can define additional properties of the container (or card )in the dictionary when you add it. For example tmpl.main.append(pn.Rowncur, dummy_js , sizing_mode = 'stretch_both')) Note the true is a string lowercase. Aditionally minimun and maximun width and height can be fixed. ( minW: 2, maxW: 4 , minH: 2, maxH: 4 )
The reflow and persistence is the main thing I like of this framework. They have break points and you can save the layout in local storage. I'm working in something similar to the example linked below, but I am still having problem how to reset the layout from python and not from react. https://strml.github.io/react-grid-layout/examples/8-localstorage-responsive.html When I have a fully working version of this I am going to add to this PR. Any other suggestions or comments you have are well accepted and thanks to both of you because I'm learning a lot when using panel (a year ago I only programmed in labview) |
Only changing the configurations of the breakpoints and the numbers of columns <ResponsiveGridLayout className="layout" it seems the framework do some magic and re-arrange the layout. As you can see, when the window get smaller works ok, but when the window get bigger it does not re-arrange. I need more work yet. It is related to this issue, |
For me this template is a game changer. It solves at lot of problems at onde: grid layout, mobile, rediger, maximize. If we you/we can keep it simple and straightfoward to use then its a game changer in my opinion. If we have to say goodbye to some Advanced feature so be it. an Advanced user Can always create a custom template if needed. |
This all looks incredible. Let me know what I can help you with here. |
One suggestion. Would it be an idea to change For example FYI. @philippjfr |
"Bug Report". @nghenzi . The widgets in the side bar in your example do not "stretch_width". You should just change to freq = pn.widgets.FloatSlider(name="Frequency", start=0, end=10, value=2, sizing_mode="stretch_width")
phase = pn.widgets.FloatSlider(name="Phase", start=0, end=np.pi, sizing_mode="stretch_width") |
@philippjfr and @kebowen730 . I guess the progress indicator in the upper right is something from the general template. It looks like this for me There are two problems. One is the overflow of the bar onto the scrollbar? The other is just that in my personal opinion the progress circle should have a little bit more margin on the right. |
@nghenzi . A lot of times when I drag elements they don't drag or I actually drag to content of the plot. Maybe it is something to get used to. Maybe it is just me that have not yet figured out exactly what triggers the drag or where to click for dragging. If you can only drag in certain areas I was thinking whether it would be helpful to have a special mouse cursor when the mouse is over that area? |
@nghenzi (and @philippjfr ) In your example the card does not have a nice margin at the bottom. I tried to solve it by playing with the I tried for example tmpl.main.append(pn.Card(cur, title='Sine',sizing_mode = 'stretch_both', margin=50)) I tried a lot of different hacks without luck. |
@kebowen730 and others When I have clicked the title link it turns blue and underlined. I believe that today people would just keep it the original color (in this case white) and without the underline. |
@kebowen730 and others Regarding the sidebar in the dark theme. It would be really, really nice to have something indicating a clear seperation between the sidebar and the main area. Like for example this example from https://material-ui.com |
@kebowen730 and others I believe (personal preference?) that the hamburger menu needs a little bit more margin. And it would also be really awesome if the menu closed when you click outside the sidebar For inspiration take a look at material-ui.com |
Hi @nghenzi One more question. Do you/ we know that react grid table is the "best" one to choose. I thinking about user experience, about performance about "bundle size" about responsiveness etc. There are alternatives I can see like https://packery.metafizzy.co/ For fixed layouts I've found this http://callmecavs.com/bricks.js/ This one also looks interesting |
Thanks @MarcSkovMadsen for the detailed feedback. Most of these are matters of polish and something I'm happy to tackle even after this is merged. The main items I'd like to see addressed before merging this:
I don't have strong opinions about the various grid libraries but I'd love to see someone summarize the differences between the libraries that @MarcSkovMadsen listed. |
I still working in incorporating your suggestions. Thanks @MarcSkovMadsen and @philippjfr . Today in the night or tomorrow I think I can answer the issues. https://gridstackjs.com/ seems to have the same funcionality that react grid layout, and may be it is easier to use. |
I am observing the same thing. When dragging or resizing, the map zooms out. If you observe your image you can see that you have a lot of worlds inside the map. These two functions do the resizing of the bokeh plot when the card resizes. resize_layout(obj, old_, new_, p, e, element) { resize_layout_stop(obj, old_, new_, p, e, element) { The first function does the resize of bokeh plots while resizing and the second function does the resize when the resize stop. I commented the first function to obtain the same behaviour that the golden layou template, then the crash is leess frecuent, but it is still active. After that, I tried resizing the tab of a map with the golden layout template and the same error appears. I think the error is related to some number really big as the error in js console says "ncaught TypeError: coordinates must be finite numbers" . The x and y scale in the tiles are in web mercator, then in a single plot you have numbers like 10 o 100 thousand. After a while looking for, I found an option of min and max zoom out in bokeh tiles model, but I dont know how to use it. http://docs.bokeh.org/en/latest/docs/reference/models/tiles.html About the dragging, there is no much space due to the fact that you have the plots. I changed the color of the card to white, you can see that if you press in the top white zone, the dragging is working. Maybe that zone can be bigger. I am working to add the maximize button. Once I have that button working, a dragging button or dragging zone can be added to make it easy to select the dragging. |
I try to add a little margin to the card to avoid that, but bokeh do not take it into account. I am searching a solution, but the sizing behaviour is different to common plots. |
Don't worry about minor tweaks like margins and so on for now. I'll take care of that, I'm really more interested in getting the API in good shape and ensuring that resizing works consistently. |
I really wouldn't expect you to have to trigger relayout events on individual plots. It should be sufficient to run global resize events on the window to trigger a relayout: window.dispatchEvent(new Event("resize")) |
great !!! it is very much easy because there is no need to keep track of the id of the plot. The same problem with the resizing of the map appears. Here you can see the same problem with the map resizing in golden layout template About the API, the React grid layout has two different ways of setting the grid properties. The first one is setting the grid properties in the div containing the plot of the element add to the main section
With this the React grid layout make some magic and rearrange the card according to the window width. I have a first protoype working, but in some windows width the card appears in random places. I need to add the data grid property to use this api. This is the reason of the add_data_grid method, after that with some jinja logic I build the div. Each div with a key is a card. I use this print to see the created template The other api is something like this
In this case, the user can define the breakpoints, the number of columns and the layout for each different device window width
This is a lot of configuration as you have to define a layout of evry card for each different breakpoint that you define, but it can be exposed in python trough jinja variables. I am going to create an example for the two api and you can define wich one you prefer to merge. The last thing, in the weekends I have more time to work in these things, so sorry if in working days I am late to answer. |
I found this issue in bokeh tiles Where they force the aspect ratio of the map. |
A work around to this is add a little spacer in a column tmpl.main.append(pn.Column(pn.Card(cur, title='Sine',sizing_mode = 'stretch_both'), |
the configurations of the layouts is exposed like dictionaries
I recently commit the last version of the grid. Now the config of the layouts is exposed through a a dictionary and a method config_layout. There is no magic to interpolate the layout, you have to define the layout in each breakpoint. The i key in the layouts properties now it is defined like a integer from 1 (1,2,3 for each element appended to the layout.) . Later I am going to change it to relate with the ID or data-root-id which the embed(root) provides. Here you have an example
Here you have it working You can define less breakpoints, but you should supply at least one breakpoint via the layouts property. In the layouts properties there is an option to define the card static or dynamic, but I could not get it working, due to the difference in the True from python and the true bolean in jsx. The To Do list is
I |
This is definitely an unrelated problem and I would not try to solve it here.
I'd be okay with merging it without this but it's definitely a nice to have. |
Ok. Great if you merge it ! let me know if something else is necessary When I found the way with the maximize button I'll make other PR. |
Brilliant, could you just resolve the linting issues, it's just a few unused import ./panel/template/__init__.py:7:1: F401 '.react.ReactTemplate' imported but unused
./panel/template/react/__init__.py:11:1: F401 '...layout.ListLike' imported but unused
./panel/template/react/__init__.py:14:1: F401 'random' imported but unused
./panel/template/react/__init__.py:15:1: F401 'string' imported but unused For the first one simple add |
Done ! |
panel/template/react/react.html
Outdated
setTimeout(function(){ | ||
console.log("I am setTimeout", new_['i']); | ||
window.dispatchEvent(new Event("resize")) | ||
// window.Bokeh.index[new_['i'].split('_')[1]].resize_layout(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also just clean up the leftover comments and log statements here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, I'm not used to community programming
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, happens to all of us. This is an amazing first contribution to a project!
Codecov Report
@@ Coverage Diff @@
## master #1530 +/- ##
==========================================
- Coverage 86.07% 85.69% -0.39%
==========================================
Files 141 146 +5
Lines 15640 16069 +429
==========================================
+ Hits 13462 13770 +308
- Misses 2178 2299 +121
Continue to review full report at Codecov.
|
Will merge and start improving it in a new PR. |
Thanks so much for this contribution @nghenzi! |
This pull request is trying to add an easy way to use a draggable and droppable grid in the panel templates. It is based on
https://github.com/STRML/react-grid-layout
The main difference with the other templates is you have to add the position and size of the grid element. Here you have an example
and here you have how it works.