🏠 back to Observable

CORS Error when trying to include notebook locally.


#1

I have been following the steps in the following link in order to embed a chart in the UI using a locally stored notebook:

I get the following error in the javascript console as a response:

Access to script at 'file:///Users/danielbruce/Downloads/667e4df76848e72f250b-117f7825ef20b1fe1cee954ee5c4c11b6de9d8e6/circle-graph-2.js' from origin 'null' has been blocked by CORS policy: The response is invalid.

How do I overcome this?


#2

Local JavaScript files often don’t work well in browsers these days.

Instead of opening the index.html page directly, you can serve it from a local webserver. For example: try opening a terminal for the directory that holds your index.html page, running python -m SimpleHTTPServer, and then visiting http://localhost:8000.

If its still giving you trouble, tell us a bit more about your OS — or where you’re trying to host your notebook, and perhaps we can further assist…


#3

The solution using python works like a charm :slight_smile:

Now how do I populate the chart with my own custom data just as if I would type it into the UI beside ‘data’ on an observable page?


#4

I think you’re asking how to rewrite your ‘data’ cell so that it loads a file containing your custom data from disk. There’s some discussion of techniques to do this in these two tutorials:


If you share a link to your notebook and say a little more about what you want, we can probably help you get something working.


#5

You are correct about what I want to do. The notebook I want to use (locally) is given below:

https://api.observablehq.com/@mbostock/d3-zoomable-circle-packing.js

In order to load data from a file or json text, I believe it is the following line that I need to replace:

value: (function(require){return(
require("@observablehq/flare")
)})

The problem is that I don’t know what to replace it with in order to read json so that I can create my own structure of zoomable circles.

Any help is most appreciated.


#6

The first thing you’ll need to do is figure out how to write JSON that conforms to the format which that notebook can read. For reference, here’s the actual file that the notebook you’re looking at is parsing. https://unpkg.com/@observablehq/flare@0.0.0/index.js

Basically you want to create a JSON data which imitates the structure of everything in the curly braces after “return” in that JS file. Here’s one very basic example which you can try out by replacing the data cell in the online Observable version with this:

data = ({name:"big",children:[{name:"medium2",children:[{name:"small200",size:"200"},{name:"small100",size:"100"}]},
                             {name:"medium3",children:[{name:"small50",size:"50"},{name:"small150",size:"150"},
                                                       {name:"small75",size:"75"}]}]})

If you were to export the notebook, the cell should translate into something like this:

    {
      name: "data",
      inputs: [],
      value: (function(){return({name:"big",children:[{name:"medium2",children:[{name:"small200",size:"200"},{name:"small100",size:"100"}]},
                             {name:"medium3",children:[{name:"small50",size:"50"},{name:"small150",size:"150"},
                                                       {name:"small75",size:"75"}]}]}
)})
    },

This should work for testing, but you may eventually want an approach which more cleanly separates the data from the visualization so that you won’t have to keep editing this JS file to change the data.

One way to do this is as follows. First save your JSON file somewhere in the local directory where your html / js files are, say in my_data.json. Note that to be valid JSON, the property names like “name”, “size”, and “children” have to be in double quotes like this:

{"name":"big","children":[{"name":"medium2","children":[{"name":"small200","size":"200"},{"name":"small100","size":"100"}]},
                             {"name":"medium3","children":[{"name":"small50","size":"50"},{"name":"small150","size":"150"},
                                                       {"name":"small75","size":"75"}]}]}

Then in the JS file corresponding to your notebook, replace the data cell with the following, which uses d3.json to request and parse the file:

    {
      name: "data",
      inputs: ["d3"],
      value: (function(d3){return(
d3.json('my_data.json')
)})
    },

Now you can just edit my_data.json and refresh the page to see the changes.


#7

This is exactly what I need! Thank you.