This repository was archived by the owner on Jun 4, 2024. It is now read-only.
This repository was archived by the owner on Jun 4, 2024. It is now read-only.
React "Max update depth exceeded" error with tooltips #883
Open
Description
Mark's app shows the below errors while using both tooltip_conditional
and tooltip_data.
The tooltips still render, but this breaks parts of his app including a script that tweaks the position and innerText of the DataTable's export button.
This is a skeleton of his DataTable implementation:
# app.py
sensitivity_dict = {'Medium': 'Medium Sensitivity', 'High': 'High Sensitivity', 'Low': 'Low Sensitivity'}
tt_data = [{c: {'type': 'text', 'value': sensitivity_dict[d], 'delay': 100, 'duration': 3000} for c, d in row.items() if
c == 'data sensitivity'} for row in df.to_dict('rows')]
tt_data = [
{c: {'type': 'text', 'value': str(d), 'delay': 100, 'duration': 3500} for c, d in row.items() if c in df} for
row in df.to_dict('rows')]
tt_cond = [
{
'if': {
'filter_query': '{data sensitivity} = "Medium"',
'column_id': 'data sensitivity'
},
'delay': 100,
'value': 'Medium Sensitivity',
},
{
'if': {
'filter_query': '{data sensitivity} = "High"',
'column_id': 'data sensitivity'
},
'delay': 100,
'value': 'High Sensitivity',
},
{
'if': {
'filter_query': '{data sensitivity} = "Low"',
'column_id': 'data sensitivity'
},
'delay': 100,
'value': 'Low Sensitivity',
},
]
app.layout = ddk.App([
ddk.ControlCard(width=100, id='table-card', children=[
ddk.DataTable(
id='table',
columns=[{"name": i, "id": i, 'hideable': True} for i in df],
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'filter': 'brightness(120%)'
}
],
data=df.to_dict("rows"),
# editable=True,
fixed_rows={'headers': True},
# page_size=50,
style_table={
'height': '67vh',
'maxHeight': '67vh',
'overflowY': 'auto'
},
style_filter={'height': '35px'},
style_cell={
'height': 'auto',
# all three widths are needed
'minWidth': '180px',
'width': '180px',
'maxWidth': '180px',
#####
'whiteSpace': 'pre-line',
},
style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_selectable="multi",
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action="native",
export_columns='visible',
export_format='csv',
tooltip_data=tt_data,
# tooltip_conditional=tt_cond,
),
ddk.Row([
html.Div(
id="dl-csv-div",
children=[
html.A(
[
html.Button(
"Download Full CSV",
id="full-csv-button",
style={'marginTop': '15px'},
)
],
id="download-full-tbl",
download="full_data.csv",
href='',
target="_blank",
),
]),
]),
])
])
# @app.callback(
# Output('table', 'style_data_conditional'),
# Input('data-sensitivity-colors', 'value')
# )
# @app.callback(
# Output('table', 'data'),
# [Input('forms-dropdown', 'value'),
# Input('offices-dropdown', 'value'),
# Input('systems-dropdown', 'value')]
# )
# @app.callback(
# Output('forms-selected-card', 'value'),
# Output('formats-selected-card', 'value'),
# Output('systems-selected-card', 'value'),
# Input('table', 'derived_virtual_row_ids')
# )
# tweaks.js
// function to create interval and remove once
function createInt(){
var interval = setInterval(function(){
// make sure Dash isn't still loading
var loading = document.querySelector("._dash-loading-callback");
if(tgt){
tgt.style.overflow = "";
}
var tgt = document.querySelector(".sidebar--content");
// if tgt exists and Dash isn't still loading, run command and remove interval
if(tgt && !loading){
tgt.style.overflow = "visible"
if(tgt.style.overflow == "visible"){
// document.removeEventListener("DOMContentLoaded", changeOverflow);
clearInterval(interval);
}
}
}, 1000)
}
function checkBtn(){
var interval = setInterval(function(){
var btn = document.querySelector('.export')
var btn_div = document.getElementById('dl-csv-div');
if(btn){
btn_div.prepend(btn)
btn.innerHTML = 'Download Filtered CSV';
btn.style.marginRight = '10px';
clearInterval(interval);
}
}, 100)
}
// Run the overflow function in an interval to be sure it runs properly
function changeOverflow(){
createInt();
}
// listen for original content loading
document.addEventListener("DOMContentLoaded", function(){
changeOverflow();
checkBtn();
});
// listen for URL change
var oldHref = document.location.href;
window.onload = function(){
var bodyList = document.querySelector("body");
var observer = new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(oldHref != document.location.href){
oldHref = document.location.href;
changeOverflow();
checkBtn();
}
});
});
var config = {
childList: true,
subtree: true,
}
observer.observe(bodyList, config);
}
cc @plotly/product