0

I am fairly new to Chart.js and I have tried a lot of different ways of doing this but I just can not seem to resolve loading data from JSON in to a bar type chart.

I am trying to display a chart of monthly expenses with latest version of Chart.js.

The JSON string is as follows:

[{"month":"Jan","amount":"0.00"},{"month":"Feb","amount":"0.00"},{"month":"Mar","amount":"100.00"},{"month":"Apr","amount":"0.00"},{"month":"May","amount":"0.00"},{"month":"Jun","amount":"977.00"},{"month":"Jul","amount":"0.00"},{"month":"Aug","amount":"0.00"},{"month":"Sep","amount":"0.00"},{"month":"Oct","amount":"0.00"},{"month":"Nov","amount":"0.00"},{"month":"Dec","amount":"0.00"}]

My code is as follows:

$(function () {
var chartColors = {
    red: 'rgba(255, 99, 132, 1)',
    blue: 'rgba(54, 162, 235, 1)',
    yellow: 'rgba(255, 205, 86, 1)',
    green: 'rgba(75, 192, 192, 1)',
    purple: 'rgba(153, 102, 255, 1)',
    orange: 'rgba(255, 159, 64, 1)',
    darkgrey: 'rgba(102, 102, 102, 1)',
    maroon: 'rgba(200, 112, 91, 1)',
    khaki: 'rgba(190, 204, 200, 1)'
};

if( $("#ChartExpenseBar").length > 0 ){
    $.ajax({
        type: 'POST',
        url: '/expenses/',
        data: {'expense_chart': 'monthly'},
        success: function(data) {
            var months = [];
            var amount = [];

            for (var i in data) {
                months.push(data[i].month);
                amount.push(data[i].amount);
            }

            var ctx = document.getElementById("ChartExpenseBar").getContext('2d');
            var myChart = new Chart(ctx, {
                type: 'bar',
                data: {
                    //labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
                    labels: months,
                    datasets: [{
                        label: 'Monthly expenses',
                        backgroundColor: [
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange,
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange
                        ],
                        borderColor: [
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange,
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange
                        ],
                        borderWidth: 1,
                        data: amount
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    tooltips: {
                        displayColors: false,
                        callbacks: {
                            // use label callback to return the desired label
                            label: function(tooltipItem, data) {
                                return "£" + tooltipItem.yLabel;
                            },
                            // remove title
                            title: function(tooltipItem, data) {
                                return;
                            }
                        }
                    },
                    legend: {
                        display: false
                    },
                    scales: {
                        xAxes: [{
                            gridLines: {
                                display: false
                            }
                        }],
                        yAxes: [{
                            gridLines: {
                                display: false
                            },
                            ticks: {
                                beginAtZero:true,
                                userCallback: function(value, index, values) {
                                    // Convert the number to a string and splite the string every 3 charaters from the end
                                    value = value.toString();
                                    value = value.split(/(?=(?:...)*$)/);

                                    // Convert the array to a string and format the output
                                    value = value.join('.');
                                    return '£' + value;
                                }
                            }
                        }]
                    }
                }
            });
        },
        error: function() {
            alert("There is a problem with loading the chart!");
        }
    });
}
 });

I can most likely imagine myself doing something very silly that is causing an undefined error, and I would love to see someone help me please.

Much appreciated and thank you.

3 Answers 3

1

Your chart does a POST?

Try something along that lines:

$.ajax({
  url: '/expenses/',
  async: false,
  dataType: 'json',
  type: "GET",
  success: function (d) {
           chartData = {
                labels: d.AxisLabels,
                datasets: [
                    {
                        fillColor: "rgba(220,220,220,0.5)",
                        strokeColor: "rgba(220,220,220,1)",
                        pointColor: "rgba(220,220,220,1)",
                        pointStrokeColor: "#fff",
                        data: d.DataSets[0]
                    }
                ]
            };

            max = Math.max.apply(Math, d.DataSets[0]);
            steps = 10;

            respondCanvas();
        }
    });
};
Sign up to request clarification or add additional context in comments.

1 Comment

You are a life saver. I change the type to GET and the following two were the game changer: async: false and dataType: 'json'. Works like a treat - thank you so much!
1

Minimal reproduction of your code seems to indicate that it is working fine, except the 2 options responsive and maintainAspectRatio (they works fine if the chart is contained in a div). Copy and paste as a new html file into your web server to view.

Key changes made from your sample code:

  • AJAX API call changed to GET from ./
  • Added fake success data

Note: responsive and maintainAspectRatio seems to cause the chart to "tremble", unless the chart is wrapped in a div

Image of chart

The problem could lie in elsewhere, maybe in your server response?

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script
    src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js" integrity="sha256-JG6hsuMjFnQ2spWq0UiaDRJBaarzhFbUxiUTxQDA9Lk=" crossorigin="anonymous"></script>
<div style="width:500px;">
    <canvas id="ChartExpenseBar" width="200" height="200"></canvas>
</div>
<script>

    $(function () {
    var chartColors = {
        red: 'rgba(255, 99, 132, 1)',
        blue: 'rgba(54, 162, 235, 1)',
        yellow: 'rgba(255, 205, 86, 1)',
        green: 'rgba(75, 192, 192, 1)',
        purple: 'rgba(153, 102, 255, 1)',
        orange: 'rgba(255, 159, 64, 1)',
        darkgrey: 'rgba(102, 102, 102, 1)',
        maroon: 'rgba(200, 112, 91, 1)',
        khaki: 'rgba(190, 204, 200, 1)'
    };

    if( $("#ChartExpenseBar").length > 0 ){
        $.ajax({
            type: 'GET',
            url: './',
            data: {'expense_chart': 'monthly'},
            success: function(data) {
                var months = [];
                var amount = [];
                // fill with fake data
                data = [{"month":"Jan","amount":"0.00"},{"month":"Feb","amount":"0.00"},{"month":"Mar","amount":"100.00"},{"month":"Apr","amount":"0.00"},{"month":"May","amount":"0.00"},{"month":"Jun","amount":"977.00"},{"month":"Jul","amount":"0.00"},{"month":"Aug","amount":"0.00"},{"month":"Sep","amount":"0.00"},{"month":"Oct","amount":"0.00"},{"month":"Nov","amount":"0.00"},{"month":"Dec","amount":"0.00"}];
                for (var i in data) {
                    months.push(data[i].month);
                    amount.push(data[i].amount);
                }

                var ctx = document.getElementById("ChartExpenseBar").getContext('2d');
                var myChart = new Chart(ctx, {
                    type: 'bar',
                    data: {
                        //labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
                        labels: months,
                        datasets: [{
                            label: 'Monthly expenses',
                            backgroundColor: [
                                chartColors.red,
                                chartColors.blue,
                                chartColors.yellow,
                                chartColors.purple,
                                chartColors.green,
                                chartColors.orange,
                                chartColors.red,
                                chartColors.blue,
                                chartColors.yellow,
                                chartColors.purple,
                                chartColors.green,
                                chartColors.orange
                            ],
                            borderColor: [
                                chartColors.red,
                                chartColors.blue,
                                chartColors.yellow,
                                chartColors.purple,
                                chartColors.green,
                                chartColors.orange,
                                chartColors.red,
                                chartColors.blue,
                                chartColors.yellow,
                                chartColors.purple,
                                chartColors.green,
                                chartColors.orange
                            ],
                            borderWidth: 1,
                            data: amount
                        }]
                    },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        tooltips: {
                            displayColors: false,
                            callbacks: {
                                // use label callback to return the desired label
                                label: function(tooltipItem, data) {
                                    return "£" + tooltipItem.yLabel;
                                },
                                // remove title
                                title: function(tooltipItem, data) {
                                    return;
                                }
                            }
                        },
                        legend: {
                            display: false
                        },
                        scales: {
                            xAxes: [{
                                gridLines: {
                                    display: false
                                }
                            }],
                            yAxes: [{
                                gridLines: {
                                    display: false
                                },
                                ticks: {
                                    beginAtZero:true,
                                    userCallback: function(value, index, values) {
                                        // Convert the number to a string and splite the string every 3 charaters from the end
                                        value = value.toString();
                                        value = value.split(/(?=(?:...)*$)/);

                                        // Convert the array to a string and format the output
                                        value = value.join('.');
                                        return '£' + value;
                                    }
                                }
                            }]
                        }
                    }
                });
            },
            error: function() {
                alert("There is a problem with loading the chart!");
            }
        });
    }
    });

