Reputation: 429
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
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
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