user2896287
user2896287

Reputation: 13

Data array from Couchdb documents into D3

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.

Upvotes: 1

Views: 1398

Answers (2)

SimonM
SimonM

Reputation: 116

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

Upvotes: 2

Stefan K&#246;gl
Stefan K&#246;gl

Reputation: 4733

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.

Upvotes: 1

Related Questions