{"id":742,"date":"2009-01-18T01:27:00","date_gmt":"2009-01-18T00:27:00","guid":{"rendered":"https:\/\/www.tomfotherby.com\/blog\/?p=742"},"modified":"2009-01-18T18:58:07","modified_gmt":"2009-01-18T17:58:07","slug":"how-to-plot-dates-in-google-charts-api","status":"publish","type":"post","link":"https:\/\/www.tomfotherby.com\/blog\/index.php\/2009\/01\/how-to-plot-dates-in-google-charts-api\/","title":{"rendered":"How to plot dates in Google Charts API"},"content":{"rendered":"<p>The <a href=\"http:\/\/code.google.com\/apis\/chart\/\">Google Charts API<\/a> is great but it can&#8217;t handle date-based data. Lets say you want to plot some values over a timespan, how do you do it? One way is to sample the data at regular time intervals and plot it as normal. But if the timestamps you want to plot are not regular, the trick is to convert each date into a day offset and plot the offset whilst still labelling the axis with the date text.<\/p>\n<p>This is an example of plotting date-based data on the X-axis:<br \/>\n<center><img decoding=\"async\" src=\"http:\/\/chart.apis.google.com\/chart?&#038;cht=lxy&#038;chs=400x150&#038;chg=0,10&#038;chds=0,517,12,72&#038;chxt=x,y,x,y&#038;chxl=0:|20\/Jan\/08|20\/Feb\/08|20\/Jan\/09|20\/Mar\/09|20\/Jun\/09|1:|12|42|72|2:||Time%20scale||3:||Data|&#038;chm=D,FF0000,0,-1,1|o,000000,0,-1,4&#038;chd=t:0,31,366,425,517|12,22,52,32,72\" \/><\/center><\/p>\n<p>In, PHP you set the first date as 0 and then work out the day difference for each subsequent date. At the same time you need to store the text label for that date.<\/p>\n<pre>\r\n<code>\r\n<html><body>\r\n<?\r\n   $dataSet[\"20 January 2008\"]  = 12;\r\n   $dataSet[\"20 February 2008\"] = 22;\r\n   $dataSet[\"20 January 2009\"]  = 52;\r\n   $dataSet[\"20 March 2009\"]    = 32;\r\n   $dataSet[\"20 June 2009\"]     = 72;\r\n\r\n   $firstDate = \"\";\r\n   $googleChartDataY = \"\";\r\n   $googleChartDataX = \"\";\r\n   $maxDay = 0;\r\n\r\n   foreach($dataSet as $date => $data):\r\n           if ($firstDate == \"\")\r\n              $firstDate = strtotime($date);\r\n\r\n           $dayDiff = round((strtotime($date)-$firstDate) \/ (60 * 60 * 24));\r\n\r\n           if ($dayDiff > $maxDay)\r\n              $maxDay = $dayDiff;\r\n\r\n           $googleChartDataX .= $dayDiff . \",\";\r\n           $googleChartDataY .= $data. \",\";\r\n           $googleChartLabsX .= \"|\". date(\"d\/M\/y\",strtotime($date));\r\n   endforeach;\r\n\r\n   $axisScale    = \"&chds=0,$maxDay,\".min($dataSet).\",\".max($dataSet);\r\n   $axisLabels   = \"&chxt=x,y,x,y&chxl=0:{$googleChartLabsX}|1:|\".min($dataSet).\"|\".((min($dataSet)+max($dataSet))\/2).\"|\".max($dataSet).\"|2:||Time scale||3:||Data values|\";\r\n   \/\/ Display a red line with a black dot at each point\r\n   $dataLabels   = \"&chm=D,FF0000,0,-1,1|o,000000,0,-1,4\";\r\n   $dataPoints   = \"&chd=t:\".substr($googleChartDataX,0,-1).\"|\".substr($googleChartDataY,0,-1);\r\n\r\n   echo \"<img src=\\\"http:\/\/chart.apis.google.com\/chart?&#038;cht=lxy&#038;chs=400x150&#038;chg=0,10{$axisScale}{$axisLabels}{$dataLabels}{$dataPoints}\\\" \/>\";\r\n?>\r\n<\/body><\/html>\r\n<\/code>\r\n<\/pre>\n<p>I created a <a href=\"http:\/\/wordpress.org\/extend\/plugins\/fotherplot\/\">small WordPress plugin<\/a> that uses the above code to graph custom field data over time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Google Charts API is great but it can&#8217;t handle date-based data. Lets say you want to plot some values over a timespan, how do you do it? One way is to sample the data at regular time intervals and plot it as normal. But if the timestamps you want to plot are not regular, [&hellip;]<\/p>\n","protected":false},"author":52,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-742","post","type-post","status-publish","format-standard","hentry","category-techjournal"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/742","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/52"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=742"}],"version-history":[{"count":17,"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/742\/revisions"}],"predecessor-version":[{"id":762,"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/742\/revisions\/762"}],"wp:attachment":[{"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=742"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=742"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tomfotherby.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=742"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}