-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
New features for dcc.Loading #2760
Conversation
components/dash-core-components/src/components/Loading.react.js
Outdated
Show resolved
Hide resolved
@AnnMarieW Could you give an example of when target_component is used? delay_show and delay_hide seem reasonable and the implementation makes sense to me. |
components/dash-core-components/src/components/Loading.react.js
Outdated
Show resolved
Hide resolved
@AnnMarieW This is really exciting, the loading opacity update is really clever, and the demonstrations are really helpful to understand the scope of these updates. |
@AnnMarieW re: 'mode' prop- What you implemented matches the Loading behavior that I'd like to have. I'd consider changing the name, however. 'mode' seems like a execution context rather than 'on or off.' I'd perhaps use 'mode' to be 'auto' or 'manual' and 'manual' would disable targeted loading state and consideration of the loading state of children, and instead would rely on another prop like 'setLoading' or something. This would clarify that the Loading component is either driven by state that can be inferred from the renderer (those components whose state are waiting for backend information) or directly specified by the user (indirectly related components, like a search option that should be put into a loading state while something else is executing). |
@JamesKunstle I'm not sure what you mean re the mode prop. Can you clarify or supply some code? |
@AnnMarieW So When not in In if (manual_mode) {
setShowSpinner(set_loading);
return;
} Here's a concrete example: Imagine that I have a dcc.Interval component that fires every 5 seconds, making a request to the backend to check whether an asynchronous resource is available. Another component, like a Dropdown, indirectly relies on the availability of that resource, so it should be in a forced Loading state that stays enabled even when the dcc.Interval is waiting to fire again. If I could use manual mode, a final successful return from the callback that handles the Interval logic could disable loading for the Dropdown. This way, Loading becomes a developer-controllable state that is managed by application logic rather than by the dash renderer. |
const hiddenContainer = mergeRight( | ||
{visibility: 'hidden', position: 'relative'}, | ||
overlay_style | ||
); |
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.
overlay_style
to set dcc.Loading
to be semi-translucent feels like a really common use case. I wonder if it's worth adding a prop like opacity
to specify explicitly with some default styles applied?
This way developers don't need to remember the more complex e.g. overlay_style={"visibility":"visible", "opacity": .5, "backgroundColor": "white"}
if they just want to make the overlay translucent?
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.
I thought about that, but I expect most people would tweak the opacity and background color depending on the theme (light/dark). Or do know some CSS that would work in most cases?
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 probably pick a neutral grey? I've found #7F8487
is a good middle ground grey that works well in light and dark.
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.
I can try that - but still want to give the ability for people to use any CSS in overlay_style
. Are you suggesting another prop, perhaps that sets {"visibility":"visible", "opacity": .5, "backgroundColor": "#7F8487"}
?
Then what if people set both props?
If there are a couple examples in the docs, it might work OK to just leave it as-is?
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.
Yeah, maybe let's leave as-is for now with good examples in the docs, and see if there is community feedback from there?
* example: `[{"output-container": "children"}]` | ||
* | ||
*/ | ||
target_components: PropTypes.arrayOf(PropTypes.object), |
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.
I wonder if this would be better as
objectOf(arrayOf(string))
or perhaps
objectOf(oneOfType([string, arrayOf(string)]))
so you could do something like:
target_components={"my_table": ["data", "columns"], "my_dropdown": "options"}
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.
I added this, plus it's possible to use a wildcard. This will trigger loading for any prop in the "my_table"
component
target_components={"my_table": "*", "my_dropdown": "options"}
re: What about borrowing from CSS: |
Re: api for enabling/disabling, what feels most intuitive to me is |
That, for me, feels ergonomically less nice for the same reason that it does for dcc.Interval - negating 'disabled' in my head to set the correct boolean value takes a few more cycles than I want, and I normally create global variables to solve it, like "INTERVAL_DISABLED" = True, "INTERVAL_ENABLED" = False, etc.
Passing a string parameter for 'display' seems reasonable |
Ok great, let’s go with |
Done |
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.
💃 Super excited about these changes. I think it'd be nice to have a dedicated opacity
prop but I understand concerns about color... so I don't feel super strongly about this, as long as it's well-documented.
On that note... is there a corresponding docs PR?
I can work on the docs PR next. |
Super excited for these! |
Can we hold on merging while I work on a fix for #2775 |
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.
💃
Here's the PR for the docs https://github.com/plotly/ddk-dash-docs/pull/2570 |
Hello AnnMarieW, thank you very much for implementing the features delay_show and delay_hide to dcc.Loading. Thank You very much in Advance
dash==2.14.1 After updating dash: |
Hi @schultz77 Thanks! I’m looking forward to it too 🙂. This will be available in the next release (Dash 2.17) |
Ok! Thank You for your quick reply. In the meantime I'll keep using dbc.Spinner... |
This PR adds features to
dcc.Loading
delay_show
anddelay_hide
props to prevent flickering when the loading spinner shows only for a short time. (same as in the Dash Bootstrap Components dbc.Spinner)overlay_style
prop so you can do things like make children visible during loading and add opacity.target_components
prop to specify which component/props can trigger the loading spinnercustom_spinner
prop so you can provide your own spinner rather than using the built-in optionsdisplay
prop to override the loading status. Can set to "show", "hide", or "auto"Closes:
#951
#2147 will be fixed by using
delay_show
#1922 will be fixed by using
target_components
#1802 will be fixed by using
delay_show
#2422 will be fixed by using
delay_show
#879 will be possible by using
custom_spinner
andoverlay_style
#736. can't replicate the issue
Closes from the old dcc repo
plotly/dash-core-components#873 - possible with
custom_spinner
anddelay_show
#1541 - can't replicate the issue
plotly/dash-core-components#709 - possible with
target_components
Contributor Checklist
To Do / Questions
Controlling the visibility of the component being loaded with the opacity and background color of the spinner would be a breaking change. Probably need to find a better way to make it possible to add opacity to the component . Update: added
overlay_style
prop.Add ability to manually trigger loading as requested in [Feature Request] Make
dcc.Loading
toggle-able attribute for enabled/disabled #2696 . It's currently called "mode" with options "on", "off", "auto".Would setting a
delay_hide
time solve the issue where there is a lag between the callback finishing and a figure rendering with large data sets? Or might that time be too variable? If this is a solution, I'd need to update thedelay_hide
timer because it currently sets a minimum time for the timer to display rather than extending the display time. See provide loading Indicator during plotly rendering #2690I have run the tests locally and they passed.
I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR
I have added entry in the
CHANGELOG.md
If this PR needs a follow-up in dash docs, community thread, I have mentioned the relevant URLS as follows
Example 1
delay_hide
anddelay_show
propThe
delay_hide
anddelay_show
props can be used to prevent flickering when the loading spinner shows only for a short time.This callback runs for 500ms. This example shows how to:
delay_show=700
.delay_hide=2000
A good use-case for
delay_show
is whenhoverData
is used in a callback. A good demo is this cross filter example in the docs Try wrapping the app layout withdcc.Loading([<example app layout> ], delay_show=500)
Example 2
target_components
propUse the
target_components
prop to specify which component/props can trigger the loading spinner.By default, Loading fires when any child element enters loading state. This makes loading opt-in: Loading animation only enabled when one of target components/props enters loading state.
target_components
is a dict where the key is the component id, and the value is the prop name | list of prop names | "*"examples - the following will trigger the loading spinner:
Any prop in the "grid" component
Either the grid's
rowData
orcolumnDefs
Only the grid's
rowData
Example 3 Styling with
overlay_style
propDefault: content is hidden while loading
Styled with
overlay_style={"visibility":"visible", "opacity": .5, "backgroundColor": "white"}
This keeps the content visible while loading and adds opacity
Example 4
custom_spinner
propInstead of using one of the built-in spinner component, you can provide your own.
A
custom_spinner
can be used to remove/hide the spinner. This is a convenient way to remove the spinner when using nesteddcc.Loading
components.It's possible to create a component with custom loading messages using any Dash components.
This example uses:
Example 5
display
propUse the
display
prop to manually display or hide the loading spinner. Set to "show", "hide" or "auto"(the default)