JammoD
JammoD

Reputation: 429

Chart.js BarChart not appearing

I am trying to get a BarChart appear using MVC, EF and json. For some reason the Bar Chart does not load and Google Chrome shows the following error "Uncaught TypeError: Cannot read property 'length' of undefined" in the console.

I am struggling to find the error in my code and hope someone can help me.

DashboardController

    [AjaxOnly]
    public ActionResult WeeklyLatenessSummary()
    {
        ChartHelper chart = new ChartHelper();

        DateTime d = DateTime.Today;

        int offset = d.DayOfWeek - DayOfWeek.Monday;
        offset = (offset < 0) ? 6 : offset;

        DateTime startDate = d.AddDays(-offset);
        DateTime endDate = startDate.AddDays(7);

        var data = (from a in _db.Attendances
                    join at in _db.AttendanceTypes on a.Type equals at.AttendanceTypeID
                    where a.Date >= startDate
                    && a.Date < endDate
                    && at.AttendanceTypeCode == "L"
                    group at by at.AttendanceTypeDescription into g
                    select new
                    {
                        value = g.Count()
                    }).ToList();

        return Json(JsonConvert.SerializeObject(chart.PopulateBarChart("Weekly Lateness", data)), JsonRequestBehavior.AllowGet);
    }

JSON Result

"[{\"label\":\"Weekly Lateness\",\"data\":\"3\",\"fillColor\":\"#F7464A\",\"strokeColor\":\"#F7464A\",\"highlightFill\":\"#FF5A5E\",\"highlightStroke\":\"#FF5A5E\"}]"

View

<div class="col-md-12">
            <div class=" panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">Weekly Lateness Summary</h3>
                </div><!--End of panel-heading-->
                <div class="panel-body">
                    <canvas id="weekly-lateness" width="650" height="300" class="center-block"></canvas>
                </div><!--End of panel-body-->
            </div><!--End of panel-->
        </div><!--End of col-md-12-->

smChart.js

    var ctx3 = $("#weekly-lateness").get(0).getContext("2d");

var barChartOptions = {
    //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
    scaleBeginAtZero: true,

    //Boolean - Whether grid lines are shown across the chart
    scaleShowGridLines: true,

    //String - Colour of the grid lines
    scaleGridLineColor: "rgba(0,0,0,.05)",

    //Number - Width of the grid lines
    scaleGridLineWidth: 1,

    //Boolean - Whether to show horizontal lines (except X axis)
    scaleShowHorizontalLines: true,

    //Boolean - Whether to show vertical lines (except Y axis)
    scaleShowVerticalLines: true,

    //Boolean - If there is a stroke on each bar
    barShowStroke: true,

    //Number - Pixel width of the bar stroke
    barStrokeWidth: 2,

    //Number - Spacing between each of the X value sets
    barValueSpacing: 5,

    //Number - Spacing between data sets within X values
    barDatasetSpacing: 1,

    //String - A legend template
    legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"

}

    var getDaysInMonth = function (month, year) {
        return new Date(year, month, 0).getDate();
    }

    var dates = [];
    for (var i = 1; i <= getDaysInMonth(8,2015); i++) {
        dates.push(i);
    }


    window.onload = function () {
            $.ajax({
            type: "GET",
            dataType: "json",
            url: "/Dashboard/WeeklyLatenessSummary/",
            success: function (data) {
                var json = JSON.parse(data);
                var chartData = [];

                for (var k in json) {
                    chartData.push(json[k])
                }

                if (chartData.length == 0) {
                    $('#weekly-lateness').hide();
                    $('#weekly-lateness').before("<h3 class='text-center'>No Data</h3>");
                }
                else {
                    var myPieChart3 = new Chart(ctx3).Bar(chartData, barChartOptions)
                }
            }
        });
    }

Upvotes: 1

Views: 5150

Answers (2)

potatopeelings
potatopeelings

Reputation: 41065

You're building the chartData variable incorrectly. For reference, here is what it should look like (from http://www.chartjs.org/docs/#bar-chart)

{
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fillColor: "rgba(220,220,220,0.5)",
            strokeColor: "rgba(220,220,220,0.8)",
            highlightFill: "rgba(220,220,220,0.75)",
            highlightStroke: "rgba(220,220,220,1)",
            data: [65, 59, 80, 81, 56, 55, 40]
        },
        {
            label: "My Second dataset",
            fillColor: "rgba(151,187,205,0.5)",
            strokeColor: "rgba(151,187,205,0.8)",
            highlightFill: "rgba(151,187,205,0.75)",
            highlightStroke: "rgba(151,187,205,1)",
            data: [28, 48, 40, 19, 86, 27, 90]
        }
    ] };

The labels (not to be confused with label which is the series name)correspond to the x axis entries and the there is a datasets element for each series. Each series has as many entries in its data array as there are entries in labels


With the sample JSON you've given, here's one way to make the data appear

var chartData = {
    labels: ['Potatoes'],
    datasets: []
};

for (var k in json) {
    chartData.datasets.push(json[k])
}

It will be easier to change it based on your requirements about what needs to be displayed and on which dimension.

Upvotes: 1

WhiteHat
WhiteHat

Reputation: 61222

I would venture to say it is bombing on your legend template when it is rendered. datasets is undefined

legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"

Upvotes: 0

Related Questions