Google Visualization API for Pachube history

Hello everyone

I have made a Pachube Application that uses Google's Vizualization API to generate graphs from an individual Pachube datastream history. It will be much more useful when Pachube starts storing history for longer than 24 hours, but I thought I would contribute this now since a lot of people have been talking about the Visualization API.

There are three ways you can use it:

  • The easy way Just use the Pachube app at http://apps.pachube.com/google_viz. It's all pretty self explanatory, you put in the feed and datastream you want, the size and color and out pops HTML you can embed in your website.
  • Slightly harder, but eventually quicker Just use the code below in your own webpage and change the variables as necessary:
    <script language="JavaScript" src="http://apps.pachube.com/google_viz/viz.js"></script>
    <script language="JavaScript">createViz(504,0,600,300,"FF0066");</script>
    // that's feed ID, datastream ID, width, height, html color
    
  • Most difficult but most configurable I've exposed the code that converts Pachube's history CSV into the JSON format that Google's API expects. So you can use this in your own visualization gadgets, just by including it as the datasource. It's pretty obvious also, just plug in feed ID and datastream ID: http://apps.pachube.com/google_viz/viz.php?f=1200&d=13

    Of course if you make some nice visualizations using the Google API post em back here for all of us!

This is my first try, so bug reports would be welcome here in the forum!

Re: Google Visualization API for Pachube history

very handy!

for info, here's a preview of what the code in "Slightly harder" above generates:

Re: Google Visualization API for Pachube history

Has anybody else noticed that if you make more than one call to the "Slightly harder" method only the first graph will appear?

Re: Google Visualization API for Pachube history

that's happening because the javascript is using a callback function for processing and displaying the data once its loaded - but the way the callback function works it doesn't "know" which graph object triggered it. if you have an example of a page with multiple google visualization API graphs on one page we could have a look at how they're doing it and see if it's translatable; alternatively, the quick workaround is to copy/paste the .js file contents and edit to create a different callback function for each graph you want to embed in the single page.

Re: Google Visualization API for Pachube history

