Issue
I am trying to update a plotly chart from a user click (on a plotly choropleth map). The backend is running with Flask. I have limited knowledge in AJAX and JS but thanks to some good tutorials I have been able to reproduce something close to what I am looking for. It would be probably easier to use Dash but I would like to stick with Plotly, JS and AJAX.
FLASK
#Reserve page
@app.route('/reserves/', methods = ["POST","GET"])
def reserves():
reserves_map = map()
return render_template("reserves.html", reserves_map = reserves_map, graphJSON=map_filter())
#Callback when clicking on a country from the map with oil & gas reserves
@app.route('/callback', methods=['POST', 'GET'])
def cb():
return map_filter(request.args.get('data'))
#update graph with the country selected
def map_filter(country='US'):
df = sql("""select country.id_country, year, country, oilreserves_bbl, gasreserves_tcm
from country
inner join oilgas as a on country.id_country = a.id_country;""")
fig = px.line(df[df['country']==country], x="year", y="oilreserves_bbl")
graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
return graphJSON
HTML
<!-- Map Reserves-->
<div class='persomargin' style="text-align: center; width:100%; border-radius: 7px; padding: 0px 0px;">
<div class="wrap" >
<div class="one" style="text-align: left; margin-top:35px;" shadow="">
<center><h6>Oil & Gas proved reserves in the the World</h6></center>
<div id="map" class="map"></div>
<center><i style="font-size: 70%">Source: <a href="https://www.bp.com/en/global/corporate/energy-economics/statistical-review-of-world-energy/downloads.html" target="_blank">BP - Statistical Review of World Energy (2019)</a></i></center>
</div>
</div>
</div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
var map_var = {{reserves_map | safe}};
var config = {displayModeBar: false};
Plotly.setPlotConfig(config);
Plotly.plot("map",map_var);
</script>
<!-- Function to update line plot-->
<script>
function update_graph(selection) {
$.getJSON({
url: "/callback", data: { 'data': selection }, success: function (result) {
Plotly.newPlot('chart', result, {});;
}
});
}
</script>
<div id='myDiv'><center><h6>Oil & Gas proved reserves in the the World</h6></center></div>
<!-- user input country name-->
<input type="text" id="fname" name="fname" onchange="update_graph(this.value)">
<!-- Line plot html-->
<div id="chart" class="chart"></div>
<!-- Line plot -->
<script type="text/javascript">
d = {{ graphJSON | safe }};
var config = {displayModeBar: false};
Plotly.setPlotConfig(config);
Plotly.newPlot('chart', d, {});
</script>
As you can see, the line chart will be updated based on the user input. I have been trying to work around this code to adapt it to my usecase but without success. I don't know how to get the user click value and pass it back to flask.
Thank you!
Solution
You can try using a plotly click event
handler to call update_graph
<script type="text/javascript">
var map_var = {{reserves_map | safe}};
var config = {displayModeBar: false};
var map = document.getElementById('map'),
Plotly.setPlotConfig(config);
Plotly.plot("map",map_var);
map.on('plotly_click', function(data){
update_graph(data.points[0].location);
});
</script>
Answered By - Musa
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.