Search code examples
pythonflaskchartsclickablecanvasjs

On clicking the specific label in Canvasjs Pie chart, pass the clicked label to Flask for further processing


I am working with pie charts using Canvasjs and I want to make it clickable so that if the specific label is clicked it will send the clicked label value to the flask so that I can process that value in the flask also redirect me to the other page
My Chart Code on the index.html page

{%extends "master.html"%}

{%block chart%}
<script>
  window.onload = function () {

var chart = new CanvasJS.Chart("chartContainer", {
    animationEnabled: true,
     exportEnabled: false,
  theme: "light1", // "light1", "light2", "dark1", "dark2"
   backgroundColor: "transparent",
    **data: [{
      click: function (e) {
                            var dataPoint = e.dataPoint.label;
                            window.open({{url_for('jazz_index')}}, "_blank");
                    },**
        type: "doughnut",
        startAngle: 20,
        //innerRadius: 10,
        indexLabelFontSize: 17,
        indexLabelFontColor: "white",
        indexLabel: "#percent%",
        toolTipContent: "<b>{label}:</b> {y} (#percent%)",
        dataPoints: [

        {%for outgoing_number,outgoing_call_type in outgoing_calls%}
        { y: {{outgoing_call_type}}, label: "{{outgoing_number}}" },
            {%endfor%}
            ]
    }]
});
chart.render();
}
</script>

{%endblock%}

{%block body%}
<div class="card-body" id="chartContainer" style="min-height: 250px; height: 250px; max-height: 250px; max-width: 90%;">
                    </div>
{%endblock%}

In this code, I am making a pie chart and I want to pass variable dataPoint to the flask route jazz_index when the specific bar is clicked on the pie chart and I also want to know how to access that variable value in the route jazz_index so that I can process that dataPoint value and redirect the chart to the new page (jazz_index.html) which contains the information related to that dataPoint.

This is my jazz_index route

    @app.route('/jazz', methods=['GET', 'POST'])
def jazz_index():
    return render_template('jazz_index.html')

Please help me out with some code. Thanks in advance


Solution

  • You are using an approach that is not ideal and there are many ways to improve it.

    Having the browser open up a new page just to send data to the back end is not a great user experience.

    Also by the time that your Javascript finally runs, the code for url_for will have already executed and rendered out a url. It's not possible for url_for to dynamically include a value from Javascript like you are attempting to do.

    Without diving too deep into the front end changes that will be required to make this production ready, you can get it "working" by taking an approach similar to below and then improve from there.

    {
        data: [{
            click: function(e) {
                var dataPoint = e.dataPoint.label;
    
                var url = `{{url_for('jazz_index')}}`;
    
                fetch(url + `?dataPoint=${dataPoint}`)
                    .then(response => response.json())
                    .then(data => console.log(data));
            }
        }]
    }
    

    Then in flask you need to get the data from the url parameters.

    @app.route('/jazz', methods=['GET', 'POST'])
    def jazz_index():
        # import request from Flask
        datapoint = request.args.get('dataPoint')
    
        return render_template('jazz_index.html')