{"id":2956,"date":"2009-12-10T15:47:56","date_gmt":"2009-12-10T21:47:56","guid":{"rendered":"http:\/\/bobbeaty.com\/wp\/?p=2956"},"modified":"2009-12-14T09:09:08","modified_gmt":"2009-12-14T15:09:08","slug":"optimizing-google-annotatedtimeline-updating","status":"publish","type":"post","link":"https:\/\/bobbeaty.com\/wp\/archives\/2956","title":{"rendered":"Optimizing Google AnnotatedTimeLine Updating"},"content":{"rendered":"<p>When I added a bunch of additional values to my web app, I noticed that the updating of the Google <a href=\"http:\/\/code.google.com\/apis\/visualization\/documentation\/gallery\/annotatedtimeline.html\">AnnotatedTimeLine<\/a> was taking a <strong>lot<\/strong> longer than before. I mean it was pausing for a good 3 sec. before updating the view. I looked at the CPU usage, and it was all in the Flex component. It was bad. Very bad. So I knew I had to do something about it.<\/p>\n<p>In the original version of the page, I had code that was run when the data was received and the graph redrawn. This was a standard hook for the AnnotatedTimeLine:<\/p>\n<pre class=\"javascript\" style=\"font-family:monospace;\">  <span style=\"color: #006600; font-style: italic;\">\/**\n   * This function is called when the ATL is done updating the graph\n   * from the data and the &quot;draw()&quot; method.\n   *\/<\/span>\n  <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;\">\/\/ hide all the unchecked data sets<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000066; font-weight: bold;\">var<\/span> i <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">0<\/span><span style=\"color: #339933;\">;<\/span> i <span style=\"color: #339933;\">&lt;<\/span> portfolioChecks.<span style=\"color: #660066;\">length<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #339933;\">++<\/span>i<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #000066; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #339933;\">!<\/span>portfolioChecks<span style=\"color: #009900;\">&#91;<\/span>i<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">checked<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n        updateBackgroundVisibility<span style=\"color: #009900;\">&#40;<\/span>portfolioNames<span style=\"color: #009900;\">&#91;<\/span>i<span style=\"color: #009900;\">&#93;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #003366; font-weight: bold;\">false<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n      <span style=\"color: #009900;\">&#125;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/ ...finish up with more processing<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span>\n&nbsp;\n  <span style=\"color: #006600; font-style: italic;\">\/**\n   * This is called to update the visibility of the named portfolio\n   * to the provided state in the background graph.\n   *\/<\/span>\n  <span style=\"color: #000066; font-weight: bold;\">function<\/span> updateBackgroundVisibility<span style=\"color: #009900;\">&#40;<\/span>name<span style=\"color: #339933;\">,<\/span> state<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> colCnt <span style=\"color: #339933;\">=<\/span> graphData.<span style=\"color: #660066;\">getNumberOfColumns<\/span><span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/ I have to find the column name in the table<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">for<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000066; font-weight: bold;\">var<\/span> i <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">1<\/span><span style=\"color: #339933;\">;<\/span> i <span style=\"color: #339933;\">&lt;<\/span> colCnt<span style=\"color: #339933;\">;<\/span> <span style=\"color: #339933;\">++<\/span>i<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #000066; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span>graphData.<span style=\"color: #660066;\">getColumnLabel<\/span><span style=\"color: #009900;\">&#40;<\/span>i<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #339933;\">==<\/span> name<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n        <span style=\"color: #006600; font-style: italic;\">\/\/ the dataset number is one less than the column number<\/span>\n        <span style=\"color: #000066; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span>state<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n          chart<span style=\"color: #009900;\">&#91;<\/span>bg<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">showDataColumns<\/span><span style=\"color: #009900;\">&#40;<\/span>i<span style=\"color: #339933;\">-<\/span><span style=\"color: #CC0000;\">1<\/span><span style=\"color: #009900;\">&#41;<\/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          chart<span style=\"color: #009900;\">&#91;<\/span>bg<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">hideDataColumns<\/span><span style=\"color: #009900;\">&#40;<\/span>i<span style=\"color: #339933;\">-<\/span><span style=\"color: #CC0000;\">1<\/span><span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n        <span style=\"color: #009900;\">&#125;<\/span>\n      <span style=\"color: #009900;\">&#125;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span><\/pre>\n<p>When I originally built the code, I wanted to have something that allowed me to change the visibility of the data sets in the graph(s) either way, and that's really nice. But what I didn't expect was the performance penalty I would pay for such a design.<\/p>\n<p>As it turns out, there's a form of the <tt>hideDataColumns()<\/tt> <a href=\"http:\/\/code.google.com\/apis\/visualization\/documentation\/gallery\/annotatedtimeline.html#Methods\">method<\/a> on the ATL that allows the user to send an array of dataset indexes. I didn't know what to expect, but I thought it <strong>had<\/strong> to be better than this, so I recoded this as:<\/p>\n<pre class=\"javascript\" style=\"font-family:monospace;\">  <span style=\"color: #006600; font-style: italic;\">\/**\n   * This function is called when the ATL is done updating the graph\n   * from the data and the &quot;draw()&quot; method.\n   *\/<\/span>\n  <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;\">\/\/ hide all the unchecked data sets<\/span>\n    <span style=\"color: #000066; font-weight: bold;\">var<\/span> cols <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;\">for<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #000066; font-weight: bold;\">var<\/span> i <span style=\"color: #339933;\">=<\/span> <span style=\"color: #CC0000;\">0<\/span><span style=\"color: #339933;\">;<\/span> i <span style=\"color: #339933;\">&lt;<\/span> portfolioChecks.<span style=\"color: #660066;\">length<\/span><span style=\"color: #339933;\">;<\/span> <span style=\"color: #339933;\">++<\/span>i<span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n      <span style=\"color: #000066; font-weight: bold;\">if<\/span> <span style=\"color: #009900;\">&#40;<\/span><span style=\"color: #339933;\">!<\/span>portfolioChecks<span style=\"color: #009900;\">&#91;<\/span>i<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">checked<\/span><span style=\"color: #009900;\">&#41;<\/span> <span style=\"color: #009900;\">&#123;<\/span>\n        cols.<span style=\"color: #660066;\">push<\/span><span style=\"color: #009900;\">&#40;<\/span>i<span style=\"color: #339933;\">-<\/span>i<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n      <span style=\"color: #009900;\">&#125;<\/span>\n    <span style=\"color: #009900;\">&#125;<\/span>\n    chart<span style=\"color: #009900;\">&#91;<\/span>bg<span style=\"color: #009900;\">&#93;<\/span>.<span style=\"color: #660066;\">hideDataColumns<\/span><span style=\"color: #009900;\">&#40;<\/span>cols<span style=\"color: #009900;\">&#41;<\/span><span style=\"color: #339933;\">;<\/span>\n    <span style=\"color: #006600; font-style: italic;\">\/\/ ...finish up with more processing<\/span>\n  <span style=\"color: #009900;\">&#125;<\/span><\/pre>\n<p>Without the call to <tt> updateBackgroundVisibility()<\/tt>, I knew it'd be a little faster - no need to look up all the column headers, etc. But I didn't expect to see what I saw.<\/p>\n<p>The resulting code took the refresh time from 2-3 sec. to under the blink of an eye. Really. It was a slight <em>flicker<\/em>, but that's about it. Amazing. In retrospect, it makes sense... I was individually hiding about 30 columns each update. That's a lot. To do it right, there had to be some type of lock, update, refresh\/redraw, and then unlock. All that added up. Big time.<\/p>\n<p>It's taught me a big lesson about the efficiency of Google's code: if in doubt, look for a better way, there's probably one there, or you can always ask the visualization team. I know I've learned my lesson.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I added a bunch of additional values to my web app, I noticed that the updating of the Google AnnotatedTimeLine was taking a lot longer than before. I mean it was pausing for a good 3 sec. before updating the view. I looked at the CPU usage, and it was all in the Flex [&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],"tags":[],"class_list":["post-2956","post","type-post","status-publish","format-standard","hentry","category-coding","category-cube-life"],"_links":{"self":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/2956","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=2956"}],"version-history":[{"count":1,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/2956\/revisions"}],"predecessor-version":[{"id":2957,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/posts\/2956\/revisions\/2957"}],"wp:attachment":[{"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/media?parent=2956"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/categories?post=2956"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bobbeaty.com\/wp\/wp-json\/wp\/v2\/tags?post=2956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}