Reputation: 367
Tools of note: Using Django 3.0, plotly offline, jQuery.
(comment after solution: solved loading plotly.offline.plot() by not including the library inside the plot div.)
I am not sure if my workflow needs changing or if there is a different DOM manipulation technique, but I am seeing slow load times while adding plots into a dashboard. The generated string elements from plots are quite large and could be a factor. (MB size if I interpret the console correctly. I am new to web design.) Basically what I think happens is the jQuery runs, and then once it returns the webpage 'freezes' while it tries to add in the DOM elements.
Okay so here is the current workflow:
Step 3 is really the step I think needs fixing if possible. If not, is there an alternative solution?
Here is my jQuery which I hope can be improved - It is found within 'script' tags inside my .html document at the end (right before the '' tag).
var my_id = {{ my_id }}; //Django template value needed by plotly
$( document ).ready(function() {
var plots_id_tag = "data_plots";//data_plots is my .inner-carousel div element where everything will be inserted
var elmt = document.getElementById(plots_id_tag);
var endpoint = elmt.getAttribute("data-url"); //URL of view
$.ajax({
url: endpoint,
data: {
'my_id': my_id
},
success: function (data) {
var is_first = true;
var concat_divs = ''
//data is a JsonResponse value (serialized)
jQuery.each(data, function(item, val) {
if (is_first){
{#$("#" + plots_id_tag).append("<div class='item active'>" + val + "</div>");#} //Method 1 I tried was appending in loop
concat_divs += "<div class='item active'>" + val + "</div>" //Method two I tried was appending into a single long string.
is_first = false;
}
else {
{#$("#" + plots_id_tag).append("<div class='item'>" + val + "</div>");#}//Method 1
concat_divs += "<div class='item'>" + val + "</div>"//Method 2
}
})
$(elmt).append(concat_divs);//Method 2a
$(elmt).innerHTML(concat_divs);//Method 2b This one doesn't show the plots at all. I see html added to the DOM, but nothing gets shown. If this would be faster, is there an update function I need to call?
}
});
})
Here is the code generation for plotly
def get_plots(df):
#Some data manip here
layout = go.Layout(yaxis=dict(title='My plot', range=[0, y_lim], showline=True, linewidth=1, linecolor='#41b3f9', gridcolor='#e6e9ed'),
xaxis=dict(title=x_dim, showline=True, linewidth=1, linecolor='#41b3f9', gridcolor='#e6e9ed'),
title=title,
titlefont={'size': 18},
showlegend=False,
height=500,
width=1000,
plot_bgcolor='rgba(255,255,255,.3)')
fig = go.Figure(data=[lower_trace, mid_trace, upper_trace], layout=layout)
plot_conf = {'showLink': False, 'displayModeBar': False, 'responsive': True}
div = plot(fig, auto_open=False, output_type='div', config=plot_conf)
return div
Here is part of my view called by jQuery
my_plots = []
for dataframe_to_manip in list_dfs:
my_plots.append(get_plots(dataframe_to_manip)) #long process
return JsonResponse(my_plots, safe=False) #list of div elements generated by plotly
If you need anything else let me know, but I think that gives a descent idea what is going on. Goal - speed performance of the insertion of a number of plotly graph_objects for a dynamical dashboard. I imagine if I can shrink down the size of the plot images that might help. So if you have suggestions there as well, that is fine.
Upvotes: 1
Views: 1120
Reputation: 367
Just in case someone runs across this. It appears that plotly.offline.plot() includes by default the entire plot.ly.js library. So each plot had a copy of the library inside making my html very large (MB sized)
To shrink what needed to be loaded, it is better to use:
plotly.offline.plot(..., include_plotlyjs=False)
And inside your html (before your charts are generate in the html document - so maybe at the top) you put this line:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
This sped up the load time from seconds to almost instant.
There may be a jQuery/js solution, but the above worked for me.
Upvotes: 1