I am having the same issue here, only one graph appears and that seems to vary between feeds for all the graphs.
I am not too great at HTML or Java. I have tried to follow your advise above, but I am struggling.
I have copied the viz.js to the local webserver and copied the function so I have two functions with different names, and amended my code in HTML to call each function, but I still only get one graph.
I have tested each function individually and it works.
If it helps my experimental page is http://www.bishcons.co.uk/meters.html java is at www.bishcons.co.uk/viz.js
Any help would be appreciated, otherwise I will need to create different pages with links :-(
Thanks in advance.

Re: Google Visualization API for Pachube history

Try changing the variables names of 'chart' to 'chartTwo', and 'data' to 'dataTwo' in the 'createGasRate' function.

Chris

Re: Google Visualization API for Pachube history

Sorry I should have made that clearer...

In your second function, you need to change the variable names for 'data' and 'chart' so that they are unique and change them every time they appear. From the code it also looks like you might need to change the every reference to 'google' (that isn't in a URL as well) in the same way.

Chris

Re: Google Visualization API for Pachube history

This solution doesn't actually fix it. I'm just playing around with the javascript, should have a fully working solution shortly.
Chris

Re: Google Visualization API for Pachube history

You need to make the following changes to second function (or copy mine below), assuming you leave the first one as it is.

All the changes you need are in bold below. Note: not all the changes are essential but are good practice.

1. Make sure the callback function is renamed. In this case I've changed 'process'to 'processTwo'. This is in two places.

2. Change the div ID so that the graph is drawn in a div with a different id. In this case I've renamed 'visualization' to 'visualizationTwo'. Be careful NOT to change 'visualization' when it appears in the google.load() function here:

google.load(\'visualization\',\'1\',{packages:[\'annotatedtimeline\']}); 

because this is a referring to something different. (In this case the type of Google API we are loading). This appears twice in the code

3. I also renamed some variables to make sure they data set and the chart being drawn are the ones we want. These are the references to 'data', 'chart', 'value', 'drawVisualization' and 'thisrow'. I added 'Two' to the end of all of these.

Contrary to my earlier post you definitely DON'T need to rename 'google'. This will break the code.

Chris

Quote:

function createGasRate(feed,datastream,width,height,color){
if (typeof(google) == 'undefined'){ document.write("<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>"); } document.write("<script type=\"text/javascript\"> google.load(\'visualization\',\'1\',{packages:[\'annotatedtimeline\']}); function drawVisualizationTwo(){var headID = document.getElementsByTagName('head')[0]; var newScript = document.createElement('script'); newScript.type = 'text/javascript'; newScript.src = 'http://apps.pachube.com/history/archive_json.php?f=",feed,"&d=",datastream,"&callback=processTwo'; headID.appendChild(newScript); } function processTwo(archive){ var d; var valTwo; var dataTwo = new google.visualization.DataTable(); dataTwo.addColumn('datetime', 'Date'); dataTwo.addColumn('number', 'Datastream value'); for ( var i in archive['time'] ) { var thisrowTwo = dataTwo.addRow(); var timestamp = archive['time'][i]; var ts_parts = timestamp.split('T'); var d_parts = ts_parts[0].split('-'); var t_parts = ts_parts[1].split(':'); d = new Date(parseInt(d_parts[0],10), parseInt(d_parts[1],10)-1 ,parseInt(d_parts[2],10), parseInt(t_parts[0],10), parseInt(t_parts[1],10), parseInt(t_parts[2],10) ); valTwo = parseFloat(archive['value'][i]); dataTwo.setValue(thisrowTwo, 0, d); dataTwo.setValue(thisrowTwo, 1, valTwo); } var chartTwo = new google.visualization.AnnotatedTimeLine(document.getElementById('visualizationTwo')); chartTwo.draw(dataTwo, {displayAnnotations:true,thickness:1,displayExactValues:true,fill:20,colors:['#",color,"']}); } google.setOnLoadCallback(drawVisualizationTwo);

Re: Google Visualization API for Pachube history

The forum formatting is cutting off the end of my code.

You need to add this right after what I have posted above (note: the first change to visualizationTwo if you're modifying your own code):

</script>
<div id=\"visualizationTwo\" style=\"width:",width,"px; height:",height,"px; font-size:small;\"></div>
<div style=\"width:",width,"px; background-color:#fff; margin:3px; padding-top:6px;\">
<a href=\"http://www.pachube.com/feeds/",feed,"\" target=\"_new\">
<img src=\"http://apps.pachube.com/google_viz/powered_by_pachube.png\" alt=\"powered by pachube!\" border=\"0\" style=\"\">
</a></div>")
;}

Re: Google Visualization API for Pachube history

Chris,

I now have two feeds on one page. I'll now have a play and try to get a few more ;-)

Thank you so much for your time.

Kevin.

Re: Google Visualization API for Pachube history

All working well.

Many, many thanks.

Kevin.

Re: Google Visualization API for Pachube history

Many thanks to Chris and Kevin for posting the solution to multiple GoogleViz charts on one page. I'm quite happy with the posted solution and have a few lingering comments.

1) On my charts, there is a six hour difference between the timestamp and the actual time of that data. That is, the chart shows, say, a spike at 1am when I'm cooking away at 7pm. Can I fix this with any adjusted parameters being passed to the GoogleViz script?

2) There is some utility to seeing the two datastreams from the CurrentCost meter (one for each 120Vac lead) but even more in a combined one. I haven't seen any way to add multiple data streams together in Pachube. It's not important to me where in the process they are added (an intermediate feed at Pachube or when the data is on its way to the visualization object) just as long as the final vis shows the combined time series. Any ideas or solutions?

3) I haven't had much success with being able to change the color of the GoogleViz object, even when I pass a color parameter. Is something off?
Snippet: <script language="JavaScript">create1(2119,1,1200,400,"CC3456");</script>

4) Lastly, I expect the temperature range to stay between, say, 50F and 80F. Is there any mechanism to just show that portion of the y-axis range in GoogleViz?

Thanks for your thoughts!
Puneet

Re: Google Visualization API for Pachube history

Sorry about the long delay in replying to this:

1. There is currently no way to do this with the google viz script as offered -- but it wouldn't be too difficult to modify the .js on your own to be able to do this.

2. again, this should be possible, and not terribly difficult, if you don't mind getting into the .js yourself!

3. seems to work fine for me, checking Mac Firefox, Safari, Camino. What browser/platform combo are you using, and what colour is the graph in this link: http://apps.pachube.com/google_viz/preview.php?f=504&d=2&w=600&h=400&g=47FF19

4. Unfortunately this is a limitation of Google's .js -- they determine the max and min from the data you send, so I can't think of any easy way to do this. Though again, if you are tweaking our .js, you might consider checking the data first to make sure it doesn't exceed your expected max & min.

Re: Google Visualization API for Pachube history

Thanks for the motivation to solve some of the issues I brought up. I present three solutions and two ideas for future implementations.

1) It seems that all Pachube-saved data is in GST +0 format. Since I'm six hours West from GMT in Colorado, I needed to subtract 6 from parseInt(t_parts[0],10)

