Reputation: 423
I am trying to draw a bar graph that gets updated when a dropdown selection changes.
The following code is included in my html doc, and the leaveStayGraph function is called onChange of dropdown. Every time after the first time leaveStayGraph is called, I get the following error:
Uncaught TypeError: Cannot read property 'x' of undefined
Before subsequent calls (when setData is called), leaveStayData looks perfectly fine (in fact it looks just about the same as it did on the first call, which worked).
var leaveStayChart = null;
function leaveStayGraph(display_data, date) {
/* Do stuff to get data */
// Draw Chart
var leaveStayData = {
element: 'leave_stay_pie_chart',
data: [{
label: "Stayed",
value: count
}, {
label: "Left",
value: total - count
}],
xkey: 'label',
ykeys: ['value'],
labels: ['Count'],
hideHover: 'auto'
};
if (leaveStayChart == null) {
// FIRST CALL
leaveStayChart = Morris.Bar(leaveStayData);
}
else {
// SUBSEQUENT CALLS
leaveStayChart.setData(leaveStayData);
}
}
My end goal is to update the graph upon changing the selection of the dropdown, but every time setData is called, I get this error and nothing displays. Is something happening that I can change.
UPDATE
Just to clarify, the basic idea is something like this (half-taken from the example from morris.js). When the button is pressed, the chart updates.
var x = Morris.Bar({
element: 'bar-example',
data: [
{ y: '2006', a: 100, b: 90 },
{ y: '2007', a: 75, b: 65 },
{ y: '2008', a: 50, b: 40 },
{ y: '2009', a: 75, b: 65 },
{ y: '2010', a: 50, b: 40 },
{ y: '2011', a: 75, b: 65 },
{ y: '2012', a: 100, b: 90 }
],
xkey: 'y',
ykeys: ['a', 'b'],
labels: ['Series A', 'Series B']
});
document.write("<button onClick='update()'>Test</button>");
function update() {
x.setData({
element: 'bar-example',
data: [
{ y: '2006', a: 100, b: 1 },
{ y: '2007', a: 75, b: 65 },
{ y: '2008', a: 46, b: 40 },
{ y: '2009', a: 43, b: 41 },
{ y: '2010', a: 50, b: 40 },
{ y: '2011', a: 3, b: 2 },
{ y: '2012', a: 30, b: 90 }
],
xkey: 'y',
ykeys: ['a', 'b'],
labels: ['Series A', 'Series B']
});
}
Upvotes: 2
Views: 4343
Reputation: 575
So you are on the right track, you just need to pass in the JSON data to setData instead of the entire graph object. So this would be my revised version of your code:
var leaveStayChart = null;
function leaveStayGraph(display_data, date) {
/* Do stuff to get data */
var graphData = [{
label: "Stayed",
value: count
}, {
label: "Left",
value: total - count
}];
if (leaveStayChart == null) {
// FIRST CALL
leaveStayChart = Morris.Bar({
element: 'leave_stay_pie_chart',
data: graphData,
xkey: 'label',
ykeys: ['value'],
labels: ['Count'],
hideHover: 'auto'
});
}
else {
// SUBSEQUENT CALLS
leaveStayChart.setData(graphData);
}
}
Upvotes: 2
Reputation: 423
The issue is that setData doesn't take in the same type of object that is passed in to Morris.Bar(data)
. The object passed into the setData function is the value under data
in the original object.
This would be the revised sample code:
var x = Morris.Bar({
element: 'bar-example',
data: [
{ y: '2006', a: 100, b: 90 },
{ y: '2007', a: 75, b: 65 },
{ y: '2008', a: 50, b: 40 },
{ y: '2009', a: 75, b: 65 },
{ y: '2010', a: 50, b: 40 },
{ y: '2011', a: 75, b: 65 },
{ y: '2012', a: 100, b: 90 }
],
xkey: 'y',
ykeys: ['a', 'b'],
labels: ['Series A', 'Series B']
});
document.write("<button onClick='update()'>Test</button>");
function update() {
x.setData([
{ y: '2006', a: 100, b: 1 },
{ y: '2007', a: 75, b: 65 },
{ y: '2008', a: 46, b: 40 },
{ y: '2009', a: 43, b: 41 },
{ y: '2010', a: 50, b: 40 },
{ y: '2011', a: 3, b: 2 },
{ y: '2012', a: 30, b: 90 }
]);
}
Upvotes: 0