{"id":2220,"date":"2009-07-02T15:59:47","date_gmt":"2009-07-02T20:59:47","guid":{"rendered":"http:\/\/bobbeaty.com\/wp\/?p=2220"},"modified":"2009-07-07T09:38:36","modified_gmt":"2009-07-07T14:38:36","slug":"fantastic-double-buffering-of-the-annotatedtimeline","status":"publish","type":"post","link":"https:\/\/bobbeaty.com\/wp\/archives\/2220","title":{"rendered":"Fantastic Double-Buffering of the AnnotatedTimeLine"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bobbeaty.com\/wp\/wp-content\/uploads\/2009\/03\/googlevisualization.jpg\" alt=\"GoogleVisualization.jpg\" border=\"0\" width=\"140\" height=\"103\" align=\"right\" \/><\/p>\n<p>I've been working within the limitations of the <a href=\"http:\/\/code.google.com\/apis\/visualization\/documentation\/gallery\/annotatedtimeline.html\">AnnotatedTimeLine<\/a> graph from the <a href=\"http:\/\/code.google.com\/apis\/visualization\/\">Google Visualization API<\/a> set and have just been telling my users that the unfortunate \"flash\" to white of the graph while it's updating data is an unfortunate reality of the <a href=\"http:\/\/code.google.com\/apis\/visualization\/documentation\/gallery\/annotatedtimeline.html\">AnnotatedTimeLine<\/a>, and that Google knows this is in issue and they are working on it.<\/p>\n<p>Then I read an interesting post to the mailing list about how Google Finance didn't have this issue, and it got me thinking... <em>How could they get around the flash?<\/em> And in the show this morning, it hit me: Double-Buffering.<\/p>\n<p>Simply have <strong>two<\/strong> graphs - one aligned in the z-axis behind the other. In fact, make them have the same coordinates, but just vary the <tt>zIndex<\/tt> value to \"flip\" them one in front of the other. Then, always draw to the rear (invisible) graph and when it's done, flip it to the front by setting <tt>sIndex<\/tt> to 49 on it, and setting <tt>zIndex<\/tt> to 0 on the one that was in front.<\/p>\n<p>A simple use of an array of two graphs accomplishes this quite easily. I add in two variables - the index values for \"foreground\" and \"background\", and then you always draw to <tt>chart[bg]<\/tt> and so on. It's very clean and slick. The change of the z-axis values is done in the blink of an eye, it's very hard to see. Compared to the 3 to 6 seconds that the redraw used to take, it's nothing short of <strong>amazing<\/strong>.<\/p>\n<p>In a very simplistic form:<\/p>\n<pre class=\"javascript\" style=\"font-family:monospace;\">  <span style=\"color: #000066; font-weight: bold;\">var<\/span> chart <span style=\"color: #339933;\">=<\/span> <span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #009900;\">&#93;<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #000066; font-weight: bold;\">var<\/span> fg <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">0<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #000066; font-weight: bold;\">var<\/span> bg <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">1<\/span><span style=\"color: #339933;\">;<\/span><\/pre>\n<p>and then in my initialization code, called from the Goolge <tt>setOnLoadCallback()<\/tt> method, I have:<\/p>\n<pre class=\"javascript\" style=\"font-family:monospace;\">  chart<span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #CC0000;\">0<\/span><span style=\"color: #009900;\">&#93;<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000066; font-weight: bold;\">new<\/span> google.<span style=\"color: #660066;\">visualization<\/span>.<span style=\"color: #660066;\">AnnotatedTimeLine<\/span><span style=\"color: #009900;\">&#40;<\/span>chartDiv<span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #CC0000;\">0<\/span><span style=\"color: #009900;\">&#93;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  chart<span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #CC0000;\">1<\/span><span style=\"color: #009900;\">&#93;<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #000066; font-weight: bold;\">new<\/span> google.<span style=\"color: #660066;\">visualization<\/span>.<span style=\"color: #660066;\">AnnotatedTimeLine<\/span><span style=\"color: #009900;\">&#40;<\/span>chartDiv<span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #CC0000;\">1<\/span><span style=\"color: #009900;\">&#93;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  <span style=\"color: #006600; font-style: italic;\">\/\/ tie us into the events for these guys<\/span>\n  google.<span style=\"color: #660066;\">visualization<\/span>.<span style=\"color: #660066;\">events<\/span>.<span style=\"color: #660066;\">addListener<\/span><span style=\"color: #009900;\">&#40;<\/span>chart<span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #CC0000;\">0<\/span><span style=\"color: #009900;\">&#93;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #3366CC;\">'ready'<\/span><span style=\"color: #339933;\">,<\/span> graphReady<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n  google.<span style=\"color: #660066;\">visualization<\/span>.<span style=\"color: #660066;\">events<\/span>.<span style=\"color: #660066;\">addListener<\/span><span style=\"color: #009900;\">&#40;<\/span>chart<span style=\"color: #009900;\">&#91;<\/span><span style=\"color: #CC0000;\">1<\/span><span style=\"color: #009900;\">&#93;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #3366CC;\">'ready'<\/span><span style=\"color: #339933;\">,<\/span> graphReady<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/pre>\n<p>and then when I need to draw to the correct graph, I simply call:<\/p>\n<pre class=\"javascript\" style=\"font-family:monospace;\">  chart<span style=\"color: #009900;\">&#91;<\/span>bg<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">draw<\/span><span style=\"color: #009900;\">&#40;<\/span>graphData<span style=\"color: #339933;\">,<\/span> chartParams<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span><\/pre>\n<p>When the graph is done drawing, I'll get a call to:<\/p>\n<pre class=\"javascript\" style=\"font-family:monospace;\">  <span style=\"color: #000066; font-weight: bold;\">function<\/span> graphReady<span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/swap the graphs quickly<\/span>\n    chartDiv<span style=\"color: #009900;\">&#91;<\/span>fg<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">style<\/span>.<span style=\"color: #660066;\">zIndex<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #3366CC;\">'0'<\/span><span style=\"color: #339933;\">;<\/span>\n    chartDiv<span style=\"color: #009900;\">&#91;<\/span>bg<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">style<\/span>.<span style=\"color: #660066;\">zIndex<\/span> <span style=\"color: #339933;\">=<\/span> <span style=\"color: #3366CC;\">'49'<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/ now swap what we mean by back and front<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span>fg <span style=\"color: #339933;\">==<\/span> <span style=\"color: #CC0000;\">0<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      fg <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">1<\/span><span style=\"color: #339933;\">;<\/span>\n      bg <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">0<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span> <span style=\"color: #000066; font-weight: bold;\">else<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      fg <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">0<\/span><span style=\"color: #339933;\">;<\/span>\n      bg <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">1<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span><\/pre>\n<p>There's a lot of the details I've left out because they don't really matter. The point is that you have to place them on top of each other, and then do this double-buffering. It's pretty nice.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been working within the limitations of the AnnotatedTimeLine graph from the Google Visualization API set and have just been telling my users that the unfortunate &#8220;flash&#8221; to white of the graph while it&#8217;s updating data is an unfortunate reality of the AnnotatedTimeLine, and that Google knows this is in issue and they are working [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,6,5],"tags":[],"class_list":["post-2220","post","type-post","status-publish","format-standard","hentry","category-coding","category-cube-life","category-vendors"],"_links":{"self":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/2220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/comments?post=2220"}],"version-history":[{"count":1,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/2220\/revisions"}],"predecessor-version":[{"id":2221,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/2220\/revisions\/2221"}],"wp:attachment":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/media?parent=2220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/categories?post=2220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/tags?post=2220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}