d = new Date(parseInt(d_parts[0],10), parseInt(d_parts[1],10)-1, parseInt(d_parts[2],10),
parseInt(t_parts[0],10)-6, parseInt(t_parts[1],10), parseInt(t_parts[2],10) );

2) I've stumbled around trying to get what I want in the .js. Nothing doing. True, I have not been successful in being able to modify the .js but I believe it makes more sense to have a combined data stream for

  1. time/data syncronization
  2. this application to view the summed data, and
  3. other examples such as AMEE's Carbon footprint calculator.

Is there any hope for a Pachube app to add n streams together as a new output feed?

3) I didn't use the color variable correctly. I found and used http://www.december.com/html/spec/colorhex.html to get the colors I wanted. Everything works as advertised!

4) Google provides the tools necessary to adjust the Viz chart. I added scaleType:'maximize', min:55, max:75, to the chart options. This sets a floor of 55F and a ceiling of 75F. If your data exceeds either of these two values, it go "off-chart". Incidentally, I found my CurrentCost CC128 meter to be 2.5F to 3.0F lower than other thermostats placed next to it.

chartTwo.draw(dataTwo, {displayAnnotations:true,thickness:1,
scaleType:'maximize', min:55, max:75, displayExactValues:true,fill:00,colors:['#",color,"']});

5) I thought of another idea when I read that we can add a second y-axis scale to the chart in Google Viz docs. Ideally, one series would be newly-combined electricity feeds and the second would be temperature. This will help correlate events such as furnace cycling vs. in-house temperature.

Onward!
Puneet

Re: Google Visualization API for Pachube history

OK, so i finally got round to making these changes. i haven't updated the "configurator" (i.e. the so-called 'easy way') since i figure people taking the easy route probably don't want these more complex features.

instead you use the "slightly" harder way (which isn't really hard at all).

for specifying min and max for the graph's Y-axis, just add them on to the end of the variables in the 'createViz' function call, i.e.

<script language="JavaScript" src="http://apps.pachube.com/google_viz/viz.js"></script>
<script language="JavaScript">createViz(504,0,600,300,"FF0066", 100, 800);</script>
// that's feed ID, datastream ID, width, height, html color, graph minimum, graph maximum

in order to specify several feeds and/or datastreams to be rendered in any single graph, my idea is that you just send an array of those values, where you can specify an array of feeds, an array of datastreams and an array of colours to render them as, for example:

createViz([504,504,504],[0,1,2],800,400,["ff0000","0000ff","00ff00"]);

This isn't implemented yet in the main script!. Instead, i'd like you all to check this link first, and make sure it renders nicely for you in various modern browsers without any problems: http://apps.pachube.com/google_viz/preview_multi.php

if we're all happy with it, i'll move over the 'multi' code to the main script.

let me know your thoughts.

Re: Google Visualization API for Pachube history

The multi-datastream feed works fine for me on Firefox, but has issues running on IE. The graph does get shown, but only after a couple of JS errors are thrown. BTW this is failing on IE 8 on both Vista and Windows 7. I'll try and find some time later today to work out where the error is, but initially it looks like it's a timing problem in the IE javascript runtime - it is expecting the returned data to be ready when it isn't.

Re: Google Visualization API for Pachube history

I've found the problem with the multi datastream javascript. You are making a call to the following Google viz functions everytime you call process(archive):

var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('visualization'));
chart.draw(data, {displayAnnotations:true,thickness:1,displayExactValues:true,fill:10,colors:['#ff0000','#0000ff','#00ff00']});