</script>

3 Comments

Hi Edwin, let me just quickly try this - much appreciated!
Hi Edwin, thank you for all your help. Please refer to the below answer, and I changed the type to GET as per your advice as well.
@Cam this means that your server is not configured to respond to that API call with the POST method. :) Happy I could be of help.
1

In case anyone finds themselves in a similar position, I have highlighted the answer to the above problem below - thank you to wp78de and Edwin.

  $(function () {
var chartColors = {
    red: 'rgba(255, 99, 132, 1)',
    blue: 'rgba(54, 162, 235, 1)',
    yellow: 'rgba(255, 205, 86, 1)',
    green: 'rgba(75, 192, 192, 1)',
    purple: 'rgba(153, 102, 255, 1)',
    orange: 'rgba(255, 159, 64, 1)',
    darkgrey: 'rgba(102, 102, 102, 1)',
    maroon: 'rgba(200, 112, 91, 1)',
    khaki: 'rgba(190, 204, 200, 1)'
};

if( $("#ChartExpenseBar").length > 0 ){
    $.ajax({
        type: 'GET',
        async: false,
        dataType: 'json',
        url: '/expenses/',
        data: {'expense_chart': 'monthly'},
        success: function(data) {
            var months = [];
            var amount = [];

            for (var i in data) {
                months.push(data[i].month);
                amount.push(data[i].amount);
            }

            var ctx = document.getElementById("ChartExpenseBar").getContext('2d');
            var myChart = new Chart(ctx, {
                type: 'bar',
                data: {                    
                    labels: months,
                    datasets: [{
                        label: 'Monthly expenses',
                        backgroundColor: [
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange,
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange
                        ],
                        borderColor: [
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange,
                            chartColors.red,
                            chartColors.blue,
                            chartColors.yellow,
                            chartColors.purple,
                            chartColors.green,
                            chartColors.orange
                        ],
                        borderWidth: 1,
                        data: amount
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    tooltips: {
                        displayColors: false,
                        callbacks: {
                            // use label callback to return the desired label
                            label: function(tooltipItem, data) {
                                return "£" + tooltipItem.yLabel;
                            },
                            // remove title
                            title: function(tooltipItem, data) {
                                return;
                            }
                        }
                    },
                    legend: {
                        display: false
                    },
                    scales: {
                        xAxes: [{
                            gridLines: {
                                display: false
                            }
                        }],
                        yAxes: [{
                            gridLines: {
                                display: false
                            },
                            ticks: {
                                beginAtZero:true,
                                userCallback: function(value, index, values) {
                                    // Convert the number to a string and splite the string every 3 charaters from the end
                                    value = value.toString();
                                    value = value.split(/(?=(?:...)*$)/);

                                    // Convert the array to a string and format the output
                                    value = value.join('.');
                                    return '£' + value;
                                }
                            }
                        }]
                    }
                }
            });
        },
        error: function() {
            alert("There is a problem with loading the chart!");
        }
    });
   }
 });

Comments

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.