Hidden parent div and bug in Motionchart?

37 views
Skip to first unread message

Ümit

unread,
Jun 22, 2011, 8:20:15 AM6/22/11
to google-visua...@googlegroups.com
I am trying to use the motionchart inside a GWT application. The motionchart is displayed in a div which is hidden (style="display:none").
The first time I call draw on the motionchart everything works fine. However when I call the draw method a second time I get following error in the javascript console:

  (TypeError): this.d().dataChanged is not a function stack: ([object Object],[object Object])@http://www.google.com/uds/api/visualization/1.0/c044e0de584c55447c5597e76d372bc1/default,motionchart+en_US,corechart.I.js:621
           at Unknown.anonymous(Unknown Source) 
           at Unknown.rD(Unknown Source) 
           at Unknown.jD(Unknown Source) 
           at Unknown.mD(Unknown Source) at Unknown.jZb(Unknown Source) 
           at Unknown.nZb(Unknown Source) at Unknown.YXb(Unknown Source) 
           at Unknown.Kj(Unknown Source) at Unknown.eU(Unknown Source) 
           at Unknown.IU(Unknown Source) at Unknown.anonymous(Unknown Source) 
           at Unknown.QL(Unknown Source) at Unknown.TL(Unknown Source) 
           at Unknown.anonymous(Unknown Source) at Unknown.anonymous(Unknown Source)

I tried to reproduce this error in pure Javascript in the Code Playground but I somehow stumbled over a different behavior (not sure if that is intended). 
When the motionchart is placed inside a hidden div (style="display:none") then the ready event is not fired. If the div is not hidden then the ready event is fired properly. Is this a bug or is it by design?

See here: http://savedbythegoog.appspot.com/?id=ef4df2ecf81908147e071b4502b5a22941473170 (check the javascript console. if the ready event is fired there should be a 'ready' and 'draw' log entry)

thanks in advance

Uemit



asgallant

unread,
Jun 22, 2011, 9:32:03 AM6/22/11
to google-visua...@googlegroups.com
I've encountered that second error before; I don't know if it's a bug or not, but to work around it you have to draw the charts in visible divs, and then hide your divs after the charts fire their ready events.  That may be what you need to do to work around your first problem, too.

Ümit

unread,
Jun 22, 2011, 9:46:28 AM6/22/11
to google-visua...@googlegroups.com
I could reproduce the error in the following cod sample: http://savedbythegoog.appspot.com/?id=9a0851a0489270bb5535ab87dba942ad6e3614c9

Again I put a motionchart into a hidden div. If I press the "Show" button the hidden div will be displayed and the draw method of the motionchart is called. This works for the first time. As soon as I hide the container div again (by clicking on the button) and displaying it again I get following error:  Object #<HTMLEmbedElement> has no method 'dataChanged'

I only get this error if I use style="display:block/none for the div. It doesn't occur if I use style="visibility:visible/hidden". 

In my case GWT automatically uses the display:none style setting for hiding widgets and therefore I suffer from this problem. 

asgallant

unread,
Jun 22, 2011, 10:40:25 AM6/22/11
to google-visua...@googlegroups.com
Sorry about the display vs visibility thing...I meant to imply using display:block/none rather than visibility.

Is there any particular reason to redraw the chart when you unhide it a second time?  Your error seems to stem from the redraw.  If you rewrite the code like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Google Visualization API Sample</title>
<script type="text/javascript" src="http://www.google.com/jsapi"></script> 
<script type="text/javascript"> 
google.load('visualization', '1', {packages: ['motionchart']});

function drawVisualization() {
var count = 0;
var data = new google.visualization.DataTable();

data.addRows(6);
data.addColumn('string', 'Fruit');
data.addColumn('date', 'Date');
data.addColumn('number', 'Sales');
data.addColumn('number', 'Expenses');
data.addColumn('string', 'Location');
data.setValue(0, 0, 'Apples');
data.setValue(0, 1, new Date (1988,0,1));
data.setValue(0, 2, 1000);
data.setValue(0, 3, 300);
data.setValue(0, 4, 'East');
data.setValue(1, 0, 'Oranges');
data.setValue(1, 1, new Date (1988,0,1));
data.setValue(1, 2, 950);
data.setValue(1, 3, 200);
data.setValue(1, 4, 'West');
data.setValue(2, 0, 'Bananas');
data.setValue(2, 1, new Date (1988,0,1));
data.setValue(2, 2, 300);
data.setValue(2, 3, 250);
data.setValue(2, 4, 'West');
data.setValue(3, 0, 'Apples');
data.setValue(3, 1, new Date(1988,1,1));
data.setValue(3, 2, 1200);
data.setValue(3, 3, 400);
data.setValue(3, 4, "East");
data.setValue(4, 0, 'Oranges');
data.setValue(4, 1, new Date(1988,1,1));
data.setValue(4, 2, 900);
data.setValue(4, 3, 150);
data.setValue(4, 4, "West");
data.setValue(5, 0, 'Bananas');
data.setValue(5, 1, new Date(1988,1,1));
data.setValue(5, 2, 788);
data.setValue(5, 3, 617);
data.setValue(5, 4, "West");

window.motionchart.draw(data, {'width': 800, 'height': 400});
}

function toggleVisibility(ctrl) {
container = document.getElementById('container');
console.log(ctrl.value);
if (ctrl.value=='Show_first') {
container.style.display = 'block';
ctrl.value='Hide';
drawVisualization();
}
else if (ctrl.value=='Show') {
container.style.display = 'block';
ctrl.value='Hide';
}
else {
container.style.display = 'none';
ctrl.value='Show';
}
}
google.setOnLoadCallback(function() {
document.getElementById('button').style.visibility = 'visible';
window.motionchart = new google.visualization.MotionChart(document.getElementById('visualization'));
console.log(window.motionchart);
});

</script> 
</head> 
<body style="font-family: Arial;border: 0 none;"> 
Refresh Motionchart
<input id="button" type="button" value="Show_first" onclick="toggleVisibility(this);"></input> 
<div id="container" style="display:none">  <!-- use visibility:hidden for the other case --> 
Motionchart
<div id="visualization" style="width: 800px; height: 400px;"></div> 
</div> 
</body> 
</html> 

Then it only draws the function the first time you click the button.  You can then hide and unhide it as many times as you like.

Ümit

unread,
Jun 22, 2011, 10:56:45 AM6/22/11
to google-visua...@googlegroups.com
Yes that's true. 
Unfortunately in my case the underlying DataTable might have been changed in the meantime and thus I have to redraw the motionchart. 
What also does work is to recreate the motionchart instance in the drawVisualization() method. Somehow it seems that there is an issue with re-using that instance when doing a redraw of the motionchart. 





Reply all
Reply to author
Forward
0 new messages