the problem being that when the call to chart.draw is made, the datatable hasn't been setup (which is done inside else block) , resulting in an error being thrown inside the google viz code stating that the datatable doesn't exist. By moving the above two lines *inside* the 'else ' block (at the end of the block), then the call to draw the viz will only be made once all data has been received (complete == graphs) and the datatables have been created.

One other small issue - I see that you have alo included my fix to check that the type of the timestamp object is not a function, however the timestamp object hasn't been instantiated by the time of the check. ie you have the following:

if (typeof(timestamp) != "function")
{
    var thisrow = data.addRow();
    var timestamp = archive['time'][i];
    ....

and should be like this:

var timestamp = archive['time'][i];
if (typeof(timestamp) != "function")
{
    var thisrow = data.addRow();
    ...

PS: The chart.draw shown above is my version used for debugging - you'll need to use your original version which inserts the maxmin and m_color values accordingly.

Re: Google Visualization API for Pachube history

Thanks again - fixed here too. Any errors for you?

Re: Google Visualization API for Pachube history

That's fine now, all working okay in both IE and Firefox with no javascript errors.

Glad to be of help!

Re: Google Visualization API for Pachube history

Excellent!
By the way, since you clearly know your javascript, do let us know if you come up with any other api/mashup/visualization apps and we'll get them integrated in the Pachube apps site.
Thanks again.

Re: Google Visualization API for Pachube history

I really like the multi-graph version! Maybe it could slightly be improved by making the datastream descriptions configurable. So instead of "datastream value", something more descriptive could be put into the chart. It would require an additional parameter. What do you think?

Re: Google Visualization API for Pachube history

Hi All,

I've taken a copy of viz_multi.js and hacked it (severely) for my own use. I'm just putting my copy up just in case anyone finds use for it. I've added the following features on my copy based on the suggestions/solutions discussed on this thread.

1. the additional labels parameter
2. timezone offset
3. concatenating of multiple datastreams together
4. I've also wrapped the whole thing into its own class and added a few bodge so it can be ran multiple time on the same page.

To add datastreams together, all you have to do is to define the feed/datastream as an array for eg. (ugly but I was going for easy...)

createViz("myviz",[[3168,3168],3164],[[2,1],2],["B (Watts)", "A (Watts)"],800,200,["669933","3333CC"],11);

This will display 2 streams on the graph i.e. adding feed 3168's datastream 2 and 1 together as one and feed 3164 datastream 2.
The script is here http://mon.io2.org/viz_multi.js and more example of its use is here (my page) http://mon.io2.org - I think the other params are self explanatory.

Re: Google Visualization API for Pachube history

Thanks for this, I'm sure it will be very useful to a lot of people who have been asking for it -- any interest in turning it into a Pachube.app? Similar to the configurator found here: http://apps.pachube.com/google_viz/ it would probably just involve a little html/js tweaking and a tweak to the preview php file.

Basically we would provide you with ftp account and all those original files for you to edit as necessary which could then be called something like Pachube Viz Pro, or something similar. If you're interested, please send an email to support at pachube dot com and we'll set you up! Thanks again.