Importing local json file using d3.json does not work
Asked Answered
U

8

53

I try to import a local .json-file using d3.json().

The file filename.json is stored in the same folder as my html file.

Yet the (json)-parameter is null.

d3.json("filename.json", function(json) {
    root = json;
    root.x0 = h / 2;
    root.y0 = 0;});
    . . . 
}

My code is basically the same as in this d3.js example

Uniformitarian answered 20/6, 2013 at 12:59 Comment(5)
If you're using Chrome, you could try running it with --disable-web-security.Pluck
You can also run a local server on your machine and access the page that way. WAMP and MAMP both work great, or you can ever run from command line on a MAC: lifehacker.com/…Australopithecus
I should have just read the d3.json API a little more closely. Sorry for wasting people's time.Uniformitarian
If you're using Chrome, the command line switch --allow-file-access-from-files is safer than --disable-web-security.Attached
possible root cause: #4819560Verney
S
57

If you're running in a browser, you cannot load local files.

But it's fairly easy to run a dev server, on the commandline, simply cd into the directory with your files, then:

python -m SimpleHTTPServer

(or python -m http.server using python 3)

Now in your browser, go to localhost:3000 (or :8000 or whatever is shown on the commandline).


The following used to work in older versions of d3:

var json = {"my": "json"};
d3.json(json, function(json) {
    root = json;
    root.x0 = h / 2;
    root.y0 = 0;
});
Supersaturated answered 20/6, 2013 at 20:57 Comment(7)
Can you please explain your code a bit... how would I go from this d3.json(filename, function(error, data) {...} (Should I submit a separate question?)Everrs
I would say outright that this answer's code is wrong, except for the 13 upvotes. d3.json takes a url as its first argument, not a json object. Ditto jQuery's $.get method. If the json is already defined in the file, there's no need to issue an ajax request via d3.json or $.get; simply reference the variable directly. Or am I missing something here that would explain the 13 upvotes?Biaxial
@JamesConkling a variable isn't the same thing as a file. but yes, you can put the first line in my example in its own javascript file and that works as well.Supersaturated
@Supersaturated yeah, that's my point, if the json is defined in the script file, why use d3.json? If the json is not defined in the script file, then use d3.json and load the script via a server. Mixing the two approaches (defining the json in the script file and using d3.json makes no sense at all).Biaxial
@JamesConkling the question was about having the data in a JSON file ({"my": "data"}), not a script file (var data = {"my": "data"};)Supersaturated
@mb21, yes, in which case d3.json() takes a string representing the path to the file. In no case should d3.json() take a JSON object (or anything other than a string) as its first argument. see here.Biaxial
it works for me. I have conda managed python 3. I run above on the anaconda prompt.Frisbee
C
22

In version d3.v5, you should do it as

d3.json("file.json").then(function(data){ console.log(data)});

Similarly, with csv and other file formats.

You can find more details at https://github.com/d3/d3/blob/master/CHANGES.md

Carrick answered 18/12, 2018 at 21:49 Comment(3)
Please use the edit link to add more information to your answer rather than a comment. I've done this for you on this post.Detrition
this works on an html, js file and json file. But I use this in Angular 7 and i get GET error. I use a json emitted from a service from a url I found, and it works. For some reason, local json files cant be used inside of d3.json().Whimsicality
@Whimsicality this should work in Angular if you put the json file in your assets folderRayleigh
P
10

Adding to the previous answers it's simpler to use an HTTP server provided by most Linux/ Mac machines (just by having python installed).

Run the following command in the root of your project

python -m SimpleHTTPServer

Then instead of accessing file://.....index.html open your browser on http://localhost:8080 or the port provided by running the server. This way will make the browser fetch all the files in your project without being blocked.

Prothrombin answered 13/12, 2016 at 22:42 Comment(0)
Z
8

Loading a local csv or json file with (d3)js is not safe to do. They prevent you from doing it. There are some solutions to get it working though. The following line basically does not work (csv or json) because it is a local import:

d3.csv("path_to_your_csv", function(data) {console.log(data) });

Solution 1: Disable the security in your browser

Different browsers have different security setting that you can disable. This solution can work and you can load your files. Disabling is however not advisable. It will make you vulnerable for all kind of threads. On the other hand, who is going to use your software if you tell them to manually disable the security?

Disable the security in Chrome:

--disable-web-security
--allow-file-access-from-files

Solution 2: Load your csv/json file from a website.

This may seem like a weird solution but it will work. It is an easy fix but can be unpractical though. See here for an example. Check out the page-source. This is the idea:

d3.csv("https://path_to_your_csv", function(data) {console.log(data) });

Solution 3: Start you own browser, with e.g. Python.

Such a browser does not include all kind of security checks. This may be a solution when you experiment with your code on your own machine. In many cases, this may not be the solution when you have users. This example will serve HTTP on port 8888 unless it is already taken:

python -m http.server 8888
python -m SimpleHTTPServer 8888 &

Open the (Chrome) browser address bar and type the underneath. This will open the index.html. In case you have a different name, type the path to that local HTML page.

localhost:8888

Solution 4: Use local-host and CORS

You may can use local-host and CORS but the approach is not user-friendly coz setting up this, may not be so straightforward.

Solution 5: Embed your data in the HTML file

I like this solution the most. Instead of loading your csv, you can write a script that embeds your data directly in the html. This will allow users use their favorite browser, and there are no security issues. This solution may not be so elegant because your html file can grow very hard depending on your data but it will work though. See here for an example. Check out the page-source.

Remove this line:

d3.csv("path_to_your_csv", function(data) { })

Replace with this:

var data = 
    [
        $DATA_COMES_HERE$
    ]
Zenas answered 13/9, 2020 at 14:37 Comment(0)
G
6

http://bl.ocks.org/eyaler/10586116 Refer to this code, this is reading from a file and creating a graph. I also had the same problem, but later I figured out that the problem was in the json file I was using(an extra comma). If you are getting null here try printing the error you are getting, like this may be.

d3.json("filename.json", function(error, graph) {
  alert(error)
})

This is working in firefox, in chrome somehow its not printing the error.

Gunzburg answered 20/4, 2015 at 8:57 Comment(0)
A
1

You can't readily read local files, at least not in Chrome, and possibly not in other browsers either.

The simplest workaround is to simply include your JSON data in your script file and then simply get rid of your d3.json call and keep the code in the callback you pass to it.

Your code would then look like this:

json = { ... };

root = json;
root.x0 = h / 2;
root.y0 = 0;
... 
Attached answered 11/5, 2016 at 15:18 Comment(0)
D
1

I have used this

d3.json("graph.json", function(error, xyz) {
    if (error) throw error;
    // the rest of my d3 graph code here
    }

so you can refer to your json file by using the variable xyz and graph is the name of my local json file

Dibbuk answered 25/7, 2018 at 15:23 Comment(0)
M
-1

Use resource as local variable

var filename = {x0:0,y0:0};
//you can change different name for the function than json
d3.json = (x,cb)=>cb.call(null,x); 
d3.json(filename, function(json) {
    root = json;
    root.x0 = h / 2;
    root.y0 = 0;});
    //...
}
Marashio answered 6/1, 2022 at 10:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.