0

I'm building a flask app in python and i return 2 arrays using render_template, names and deals to my HTML file. I know these work because of the code beneath that I tried, giving the right values.

{% for deal in deals %}
        <p>Value: {{ deal }}</p>
{% endfor %}

This shows that I've got access to them in HTML. What I want to do next is get some graphics and see the values on the y-axel and the names as labels of each bar on the chart. I found a graph example from Chart.js and started working with it. But I am not getting anywhere, and the only thing I truly want is to change the data points, so instead of hardcoding it like this:

{ y: 233244, label: "Venezuela" }

it could be:

{ y: deals[i], label: names[i]  }

This is the whole chart function.

<script>
window.onload = function () {

var chart = new CanvasJS.Chart("chartContainer", {
    animationEnabled: true,
    theme: "light2",
    title:{
        text: "Top Oil Reserves"
    },
    axisY: {
        title: "Reserves(MMbbl)"
    },
    labels: names,
    data: [{
        type: "column",
        showInLegend: true,
        legendMarkerColor: "grey",
        legendText: "MMbbl = one million barrels",
        dataPoints: [
            { y: 233244, label: "Venezuela" },
            { y: 266455,  label: "Saudi" },
            { y: 169709,  label: "Canada" },
            { y: 158400,  label: "Iran" },
            { y: 142503,  label: "Iraq" },
            { y: 101500, label: "Kuwait" },
            { y: 97800,  label: "UAE" },
            { y: 80000,  label: "Russia" }
        ]
    }]
});
chart.render();

}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>

I SOLVED IT, this was the easiest and probably best way to achieve it in. I finally got through it and can claim both arrays in the graph. My solution looks like this:

var jsDeals = {{ deals|tojson }};
var jsNames = {{ names|tojson }};
var sum = {{ sum|tojson }};

var limit = jsDeals.length;
var dataP = [];

 function parseDataPoints () {
        for (var i = 0; i <= limit; i++)
          dataP.push({y: jsDeals[i], label: jsNames[i]});
 }
 parseDataPoints();

its the tojson part that did the part. Thanks for your help!

2 Answers 2

1

You can create a script tag and declare the variables dynamically in the head of your HTML:

<script>
let chartData = { deals: [], names: [] };

{% for deal in deals %}
    chartData.deals.push("{{ deal }}");
{% endfor %}

{% for name in names %}
    chartData.names.push("{{ name }}");
{% endfor %}

chartData.dataPoints = chartData.deals.map((deal, index) => ({
  y: deal,
  label: chartData.names[index]
}));

</script>

Then change your existing code to simply use the created variables.

var chart = new CanvasJS.Chart("chartContainer", {
    animationEnabled: true,
    theme: "light2",
    title:{
        text: "Top Oil Reserves"
    },
    axisY: {
        title: "Reserves(MMbbl)"
    },
    labels: names,
    data: [{
        type: "column",
        showInLegend: true,
        legendMarkerColor: "grey",
        legendText: "MMbbl = one million barrels",

        dataPoints: chartData.dataPoints

    }]
});
chart.render();

}
Sign up to request clarification or add additional context in comments.

6 Comments

Hey, I tried this. It doesn't seem like it has access to the arrays because the graph won't display. It's completely blank.
console.dir the chartData variable and let me know if it's undefined. Apologies, I can't really test because I don't have the setup you do.
I haven't used console.dir before, so It's going to take me a few minutes to figure out. But I'll get back to you fast.
@user3697903 You would just put in console.dir( chartData ); somewhere after your current code. In your Browser console ( ctrl+shift+j on Chrome, F12 on IE ) you should see something print out :)
:) thank you. It says that chartData is undefined. Exact message is "Uncaught ReferenceError: chartData is not defined"
|
0

Make your own function to do this. First, initialize the chart:

var chart = new CanvasJS.Chart("chartContainer", {
    animationEnabled: true,
    theme: "light2",
    title:{
        text: "Your title"
    },
    axisY: {
        title: "Deals"
    },
    labels: names,
    data: [{
        type: "column",
        showInLegend: true,
        legendMarkerColor: "grey",
        legendText: "MMbbl = one million barrels",
        dataPoints: []
    }]
});

Then, you could have a function to initialize your data:

function initData(deals, names, chart) {
    var n = deals.length;
    for(var i = 0; i < n; i++) {
        chart.data[0].dataPoints.push({y: deals[i], label: names[i]})
    }
    chart.render();
}

After creating the new chart, simply call initData(deals,names,chart);

If you want to add more data to the chart after initializing it, use this function:

function addNewDeal(deal, name, chart) {
    chart.data[0].dataPoints.push({y: deal, label: name});
    chart.render();
}

Hope this answered your question. Remember, every time that you want to change the data, to see the change you must call chart.render().

edit:

The final result, including the html, should look something like:

<!DOCTYPE html>

<html>
    <head>
        <script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
        <script>
            function initData(deals, names, chart) {
                var n = deals.length;
                for(var i = 0; i < n; i++) {
                    chart.data[0].dataPoints
                         .push({ y: deals[i], label: names[i]});
                }
                chart.render();
            }
            window.onload = () => {
                var chart = new CanvasJS.Chart("chartContainer", {
                    animationEnabled: true,
                    theme: "light2",
                    title:{
                        text: "Your title"
                    },
                    axisY: {
                        title: "Deals"
                    },
                    labels: names,
                    data: [{
                        type: "column",
                        showInLegend: true,
                        legendMarkerColor: "grey",
                        legendText: "MMbbl = one million barrels",
                        dataPoints: []
                    }]
                });
                chart.render()
                var names = ["name1", "name2", "name3"];
                var deals = [1,2,3];
                initData(deals, names, chart);
            }
        </script>
    </head>
    <body>
        <div id="chartContainer"></div>
    </body>
</html>

4 Comments

Hey Josh, Tried this as well. Unfortunately the graph is still blank, and the only explanation I've found is that the datapoints doesn't have access to the arrays.
@user3697903 I just updated the post with a functional example.
@user3697903 try console logging your deals and names before calling the init function if you can't get this to work :)
Thanks for the help. What happens is that i replace the two "var names =..." and "var deals =..." with the arrays that I want in the call to initData. It didn't work, If i however created chartData in the way of the other answer on here, and then use them in the call to initData, the graph did display the column names correctly. The only thing missing was then getting the values to somehow show.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.