Data array from Couchdb documents into D3 - json

I am having a problem integrating Couchdb and D3. D3 is a Javascript library that performs document driven data visualization. Couchdb is a document database. They were made for each other.
D3 binds an array of data to DOM elements of a web page. In most of the examples I have seen on the web or in books, people are working on a static data set. Generally, examples will show an array written into the Javascript or a text.csv file loaded into the page.
I would like to take data directly from database documents and load it into D3. I'm uncertain how to do it. I have seen one example on the web where a person has loaded all of their data as an array into one couchdb document and then brought the data into index.html with a couchdb.jquery call:
/ This function replaces the d3.csv function.
$.couch.db("d3apps3").openDoc("sp500", {
success : function (doc) {
var data = doc.data;
data.forEach(function(d) {
d.date = formatDate.parse(d.date);
d.price = +d.price;
})
I tried something similar with db.allDocs:
<script type="text/javascript">
$dbname = "dataset2";
$appname = "dataset2";
$db = $.couch.db("dataset2");
$db.allDocs({
success: function (data) {
console.log(data)
}
});
</script>
I could get the data to render in console.log, but could not get it into D3 and index.html. I also realized that the datastream resulting from db.allDocs is limited to the _id and _rev of each document.
I also tried to GET the data from a Couchdb view with a d3.json call. That wouldn't work because d3.json is looking for an existing .json file.
It's funny, I can call the view with cURL using a GET command and see the datastream, but can't seem to bind it with D3.
~$ curl -X GET http://anywhere.com:5984/dataset2/_desing/list_view/_view/arnold
{"total_rows":25,"offset":0,"rows":[
{"id":"dataset.csv1","key":"0","value":null},
{"id":"dataset.csv2","key":"1","value":null},
{"id":"dataset.csv11","key":"10","value":null},
{"id":"dataset.csv12","key":"11","value":null},
Any ideas would be appreciated.

Part four of https://gist.github.com/anonymous/9275891 has an example that I think you'd appreciate. You don't need to rely on the jquery.couchdb library at all - d3 knows enough abuot http and json to work right out the box. The relevant piece of code is:
d3.json("_view/pricetimeseries", function(viewdata) {
// We just want rows from the view in the visualisation
data = viewdata["rows"];
data.forEach(function(d) {
// the key holds the date, in seconds
d.date = new Date(d.key);
d.price = +d.value;
});
// rest of the visalisation code
HTH

If the page in which your D3 code is embedded is not served from the same domain (+ port) than CouchDB you will have to enable Cross-Origin Resource Sharing.
Assume your page is at http://example.com/data.html which contains JavaScript D3 code that acesses data from http://db.example.com/ or http://example.com:5984/. In that case your browser (which is executing the JavaScript) will by default deny such (cross-origin) requests unless the requested domain explicitly allows it.
There are basically two solutions to this:
Serve both the data and the page from the same domain, either by
putting a reverse proxy in between that maps resources to upstream servers (eg /couch to your CouchDB server and everything else to your web server)
serving your static files directly from CouchDB
or by allowing Cross-Origin Resource Sharing, which is available in CouchDB since version 1.3. You can find a list of relevant settings in the CouchDB docs on CORS.

Related

Can I access a blob URL in an external page? [duplicate]

I try to write an extension caching some large media files used on my website so you can locally cache those files when the extension is installed:
I pass the URLs via chrome.runtime.sendMessage to the extension (works)
fetch the media file via XMLHttpRequest in the background page (works)
store the file using FileSystem API (works)
get a File object and convert it to a URL using URL.createObjectURL (works)
return the URL to the webpage (error)
Unfortunately the URL can not be used on the webpage. I get the following error:
Not allowed to load local resource: blob:chrome-extension%3A//hlcoamoijhlmhjjxxxbl/e66a4ebc-1787-47e9-aaaa-f4236b710bda
What is the best way to pass a large file object from an extension to the webpage?
You're almost there.
After creating the blob:-URL on the background page and passing it to the content script, don't forward it to the web page. Instead, retrieve the blob using XMLHttpRequest, create a new blob:-URL, then send it to the web page.
// assuming that you've got a valid blob:chrome-extension-URL...
var blobchromeextensionurlhere = 'blob:chrome-extension....';
var x = new XMLHttpRequest();
x.open('GET', blobchromeextensionurlhere);
x.responseType = 'blob';
x.onload = function() {
var url = URL.createObjectURL(x.response);
// Example: blob:http%3A//example.com/17e9d36c-f5cd-48e6-b6b9-589890de1d23
// Now pass url to the page, e.g. using postMessage
};
x.send();
If your current setup does not use content scripts, but e.g. the webRequest API to redirect request to the cached result, then another option is to use data-URIs (a File or Blob can be converted to a data-URI using <FileReader>.readAsDataURL. Data-URIs cannot be read using XMLHttpRequest, but this will be possible in future versions of Chrome (http://crbug.com/308768).
Two possibilities I can think of.
1) Employ externally_connectable.
This method is described in the docs here.
The essence of it: you can declare that such and such webpage can pass messages to your extension, and then chrome.runtime.connect and chrome.runtime.sendMessage will be exposed to the webpage.
You can then probably make the webpage open a port to your extension and use it for data. Note that only the webpage can initiate the connection.
2) Use window.PostMessage.
The method is mentioned in the docs (note the obsolete mention of window.webkitPostMessage) and described in more detail here.
You can, as far as I can tell from documentation of the method (from various places), pass any object with it, including blobs.

How to create JSON response to AJAX request locally without WWW server

I want to practice with JSON and AJAX with HTML pages only (no PHP, no asp.NET, no ruby, no Web server locally installed). I want to create web page which will produce JSON data as result for test AJAX request.
Is it possible?
ADDED:
Lets change it a bit, suppose that I have a webpage (no asp.net, no php).
How to create web page with will output Json data with header set to
header('Content-Type: application/json');
You can give the AJAX request url as "file:///D:/test.txt"
I think IE allows it and Chrome doesn't. And I'm not sure if all versions of IE support it.
Ofcourse this 'response' will be static. It wont change based on your request inputs.
JSON are just javascript objects. What you can do is, instead of invoking the real ajax requests, do a mock request that fetch the locally declared json. For e.g.
jQuery (A concrete implementation)
$.get("ajax/test.html", function( data ) {
console.log(data);
alert( "Load was performed." );
});
Mock implementation
Create a fake json "factory"
var MockJson = (function () {
return { "mockObject" : "mockValue" };
})();
console.log(MockJson);
Of course my example is trivial, you can use the response to manipulate the DOM or display the value somewhere.

How to update Google Drive file using byte range

I'm trying to understand how the Google API works server side in order to allow me to implement my own type of resumable upload. I understand that I can use the MediaFileUpload or MediaInMemoryUpload mechanism, but I am looking for something much more raw. For example, I want to deliberately upload 1k from a file, then later on (like days later), append another 1k of the file. Obviously not real figures here, but hopefully you get the idea. Well here is where I am with the code:
headers = {
'range': 'bytes=%d-%d' % (
offset,
offset + len(data)
)
}
body = {
'title': "MyFile.bin",
'description': "",
'modifiedDate': datetime.datetime.now().isoformat(),
'mimeType': 'application/octet-stream',
'parents': [{ 'id': parentId }]
}
res = http.request(
url, method="PUT", body=body, headers=headers
).execute()
So as you can see, it is clear where you specify the parameters for the file (file attributes) and the header specification for the request. But where do you specify the actual data stream to be uploaded in that request? Is it the case that I can just specify a media_body in the request?
You need to implement a multipart HTTP request which is explained on https://developers.google.com/drive/manage-uploads#multipart
I'd recommend you to use our JS client library and use the existing implementation on the API reference right under the JavaScript tab.
It is not possible and is not formally on Google's roadmap to introduce this functionality. The only way to append to a file is to update the entire file again from scratch.

Download Client Side Json as CSV

I am using the angularJS frontend framework and nodejs/express as a backend server to send and receive JSON. The backend sent a large JSON object to the frontend and I was wondering if I could download the JSON object from the frontend in CSV format.
The data is stored as json in an scope variable: $scope.data in an angular controller. Then I converted the data to a string in CSV format in the variable $scope.CSVdata. How do I get the CSVdata to download from the client browser?
I know nodejs can be set up to send a file in CSV format but it would be nice to keep the backend a clean JSON api.
Referencing this post I've thrown together quick demonstration on how this may be done using AngularJS:
JavaScript Demo (Plunker)
I've wrapped the referenced Base64 code in a service, and use it in the following way:
$scope.downloadCSV = function() {
var data = Base64.encode($scope.CSVData);
window.location.href = "data:text/csv;base64," + data;
};
There are some disadvantages to this method however as mentioned in the comments. I've pulled out some bullet points from the Wikipedia page on this subject. Head over there for the full list.
Data URIs are not separately cached from their containing documents (e.g. CSS or HTML files), therefore the encoded data is downloaded
every time the containing documents are re-downloaded.
Internet Explorer 8 limits data URIs to a maximum length of 32 KB. (Internet Explorer 9 does not have this limitation)
In IE 8 and 9, data URIs can only be used for images, but not for navigation or JavaScript generated file downloads.[7]
Base64-encoded data URIs are 1/3 times larger in size than their binary equivalent. (However, this overhead is reduced to 2–3% if the
HTTP server compresses the response using gzip)
Data URIs do not carry a filename as a normal linked file would. When saving, a default filename for the specified MIME type is
generally used.
[ . . . ]

How do I process Proxy Digg JSON for use with jQuery?

I'm trying to deal with: "Requests made from Javascript running on your web pages must be proxied to avoid same-origin policy conflicts."
I know how to work with the JSON once I've got it. But aside from copy-pasting the JSON results via my browser, I don't know how to localize it for use.
Did you tried
$.getJSON('url', function(data){
//do smth with data
})
?
After the request is complete, data will be an object with all JSON response and you can access it as regular js object: data.something and so on.