I am looking to use Highstock.js for an application I am developing and looking to implement a stock performance with Highcharts stock library chart; http://www.highcharts.com/stock/demo/
I was wondering if there was any good suggestions on where to get the data source from?
Thank-you!
I fetch data from an API, and then store the data in localstorage.
e.g:
This fetches data from an API for use with Highcharts, and stores/updates it in localstorage (jStorage).
updateLocalStorage: function(id) {
//Check if local storage needs updating
if (isNaN($.jStorage.get(id))) {
//Data exists in Localstorage, merge data
//Query API for highstock data
return $.post('api/', {
data_id: id
}, function(data) {
if (data) {
var merged = $.extend($.jStorage.get(id), data);
$.jStorage.set(id, merged);
}
});
//return true;
}
}
Once this data has been fetched I then render highcharts from the data that is stored in localstorage.
$.when(updateLocalStorage(id)).then(function(response){
if(response){
//Local storage is up to date. Render chart
}
});
I can also fetch data from the API using a timer and update localstorage, when I want to re-render the chart I can just use the highcharts setData method, e.g:
var json = $.jStorage.get(id);
for(i =0; i < json.data; i++) {
chart_object.series[i].setData(json.data[i]);
}
You can hardcode data in series / data object as in the example http://www.highcharts.com/demo/ Obviously you can also use dynamically way to define points.
http://docs.highcharts.com/#preprocessing
If you are asking about where to get financial stock price data from, there are several sources I know of including google finance and yahoo finance. Here are some links to help you:
How can I get stock quotes using Google Finance API?
http://www.yqlblog.net/blog/2009/06/02/getting-stock-information-with-yql-and-open-data-tables/
Related
I am trying to use OpenSea API and I noticed that I need to set a limit before retrieving assets
https://docs.opensea.io/reference/getting-assets
I figured I can use the offset to navigate through all the items, even though that's tedious. But the problem is offset itself has a limit, so are assets beyond the max offset inaccessible ?
I read that you that the API is "rate-limited" without an API key, so I assume that related to the number of requests you can make in a certain time period, am I correct about that? Or does it lift the limit of returned assets ? The documentation isn't clear about that https://docs.opensea.io/reference/api-overview
What can I do to navigate through all the assets ?
May be late answering this one, but I had a similar problem. You can only access a limited number (50) assets if using the API.
Using the API referenced on the page you linked to, you could do a for loop to grab assets of a collection in a range. For example, using Python:
import requests
def get_asset(collection_address:str, asset_id:str) ->str:
url = "https://api.opensea.io/api/v1/assets?token_ids="+asset_id+"&asset_contract_address="+collection_address+"&order_direction=desc&offset=0&limit=20"
response = requests.request("GET", url)
asset_details = response.text
return asset_details
#using the Dogepound collection with address 0x73883743dd9894bd2d43e975465b50df8d3af3b2
collection_address = '0x73883743dd9894bd2d43e975465b50df8d3af3b2'
asset_ids = [i for i in range(10)]
assets = [get_asset(collection_address, str(i)) for i in asset_ids]
print(assets)
For me, I actually used Typescript because that's what opensea use for their SDK (https://github.com/ProjectOpenSea/opensea-js). It's a bit more versatile and allows you to automate making offers, purchases and sales on assets. Anyway here's how you can get all of those assets in Typescript (you may need a few more dependencies than those referenced below):
import * as Web3 from 'web3'
import { OpenSeaPort, Network } from 'opensea-js'
// This example provider won't let you make transactions, only read-only calls:
const provider = new Web3.providers.HttpProvider('https://mainnet.infura.io')
const seaport = new OpenSeaPort(provider, {
networkName: Network.Main
})
async function getAssets(seaport: OpenSeaPort, collectionAddress: string, tokenIDRange:number) {
let assets:Array<any> = []
for (let i=0; i<tokenIDRange; i++) {
try {
let results = await client.api.getAsset({'collectionAddress':collectionAddress, 'tokenId': i,})
assets = [...assets, results ]
} catch (err) {
console.log(err)
}
}
return Promise.all(assets)
}
(async () => {
const seaport = connectToOpenSea();
const assets = await getAssets(seaport, collectionAddress, 10);
//Do something with assets
})();
The final thing to be aware of is that their API is rate limited, like you said. So you can only make a certain number of calls to their API within a time frame before you get a pesky 429 error. So either find a way of bypassing rate limits or put a timer on your requests.
I am using AG-GRID version 21.1.0. I have a table on my homepage which loads data on API call. I then applied filter on any number of columns present in my table. Now I am moving to another component using routes. Coming back to my homepage should preserve the filter state for me and after the API call is done, it should show the filtered data on the table as my filter state is already saved when i moved to different component.
I have tried using this.gridApi.getFilterModel() to save the state and this.gridApi.setFilterModel(window.savedModel) to restore the state but it doesn't seems to work
watch: {
data: function(newData, oldData) {
this.gridApi.setRowData(newData);
this.rowData = newData;
this.rows = this.rowData.length;
this.restoreFilterModel();
}
},
methods: {
restoreFilterModel() {
this.gridApi.setFilterModel(window.savedModel);
this.gridApi.onFilterChanged();
},
rowClick(){
window.savedModel = this.gridApi.getFilterModel();
routerData.name = "callflow";
}
}`
on coming back to my homepage API is been called and the data gets loaded again but i want my filter to persist and show me the filtered data in table.
currently it is showing me complete data what my API is returning.
I am storing scores of a user in google cloud firestore as each score a new document in the collection named as "points".
collection name: points
document1: {id:111,userid:345,value:50}
document2:{id:222,userid:345,value:70}
document3:{id:333,userid:345,value:30}
document1:{id:444,userid:345,value:100}
I want to sum all values in value field.
I have google many times but found nothing. Is there any alternative for sum() or any other way to implement recording scores of a user?
There are no built-in aggregation operators in Cloud Firestore.
The naïve solution is to load the data in the client and sum it there, but that means that you (and your users) incur the cost of loading all documents for each time they need to show the sum.
A better way is to keep a so-called running total in your database, which you update whenever a document is written to (added, modified, removed) to the "points" collection. For this you have two options: do it from the client, or do it from a trusted environment (such as Cloud Functions). The Firestore documentation on aggregation queries describes both options and shows sample code.
Use a cloud function which will make a url for you.
Example:
import { Request, Response } from 'express'
import * as admin from 'firebase-admin'
import * as functions from 'firebase-functions'
export const getUsersCount = functions.runWith({ memory: '2GB', timeoutSeconds: 60 }).https.onRequest(async (req: Request, res: Response) => {
const allUsers = await admin
.firestore()
.collection('users')
.get()
const numberOfUsers = allUsers.size;
res.status(200).json({
allTimeUsers: numberOfUsers,
})
return true;
})
Then just do Firebase deploy --only functions:getUsersCount
The logs will print out the url for you. The url might take awhile to load if it's a big app.
You can either use forEach or iterate in a for loop. This answer on stack overflow could help.
Here's an example from the same:
for (var i in querySnapshot.docs) {
const doc = querySnapshot.docs[i]
//do what you want to here
}
---OR---
you can use forEach like this
const collRef = firebase.firestore().collection('todos');
const query = collRef.orderBy('position');
const items = query.get()
.then((snapshot) => {
let newCount = 0;
snapshot.forEach((doc) => {
const docRef = collRef.doc(doc.id);
docRef.update({ position: newCount });
newCount += 1;
});
});
Does anyone know a way to get the exact longitude and latitude for an activity from the strava api using a get request?
I'm trying to integrate the strava api with google maps and I'm trying to build an array with the appropriate long/lat locations, but the https://www.strava.com/api/v3/athlete/activities?per_page=100... request is only returning longitude and latitudes rounded off like: start_longitude: 2.6.
I've found a "hacky" way of retrieving the start coordinates by looping through results and then sending off another request within the loop, although this is sending WAY too many requests. - below is a snippet of my request:
// start request
$.get( "https://www.strava.com/api/v3/athlete/activities?per_page=100&access_token=ACCESSTOKEN", function (results) {
// loop through request
for (i = 0; i < results.length; i++) {
if(results[i].type === 'Run') {
// add an element to the array for each result
stravaComplete.push(true);
$.get( "https://www.strava.com/api/v3/activities/"+ results[i].id +"?per_page=5&access_token=ACCESSTOKEN", function (runs) {
if(typeof runs.segment_efforts[0] != "undefined"){
var runLatitude = runs.segment_efforts[0].segment.start_latitude;
var runLongitude = runs.segment_efforts[0].segment.start_longitude;
stravaActivityList.push({"lat": runLatitude, "lng": runLongitude});
}
// remove the element from the array
stravaComplete.pop();
// if all the elements have been removed from the array it means the request is complete
if(stravaComplete.length == 0) {
// reinitialize map
initMap(stravaActivityList);
}
});
}
}
});
Any guidance would be great. Thanks.
It's not clear if you need coordinates of start points only, or for the whole activity and what accuracy is required.
Response to query https://www.strava.com/api/v3/athlete/activities includes a field map => summary_polyline from which you should be able to extract coordinates of the whole (although simplified) activity. You can also use this polyline to display it in google maps.
If you, however, need even better accuracy you need to retrieve every activity and use map => summary_polyline or map => polyline fields.
To get full data streams should be used
Use summary_polyline[0] and summary_polyline[-1] (Ruby) instead of rounded values. See this code from Slava for an example.
I create dojox.grid.datagrid and I fill content from array like on example last example on page. During time, I change value of that array in code. How to refresh content of that grid ? How to load new data from changed array ?
To change values in the grid, you will need to change the value in the grid's store. The grid data is bound to the store data, and the grid will update itself as needed.
So the key is to understand Dojo's data api and how stores work in Dojo. Rather than manipulating the data directly in the grid, manipulate it in the store.
Ideally, the store is your array that you manipulate as the application runs and you should not be needing to sync the array to the grid. Just use the ItemFileWriteStore as your data holder unless thats not possible.
Also, using the dojo data identity api makes it much simple to find items in the grid if that is possible. Assuming you know when an item is updated, deleted, or changed in your application you should be able to modify the grid store as needed when the action happens. This is definitely the preferred approach. If you can't do that you will have to do a general fetch and use the onComplete callback to manually sync your arrays which will be very slow and won't scale well, in which case you may as well just create a new store all together and assign it to the grid with grid.setStore(myNewStore)
Here is a fiddle with a basic create, update, and delete operation: http://jsfiddle.net/BC7yT/11/
These examples all take advantage of declaring an identity when creating the store.
var store = new dojo.data.ItemFileWriteStore({
data: {
identifier : 'planet',
items: itemList
}
});
UPDATE AN EXISITNG ITEM:
//If the store is not in your scope you can get it from the grid
var store = grid.store;
//fetchItemByIdentity would be faster here, but this uses query just to show
//it is also possible
store.fetch({query : {planet : 'Zoron'},
onItem : function (item ) {
var humans = store.getValue(item, 'humanPop');
humans += 200;
store.setValue(item, 'humanPop', humans);
}
});
INSERT A NEW ITEM:
store.newItem({planet: 'Endron', humanPop : 40000, alienPop : 9000});
} catch (e) {
//An item with the same identity already exists
}
DELETE AN ITEM:
store.fetchItemByIdentity({ 'identity' : 'Gaxula', onItem : function (item ) {
if(item == null) {
//Item does not exist
} else {
store.deleteItem(item);
}
}});
The following code snippet can be used to update the grid:
var newStore = new dojo.data.ItemFileReadStore({data: {... some new data ...});
var grid = dijit.byId("gridId");
grid.setStore(newStore);
EDIT:
Dogo data grid reference guide (add/remove rows example, updating grid data examples )
(I suppose you already have a working grid and you want to completely change the grid's store)
Create a new datastore with your new value :
dataStore = new ObjectStore({ objectStore:new Memory({ data: data.items }) });
(data is the reponse from an ajax request for me)
Change your grid's store with the new one :
grid.store = dataStore;
Render :
grid.render();
This Will update Grid Store and refresh the View of the Grid in latest Version of Dojo 1.9
grid.store = store;
grid._refresh();
I had a server-side filtered EnhancedGrid, which was refreshing happily by changing the store, and shown in the other answers.
However I had another EnhancedGrid that would not refresh when a filter was applied. It may have been to do with the fact it was filtered client side (but data still coming from server using JsonRest store), but I don't really know the cause. Eitherway, the solution was to refresh with the following code:
grid.setFilter(grid.getFilter());
It's hacky and strange, but if it all else fails...
with this i can update a specifi row. this example is for a treegrid.
var idx = this.treeGrid.getItemIndex(item);
if(typeof idx == "string"){
this.treeGrid.updateRow(idx.split('/')[0]);
}else if(idx > -1){
this.treeGrid.updateRow(idx);
}