1

I’m trying to use data from multiple GoogleSheets to produce a single HighChart graph. I’d like to do this without moving all the data into one area of a single spreadsheet, particularly as I want to use the drilldown option which would make it difficult to collect all the data together. I thought I could pass the columns as an array and then reference the array in the data property of my chart, but I’m struggling to do that with even one column from one sheet.

I have searched for answers online, but I have not found anything relating to highcharts getting data from multiple sources. Previous Research: Using GoogleSheets Data as an array before creating the chart: (Removed Link) - The problem is that I could only use one GoogleSheets reference here as the chart object sits inside the data object.

API documentation - (Removed Link) – tells me I can access the columns but that’s not the part I’m having problems with

Querying the Chart: (Removed Link) - I have actually considered making hidden charts, then interrogating the data and making new charts from those, but that seems like a very long way round and I’m still not sure I could grab all the data I need.

Using two GoogleSheets for separate charts on the same page: (Removed Link) I have done this.

Please could you help me to understand how I can access the properties and methods of this object outside of the object itself?

Thank you.

My Code:

        //Function to produce a data array ***Not Working - Cannot extract array from object method***
    function getData(){

    Highcharts.data({
        googleSpreadsheetKey: '12x66_QEkTKg_UzvpHEygdTmfnu7oH81pSQYn78Hxt80',
        googleSpreadsheetWorksheet: 4,
        startColumn: 16,
        endColumn: 22,
        startRow: 63,
        endRow: 76,

        parsed: function (columns) {
            var dataTest2 = [];
            var columnLength = columns[1].length;
            for (i = 0; i < columnLength; i = i + 1) { 
                dataTest2.push(columns[1][i]);

            }

            alert(dataTest2); //This works here, but not if I move it outside of the method, even if I return it.
            var testReturn = this.googleSpreadsheetKey; //trying to return any property using "this" - I've also tried this.googleSpreadsheetKey.value but still undefined
            return testReturn; //returns "Undefined" 
        }

    });


    }
Faye
  • 53
  • 5
  • I don't know much about using google sheets, but from a highcharts data perspective, I would process the data entirely separate from the chart, before building the chart. Build an object that has everything you need, organized in a way that you can simply fetch the appropriate node of the object when you build the chart, when you drill down, etc – jlbriggs May 12 '15 at 12:15
  • Ok, so I would have to look into the GoogleSheets API instead of the HighCharts API (since googleSpreadsheetKey and googleSpreadsheetWorksheet are from HighCharts). I'll have a look and see what's possible. Thank you. – Faye May 12 '15 at 12:19
  • Looks like I can't do much with my puny JS skills directly with GoogleSheets :( It wants me to learn .NET or Java. – Faye May 12 '15 at 12:23
  • This thread may be of help: http://stackoverflow.com/questions/4143901/access-google-spreadsheet-or-google-data-api-only-with-javascript – jlbriggs May 12 '15 at 13:04
  • Fantastic! Thank you. I might also look at rethinking the way I'm approaching the problem. Maybe the reason there is very little documentation on this is that there are other ways around the problem. First I'll try creating an object that I can interrogate (using the JS library you have kindly provided - thank you!) - and if that doesn't work I'm going to try to align my data in GoogleSheets and splice the data I need for each chart - and if that doesn't work I'll try the create hidden charts option. – Faye May 12 '15 at 13:17
  • Update: Called my object data1 ("var data1 =") and successfully accessed other data with return data1.options.googleSpreadsheetWorksheet; which can then be used as variables throughout.... However, I still can't call the parsed function successfully. "return data1.options.parsed" returns the actual function, but return "data1.options.parsed()" does not return the result. I've tried moving it to the end of my code with just an alert to see if it was because the sheet wasn't parsed at the time the code was being run, but still no joy. – Faye May 12 '15 at 15:08
  • I've also tried data1.options.parsed(columns) – Faye May 12 '15 at 15:09
  • I think that you are trying to use data.js module while it won't suit you (or maybe I missed the idea). I would just load data on my own from spreadsheet, then preprocess all values/options and then create chart. AJAX is async so probably that's why you have problems. Check [#262](https://github.com/highslide-software/highcharts.com/blob/master/js/modules/data.src.js#L262) line - there is loaded spreadsheet. You can copy&paste then edit that method with new name. Example of use above method without Highcharts core: http://jsfiddle.net/rAsRP/150/ – Paweł Fus May 12 '15 at 16:38
  • I'll be honest - that went way over my head :-S It doesn't seem to work for me. I have this customOption firing out results - just the parsed that won't play ball: function getData(){ var data1 = Highcharts.data({ customOption: function (test){ var secondTest = ' loves Harry'; var thirdTest = test+secondTest; return thirdTest; }, }); return data1.options.customOption('Jane'); } – Faye May 12 '15 at 18:10
  • I think you missed one point: when your return something in `customOption` - that's fine, but you are invoking method `Highcharts.data()` with options. `Highcharts.data()` doesn't return anything, so returning in `customOption` doesn't work :) These two are totally different functions. I hope that's clears a bit :) – Paweł Fus May 13 '15 at 09:55

1 Answers1

0

You could use Google Sheets webQuery. Basically, this is a method to export the Spreadsheet's data into a given format such as csv, json, etc. In your case, the link should look like this:

Please note that here "tg?key" is the key of your Google Sheet, and "&gid=" is NOT 4, this only tells Highcharts to selected Sheet 4, but for Google Sheets look at the source link and copy the numbers which go after "&gid=". Furthermore, "&tq=" is used to select the columns of the Google Sheet, which in the link above selects "Column A" and "Column B". To find out more on how to select columns and query the output refer to:

