Animated Statistics Using R (to be moved to AniWiki!)
To better illustrate animations in web pages, there is still some work to do.
How are Pictures Animated by JavaScript?

As I have explained in the page "Animation Tricks", the animation is constructed using custom JavaScript functions to continually display the image frames one after another by a certain time interval. To fulfill this idea, we should first of all prepare a series of images (either hidden somewhere in a page or only URLs), then find a way to display them sequentially through a loop with a time interval specified by the function setTimeout().

setTimeout ( expression, timeout );

The code in the second part below has shown a complete example for the usage.

How to Guarantee the Speed of Loading Illustation?

Of course we hope the downloading of our animations can be as fast as possible so that they can be displayed more fluently, or the user has to wait for some time till all the frames of an animation have been downloaded. To solve this problem, we simply need to preload all the frames beforehand.

I searched online and found the one and almost only solution: nearly all people told us to create an image object in JavaScript and by assigning image addresses to the src attribute of this object one by one (via a loop), those image frames will also be downloaded into the cache of the user and can be used again later in the animation.

However, I found this solution was actually invalid! Images cannot be loaded by this way, because JavaScript will not wait for the downloading of images! But through my trials, I discovered another really valid method (for both Mozilla Firefox and Microsoft Internet Explorer). The idea is still taking advantage of the web browser's cache: we hide those images in a division (<div></div>) in order that they can really be downloaded into the browser's cache.

We first download the images in the hidden division with id = "divPreload", then these images will be displayed one after another using the function displayImage() which continually change the CSS styles (to display or not to display) of divisions containing image frames. Besides, I've also provided two functions stopImage() for terminating the animation and fasterImage() for controlling the time interval of the animation.

  1. <html>
  2. <head>
  3. <title>Animated Statistics Using R -- Yihui XIE</title>
  4. <style type="text/css">
  5. #percent {
  6. background-color: #FF0000;
  7. height: 100%;
  8. color: #FFFFFF;
  9. font-family: "Bitstream Vera Sans Mono", "Courier New", monospace;
  10. }
  11. #divDemo {
  12. height: 300px;
  13. }
  14. #divPreload {
  15. display: none;
  16. }
  17.  
  18. #divControl {
  19. margin-top: 20px;
  20. margin-bottom: 10px;
  21. font-family: "Bitstream Vera Sans Mono", "Courier New", monospace;
  22. font-size: 12px;
  23. }
  24.  
  25. #loading {
  26. font-family: "Bitstream Vera Sans Mono", "Courier New", monospace;
  27. color: #FFFFFF;
  28. background-color: #990000;
  29. padding: 2px;
  30. width: 30%;
  31. float: left;
  32. margin-top: 10px;
  33. text-align: left;
  34. }
  35. </style>
  36. <script language="JavaScript" type="text/javascript">
  37. var t
  38. var n = 1
  39. var i = 1
  40. var nmax = 10 //how many graphs to be shown
  41. function displayImage() {
  42. var lblTime = document.getElementById("lbl")
  43. var tm = Math.round((parseFloat(lblTime.innerHTML))*1000)
  44. if (n > nmax) n = 1
  45. document.getElementById("btnBegin").disabled = true
  46. document.getElementById("btnStop").disabled = false
  47. document.getElementById("btnFaster").disabled = (parseFloat(lblTime.innerHTML) <= 0)
  48. document.getElementById("btnSlower").disabled = false
  49. for(i = 1; i <= nmax; i++){
  50. document.getElementById("divPreload" + i).style.display = "none"
  51. }
  52. document.getElementById("divPreload").style.display = "block"
  53. document.getElementById("divPreload" + n).style.display = "block"
  54. document.getElementById("lblImage").innerHTML = "Graph " + n + " of " + nmax
  55. t = setTimeout("displayImage()", tm) //change every tm seconds
  56. n++
  57. }
  58.  
  59. function stopImage() {
  60. clearTimeout(t)
  61. document.getElementById("btnBegin").disabled = false
  62. document.getElementById("btnStop").disabled = true
  63. document.getElementById("btnFaster").disabled = true
  64. document.getElementById("btnSlower").disabled = true
  65. n--
  66. }
  67.  
  68. function fasterImage(step) {
  69. var lblTime = document.getElementById("lbl")
  70. var pct = document.getElementById("percent")
  71. lblTime.innerHTML = Math.round((parseFloat(lblTime.innerHTML) + step)*1000)/1000
  72. var tmp = parseFloat(lblTime.innerHTML)
  73. document.getElementById("btnFaster").disabled = (tmp <= 0)
  74. if (tmp >=0 && tmp <= 10) {
  75. pct.style.width = 100 - Math.round((parseFloat(lblTime.innerHTML))*10) + "%"
  76. pct.innerHTML = pct.style.width
  77. pct.style.display = "block"
  78. }
  79. else pct.style.display = "none"
  80. }
  81.  
  82. window.onload = function(){
  83. document.getElementById("btnBegin").disabled = false
  84. document.getElementById("btnBegin").focus()
  85. document.getElementById("loading").style.display = "none"
  86. }
  87.  
  88. </script>
  89. </head>
  90.  
  91. <body>
  92. <div align="center" id="divDemo">
  93. <div id="loading">Animation loading...</div>
  94. <div id="divPreload">
  95. <script language="JavaScript" type="text/javascript">
  96. for(i=1;i<=nmax;i++){
  97. document.write("<div id=\"divPreload" + i + "\"><img src=\"images/"
  98. + i + ".png\" /></div>")
  99. }
  100. </script>
  101. </div>
  102. </div>
  103. <div style="border: solid 1px #FF0000; margin-top: 20px; height: 20px;" title="Speed">
  104. <div id="percent" style="width: 80%">80%</div>
  105. </div>
  106. <div id="divControl">
  107. <input type="button" disabled="disabled" id="btnBegin"
  108. onClick="displayImage()" value="Begin"/>
  109. <input type="button" disabled="disabled" id="btnFaster"
  110. onClick="fasterImage(-0.1)" value="Faster"/>
  111. <input type="button" disabled="disabled" id="btnSlower"
  112. onClick="fasterImage(0.1)" value="Slower"/>
  113. <input type="button" disabled="disabled" id="btnStop"
  114. onClick="stopImage()" value="Stop "/>
  115. Time Interval: <label id="lbl">2</label> seconds; <label id="lblImage"></label>
  116. </div>
  117. </body>
  118.  
  119. </html>
A Simple Demonstration of Brownian Motion

Here is a simple demonstration of random walk on the 2D plane (Brownian motion):

loading animation frames...
80%
Time Interval: seconds;