user3697903
user3697903

Reputation: 17

Issues accessing Array for a column chart in Javascript

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!

Upvotes: 0

Views: 121

Answers (2)

Josh Mathews
Josh Mathews

Reputation: 301

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>

Upvotes: 0

zfrisch
zfrisch

Reputation: 8660

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();

}

Upvotes: 1

Related Questions