首页 > 解决方案 > 根据用户点击从绘图地图更新图表 - Flask

问题描述

我正在尝试通过用户单击更新一个绘图图表(在绘图等值线图上)。后端使用 Flask 运行。我在 AJAX 和 JS 方面的知识有限,但多亏了一些好的教程,我已经能够重现一些接近我正在寻找的东西。使用 Dash 可能会更容易,但我想坚持使用 Plotly、JS 和 AJAX。

烧瓶

#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>

烧瓶前端

如您所见,折线图将根据用户输入进行更新。我一直在尝试解决此代码以使其适应我的用例,但没有成功。我不知道如何获取用户点击值并将其传递回烧瓶。

谢谢!

标签: javascriptpythonajaxflaskplotly

解决方案


您可以尝试使用情节点击event 处理程序来调用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>

推荐阅读