Lastly, "&tqx=" is used to output your data in the format you want. The above link uses "out:csv" which will output the data as comma-separated values. This could as well be Json if you like. Have a look at this documentation:

In order to implement this output into your javascript code which you would then use to built your chart, you could use external Javascript libraries to handle these outputs. If you output your data as CSV, you can use "papaparse.js" to parse the CSV into Json which you can be then read by highcharts and allows you to built the chart. Refer to this documentation:

An alternative to this would be, to output your Google Sheets directly as Json, then use jquery to make an Ajax Call and load the JSON-encoded data into your Javascript code. Precisely, you could perhaps use jQuery.getJSON() to get the data. Look at this link for more details on how to get Json:

Finally, it is up to you on which format you choose to output the data, I prefer using Json as it saves you the extra step of having to convert the CSV into Json. Whatever suits you best and is easier for you to understand.

Once you have your data, you may have to parse your Json objects with Json.parse(), and then organize your data into an array with .push(). As @jlbriggs stated, organize your data first before you built the chart. Afterwards, you can make two, three or more Ajax calls to import data from different sources. I would not use many as this will impact in your loading and slow down data transfer.

NB: It is important to format the data accordingly for Highcharts to recognize the data, so use parseFloat() to convert strings into numbers, Date.UTC() to convert strings into date, etc.

Hope this helps you.

Ava Barbilla
  • 968
  • 2
  • 18
  • 37
  • Wow! Thank you - that is a really detailed and concise response. The overwhelming opinion seems to be that I should not be using data.js and instead extract the data from GoogleSheets independently from HighCharts, so I'm going to look at the options suggested and find the method that best suits my limited skill set. Thank you so much. I'll update once I've worked through these. – Faye May 13 '15 at 08:13
  • I'm always glad to help. I used to have a similar problem, so if you keep having trouble you could eventually provide your google sheets urls so that I can have a closer look. – Ava Barbilla May 13 '15 at 14:58
  • I have a simple JSON output here: https://docs.google.com/spreadsheets/d/12x66_QEkTKg_UzvpHEygdTmfnu7oH81pSQYn78Hxt80/gviz/tq?gid=1912490010&tq=select+A,+B,+C,+D,+E,+F,+G,+H&tqx=reqId:1 but I'm not sure how to query it. But I think that might be a whole new question! Just wanted you to know that I'm still working on this. – Faye May 14 '15 at 11:04
  • This bit "google.visualization.Query.setResponse()" is causing me some pain, Ava :-( I have the JSON but this is wrapped around it and I've spent all day trying to figure out how to get rid of it. – Faye May 14 '15 at 13:51
  • OK, I see what your problem is. You get a parsing error on line 1, given to "_google.visualization.Query.setResponse()_" as javascript is expecting either a 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', but gets 'undefined'. What is causing the problem in your case is the "_responseHandler_" since you did not define it in the link. If you look at the link I provided, you can see that at the end I inserted "_%20responseHandler:webQuery_" which will display the Json error free and makes it able to be queried afterwards. – Ava Barbilla May 14 '15 at 15:36
  • Your link should look like this: https://docs.google.com/spreadsheets/d/12x66_QEkTKg_UzvpHEygdTmfnu7oH81pSQYn78Hxt80/gviz/tq?gid=1912490010&tq=select+A,+B,+C,+D,+E,+F,+G,+H&tqx=reqId:1;out:json;%20responseHandler:webQuery . Try it now and let me know if it works for you. – Ava Barbilla May 14 '15 at 15:37
  • BTW - Given that your question states that you want to use various sources, what are the other urls? If you provide some more details I may eventually be able to prepare a fiddle for you. – Ava Barbilla May 14 '15 at 16:00
  • Thank you so much! I'll try it now. It's not actually other URLs at the moment but other parts of the googlesheet. Though I will want to use another googlesheets workbook very soon. At the moment I can't use the drilldown option in HighCharts at all because the googlesheets data just enters as a great blob and is sorted out into neat rows and columns... which is great unless you want to manipulate the series.data – Faye May 14 '15 at 16:51
  • No joy :( Now I get "Uncaught ReferenceError: webQuery is not defined" instead of "Uncaught ReferenceError: google is not defined" – Faye May 14 '15 at 16:56
  • I'm just trying to log it to the console at the moment. It works with other URLS. This person seems to have a URL that only returns the object and nothing else, but when I try it with mine it doesn't work: https://spreadsheets.google.com/feeds/list/0AtMEoZDi5-pedElCS1lrVnp0Yk1vbFdPaUlOc3F3a2c/od6/public/values?alt=json – Faye May 14 '15 at 17:04
  • Try the Google Sheet API. This will allow you to export the Spreadsheet as Json using JSONP through a Callback function. These errors may have to do with cross-domain-scripting and hence restricts access to the sheet given that it belongs to another domain. As in the last link you provided, it contains "_?alt=json_", look at this [link](https://blogs.it.ox.ac.uk/acit-rs-team/2014/10/08/how-to-get-data-out-of-a-google-spreadsheet-using-jsonp/) for more details. You can get the link structure (JSONP) following those steps and remember you have to be logged in. – Ava Barbilla May 14 '15 at 19:33
  • I'm still working on this and as soon as I've cracked it I'll tidy up the question so that it's useful for others. – Faye May 19 '15 at 12:24