I have a simple Google Spreadsheet's question. I'm attempting to pull in a table and am not having luck with ImportHTML, it will only pull the first top cell and duplicates it somehow. I also tried ImportXML, using XPath Helper to get the proper XPath, and it will not load the proper table data either.
Google Doc:
https://docs.google.com/spreadsheets/d/1-toAivOhywZuErHK0LB5EADiMu_T9ZNUTgMhqFRBHOU/edit?usp=sharing
What I'm needing is the bottom table(id='player_gbs') on the following site:
http://www.forge-db.com/us/us18/players/profile/?server=us18&world=Sinerania&id=12497
Code Snippet
Here is what I've tried so far, this is all represented in the GDoc as well.
=ImportHTML(B1, "table", 2)
Returns the following line twice:
"Great Building Era Lvl FP Req. FP FP Left 24h +"
=ImportXML(B1, "/html/body/div[#class='wrap']/div[#class='content'][2]/div[#class='b-box']")
Returns:
"GB's with a new level in the last 24 hours are shown with a yellow
background" Great BuildingEraLvlFPReq. FPFP Left24h +Great BuildingEraLvlFPReq. FPFP Left24h +"
Thinking the issue is that contained in the /div is <thead> and <tfoot> before <tbody> so I tried this XPath and just get N/A:
=ImportXML(B1, "/html/body/div[#class='wrap']/div[#class='content'][2]/div[#class='b-box']/div[#id='player_gbs_wrapper']/table[#id='player_gbs']/tbody")
I believe your problem is that that table is created via JSON and javascript. If you view source on that page you'll see this chunk ...
<script type="text/javascript" class="init">
$(document).ready(function() {
$('#player_gbs').dataTable( {
"aLengthMenu": [[30], ['All']],
"processing": true,
"serverSide": true,
"ajax": "../../getPlayerGBs.php?id=12497&server=us18",
Which tells us that the data is coming from the following URL.
http://www.forge-db.com/us/us18/getPlayerGBs.php?id=12497&server=us18
That URL is providing the data that populates the table.
This script (based off this SO response) will parse the data from that feed and write it to a sheet titled dataImport. It only gets the first two chunks of data, you'd just extend the loop to do more.
function urlDownload() {
var dataImport = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('dataImport');
var apiPoint = "http://www.forge-db.com/us/us18/getPlayerGBs.php?id=12497&server=us18";
var response = UrlFetchApp.fetch(apiPoint);
var response_json = JSON.parse(response.getContentText());
var length = response_json.data.length;
var a = [];
for(i=0; i<length; i++){
dataImport.getRange(i+2, 1, 1, 1).setValue(response_json.data[i][0])
dataImport.getRange(i+2, 2, 1, 1).setValue(response_json.data[i][1])
}
}
Related
I'm having a devil of a time going from any code found on the d3 and cubism API pages to altering things to work with what I need them to do...
I'm trying to follow the steps for a Horizon graph as listed here https://github.com/square/cubism/wiki/Horizon but I don't have a Cube or Graphite data source.
So I'm trying to make a minimal example metric from mbostock's answer here
Using Other Data Sources for cubism.js
and/or the random-value-returning metric example here
https://github.com/square/cubism/wiki/Context
I guess on that Context API page, where it explains the parameters to context.metric(), I don't understand the part "...and the callback function for when results are available". I have the following on my server and when I view/refresh in my browser I get "TypeError: callback is not a function" in my browser's console:
<body>
<div class="mag"></div>
<script type="text/javascript">
var myContext = cubism.context();
var myHoriz = myContext.horizon()
.metric(function(start, stop, step, callback) {
var values = [];
start = +start;
stop = +stop;
while (start < stop) {
start += step;
values.push(Math.random());
}
callback(null, values);
});
d3.select(".mag").selectAll("p")
.data([1, 2, 3, 7]) // the "times" for which I want to graph the data
.enter().append("p")
.call(myHoriz);
</script>
</body>
Oh (edit), I should add, the code does run, in that I do get a document with four paragraphs added into the div, and the text contents of each paragraph are the numbers 1, 2, 3, 7. So I guess at least the select(), data(), enter(), and append() bits are working.
Okay Scott Cameron's point got me over the hurdle. I'll "answer" here as well with the resulting working code for future readers. Still not as minimal of an example as I'd like, but eliminates the error, and I'll ask a follow-up in a new question for making it more minimal.
<body>
<div class="mag"></div>
<script type="text/javascript">
var myContext = cubism.context();
var myMetr = myContext.metric(function(start, stop, step, callback) {
var values = [];
start = +start;
stop = +stop;
while (start < stop) {
start += step;
values.push(Math.random());
}
callback(null, values);
});
var myHoriz = myContext.horizon()
.metric(myMetr);
d3.select(".mag").selectAll("p")
.data([1, 2, 3, 7])
.enter().append("p")
.call(myHoriz);
</script>
</body>
It looks like you are confusing horizon.metric with context.metric. It is context.metric that takes a function of the signature you're defining.
I am new to web development and I have bit off more than I can chew.
So far, I successfully have created a website to query the latest data at cosm.com
Now I am trying to save the last 10 data points from the cosm.com feed to an array using the cosm javascript library. I can't get the right syntax and I can't find examples to guide me.
cosm.feed.history( 12068, duration:'30seconds', callback(data) );
console.log(data);
http://jsfiddle.net/spuder/29cFT/12/
http://cosm.github.com/cosm-js/docs/
UPDATE 2013-4-14
After implementing #bjpirt's solution, I noticed I wasn't getting 'every' value returned inside the specified duration.
Solved it by adding "interval:0" to the request.
cosm.datastream.history( cosmFeed1, cosmDataStream1, {duration:'60seconds', interval:0}, getHistory );
http://jsfiddle.net/spuder/ft2MJ/1/
#lebreeze is correct with his advice. I got your JSFiddle working so that it is now fetching data from the Cosm API:
http://jsfiddle.net/nLt33/2/
I had to make a few changes to get it working, any of which would have been causing you errors:
The feed ID and datastream ID were incorrect
You didn't have a callback function
The options weren't in a javascript object
Also, that feed doesn't seem to have been updated recently.
Here's the updated code which seems to be working fine now:
//read only key
cosm.setKey("-Ux_JTwgP-8pje981acMa5811-mSAKxpR3VRUHRFQ3RBUT0g");
var cosmFeed = 120687;
var cosmDataStream = "sensor_reading";
$(document).ready( function() {
var success = function(data){
for(var datapoint in data.datapoints){
var dp = data.datapoints[datapoint];
$('#stuff').append('<li>Value: ' + dp.value + ' At: ' + dp.at + '</li>');
}
}
//Print out the last 10 readings or so
cosm.datastream.history( cosmFeed, cosmDataStream, {duration:'1day'}, success );
})
It's difficult to get just the last x datapoints (that's something we should change in the API I think) - what you'd normally do is ask for a specific time period.
Hope this helps.
You may need to wrap your duration:'30seconds' json options in {}
Try something like:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://d23cj0cdvyoxg0.cloudfront.net/cosmjs-1.0.0.min.js"></script>
<script>..
cosm.setKey( "APIKEY" );
cosm.feed.history(40360, {duration:'30seconds'}, function(data){
console.log(data);
console.log(data.datastreams);
});
</script>
i saw an example on how to load markers dynamically on this page
https://developers.google.com/maps/articles/phpsqlsearch_v3
and i saw another code igniter Google-maps api from BIOSTALL.
but this(http://biostall.com/codeigniter-google-maps-v3-api-library) library doesn't load the markers dynamically how can i achieve that using the library it self.
should i try to fetch the markers on map init or does the library provide a way to load these markers using ajax
Firstly, thanks for using my library. It's worth noting that the library is merely a way to simplify the generation of the Google Maps code. It constructs the JavaScript and HTML on your behalf making it quick and easy to add maps to your page.
There are a million and one ways that a developer might want to interact with the Google Maps API and it's impossible for the library to cater for every single instance. As a result, there are times where, in a bespoke situation like this, you may need to add your own code so it performs as you require.
As a result, might I suggest you simply add in the custom JS you require after you do echo $map['js']. There is a function available that comes with the library called createMarker() which, if you view the source code, you will see.
In pseudocode this will look like so:
<?php echo $map['js']; ?>
<script type="text/javascript">
// Get marker(s) with ajax
// Call createMarker() function to add marker(s) to map
</script>
I hope that helps somewhat.
Trying the pseudocode suggested by Biostall, this is what i have implemented:
$.ajax({
url: '*URL*',
type: "POST",
data: ({value : *value*}),
dataType: "json", //retrieved Markers Lat/lng in Json, thus using this dataType
success: function(data){
//Removing already Added Markers//////////
for(var i=0; i < markers.length; i++){
markers[i].setMap(null);
}
markers = new Array();
//////////////////////////////////////////
// Adding New Markers////////////////////
for (var i = 0, len = data.length; i < len; ++i) { // Iterating the Json Array
var d = data[i];
var lat = parseFloat(d.lattitude);
var lng = parseFloat(d.longitude);
var myLatlng = new google.maps.LatLng(lat,lng);
var marker = {
map:map,
position:myLatlng // These are the minimal Options, you can add others too
};
createMarker(marker);
}
}
}
);
Note: If an array of Markers is being sent to this ajax call, it must be json encoded with the php function json_encode(). And thus you can use the dataType: "json" as mentioned in the ajax call parameters.
This worked for me, hope this might help.
I have created a script that long polls a JSON source and updates a div with the results. My code is posted below.
The code works fine and the data I request is grabbed and outputted correctly. The code checks the JSON and grabs 2 images and some text data.
The problem is it keeps refreshing the data and downloading the images constantly causing high server load and bandwidth consumption (obviously this is small right now but will increase as I complete my project). This also leads ot me not being able to select the text in the div and the images flicker as they are reloaded, both are undesirable consequences of my current code.
I want to be able to grab the data and display it, and not update it at all until the data actually changes in the JSON response, I am assuming I need to do something with a timestamp?. I have tried creating a lastupdate timestamp by using the first_aired key from the JSON but it is not working, I am unsure if I have made a mistake or if I am barking up the wrong tree.
Could someone take a look at the code I have and perhaps point me in the correct direction as to what I need to do?
var lastupdate = 0;
// call getData when the document has loaded
$(document).ready(function(){
getData(lastupdate);
});
var getData = function(lastupdate) {
$.ajax({
type: "GET",
url: 'http://api.trakt.tv/user/watching.json/apikey/user/lastupdate='+lastupdate+'&callback=?',
dataType: 'jsonp',
async: true,
cache: false,
// timeout after 5 minutes, shut process down and restart
timeout:300000,
// process a successful response
success: function(watching_now) {
if (!jQuery.isEmptyObject(watching_now)) {
//console.log(watching_now);
var airDate = watching_now.episode.first_aired;
var showTitle = watching_now.show.title;
var showPoster = watching_now.show.images.poster;
var showURL = watching_now.show.url;
var episodeTitle = watching_now.episode.title;
var episodeScreen = watching_now.episode.images.screen;
var episodeNumber = watching_now.episode.number;
var episodeSeason = watching_now.episode.season;
$('#watching-now').html('<div class="screencap"><img src="' + episodeScreen +' " width="240" height="150" /></div><div class="poster"><img src="' + showPoster +'" width="85" height="120" /></div><div class="watching-info">'+episodeSeason+'x'+episodeNumber+' - '+episodeTitle+'</div>')
}
else {
$('#watching-now').html('You are not currently watching anything')
}
// set lastupdate
lastupdate = watching_now.airDate;
// call again in 1 second
setTimeout('getData('+lastupdate+');', 1000);
},
// handle error
error: function(XMLHttpRequest, textStatus, errorThrown){
// try again in 10 seconds if there was a request error
setTimeout('getData('+lastupdate+');', 10000);
},
});
};
Here is the JSON I am getting the information form:
{"type":"episode","action":"watching","show":{"title":"Stargate Atlantis","year":2004,"url":"http://trakt.tv/show/stargate-atlantis","imdb_id":"tt0374455","tvdb_id":"70851","tvrage_id":"5324","first_aired":1089961200,"country":"United States","overview":"The story of Stargate Atlantis follows the cliffhanger episode on Stargate SG-1's seventh season finale \"Lost City\", where SG-1 found an outpost made by the race known as the Ancients in Antarctica. After the events of Stargate SG-1 season eight premiere \"New Order\", the Stargate Command sends an international team to investigate the outpost. Soon, Dr. Daniel Jackson discovers the location of the greatest city created by the Ancients, Atlantis. The story unfolds when the members of the expedition encounter the Wraith, the race that defeated the Ancients ten thousand years ago.","runtime":60,"network":"Syfy","air_day":"Monday","air_time":"9:00pm","certification":"TV-PG","images":{"poster":"http://trakt.us/images/posters/329.3.jpg","fanart":"http://trakt.us/images/fanart/329.3.jpg","banner":"http://trakt.us/images/banners/329.3.jpg"},"genres":["Action","Adventure","Science Fiction"]},"episode":{"season":3,"number":10,"title":"The Return (1)","overview":"The Atlantis expedition is stunned to learn that a ship full of Ancients is returning to reclaim their lost city. ","first_aired":1158908400,"url":"http://trakt.tv/show/stargate-atlantis/season/3/episode/10","images":{"screen":"http://trakt.us/images/episodes/329-3-10.3.jpg"}}}
If you need more information please just ask and I will provide everything I can.
Cheers
Take a look at example shown in link below.
http://www.zeitoun.net/articles/comet_and_php/start
what it does is pass time-stamp and get the record between current time-stamp and passed time-stamp.
Im using the google visualization chart api here: https://developers.google.com/chart/interactive to make a server uptime graph which seems to be working nicely.
However I want the users to be able to select a date range and then redraw the graph without having to refresh the browser. And I have a small problem with this.
I first draw the graph with the initial data, and then if a user changes the date range this graph should be redrawn. I tried redrawing with some sample data and this works fine. However I cant seem to get it to work with the updated data.
Now in the php file where i fetch the data from the DB i return both the average uptime for this period as well as the total uptime for the period as such:
/*mysql query striped*/
$uptime_result = mysql_query($query, $connection) or die(mysql_error());
$uptime_data = "['Day', 'Uptime'],";
while ($items = mysql_fetch_array($uptime_result)){
$uptime_data.="['{$items['date']}',{$items['uptime']}], ";
}
// get average uptime
/*mysql query striped*/
$uptime_result = mysql_query($query, $connection) or die(mysql_error());
$result_array = mysql_fetch_array($uptime_result);
$avg_uptime = round($result_array['AVG(uptime)'],2);
echo "{\"data\":\"{$uptime_data}\",\"average\":$avg_uptime}";
Which outputs something like:
{"data":"['Day', 'Uptime'],['2012-05-31',100.00], ['2012-06-01',100.00], ['2012-05- 22',99.65], ['2012-05-21',99.65], ['2012-05-20',100.00], ['2012-05-31',100.00], ['2012-05-30',100.00], ['2012-05-29',100.00], ['2012-05-28',100.00], ['2012-05-27',100.00], ['2012-05-26',100.00], ['2012-05-25',100.00], ['2012-05-24',100.00], ['2012-05-23',100.00], ['2012-05-19',100.00], ['2012-05-18',100.00], ['2012-05-17',100.00], ['2012-05-16',100.00], ['2012-05-15',100.00], ['2012-05-14',100.00], ['2012-05-13',100.00], ['2012-05-12',100.00], ['2012-05-11',100.00], ['2012-05-10',100.00], ['2012-05-09',100.00], ['2012-05-08',100.00], ['2012-05-07',100.00], ['2012-06-02',100.00], ['2012-06-03',100.00], ['2012-06-04',100.00], ","average":99.98}
I.e a JSON array with two variables data and average. I am able to fetch the two independently as such:
$(function(){
$('#from,#to').focusout(function(){
var start=$('#from').val();
var end=$('#to').val();
$.ajax({
type: 'POST',
data: ({from : start, to : end, id : <?php echo $id; ?>}),
url: 'fetchuptime.php',
success: function(data) {
//7 reulst goes here
//var json = data;
var obj = jQuery.parseJSON(data);
$('#uptime_span').html(obj.average +" %");
$('#test').html(data);
chart_data = google.visualization.arrayToDataTable([
obj.data
]);
var ac = new google.visualization.AreaChart(document.getElementById('visualization'));
ac.draw(chart_data, {
colors : ['#00DB00'],
title : '',
isStacked: false,
width: 570,
height: 400,
'chartArea': {'width': '88%', 'height': '90%'},
hAxis: {minValue: 0,showTextEvery: 6, slantedText: false},
vAxis: {
viewWindowMode:'explicit',
viewWindow:{
max:100,
min:90.65
}
},
pointSize: 3,
legend: {position: 'none'}
});
}
});
});
});
eg. obj.average and obj.data gives me the two string. However this does not seem to work, i guess the data doesn't get passed along correctly.
I have tested the actual output data (eg obj.data) is formatted correct as I've tried inserting it statically.
So I'm obviously doing something wrong here, and I assume it's because I'm passing an string while google chart needs an array, tried to fix it in various ways but haven't found anything working yet.
Can anyone help me with this one?
The format of your JSON is valid, but probably not what you're wanting:
{"data":"['Day', 'Uptime'],['2012-05-31',100.00] ... ['2012-06-04',100.00], ", "average":99.98}
That represents an object with a field named data whose value is a string (like you said). What you probably want to do is make it an array on the server side. Instead of double quotes, use square brackets. There is also a trailing comma which must be removed.
{"data":[['Day', 'Uptime'],['2012-05-31',100.00] ... ['2012-06-04',100.00]], "average":99.98}