I'm a total novice in web development. I'm interested in using D3 to create interactive visualizations for my (insurance) work, not for sharing on web. The visualization would need to be pretty self-contained so non-tech-savvy business users can view it without special software setup--just the usual browser, internet access, and access to the same LAN locations I have. Below is my initial investigation into viability.
1) I can save this HTML example to my local machine and view the chart in a browser, no probs: https://bl.ocks.org/mbostock/b5935342c6d21928111928401e2c8608
2) Then I tried a visualization that uses a data file.
https://bl.ocks.org/mbostock/2838bf53e0e65f369f476afd653663a2
I went to the data source website and downloaded the .csv. Simply changing the file address in the d3.csv() command to my local drive didn't work (as I mentioned I'm a novice)
Can anyone show me how to make (2) work locally? I found some related answers
Loading local data for visualization using D3.js
Reading in a local csv file in javascript?
but still over my head--if someone can work the example (2) above I can probably understand better...
There are two techniques you can use to load d3 data without a server:
load the data yourself without using d3.csv() helpers.
use data-urls with d3.csv() to avoid server loading.
Loading the data yourself without d3.csv()
Your first example: Stacked Negative Values works because data is defined at the top of the page without using d3.csv():
var data = [...];
...
// d3 operates on the data
Your second example: Nested TreeMap doesn't work because the data is loaded by d3.csv() which takes a path, which ordinarily takes assumes a server:
d3.csv("Home_Office_Air_Travel_Data_2011.csv", type, function(error, data) {
...
// work on data within the anon function passed to d3.csv.
Using data-urls with d3.csv()
However, if you use a data-url as the path, you can get this to work without a server:
var data = [...];
var dataUri = "data:text/plain;base64," + btoa(JSON.stringify(data));
d3.csv(dataUri, function(data){
// d3 code here
});
Adapted from: Create data uri's on the fly?
As an aside, you may be interested in a Middleman plugin I wrote that creates self-contained d3 HTML pages that can be run from the file system without a server using these approaches:
https://github.com/coldnebo/middleman-static-d3
Most modern browsers (chrome, mozilla) have full built in html5, css3, and javascript support without need of a webserver (this is the preferred route for developement).
For example, if you're using chrome all you need to do is set the allow local file access flag: How to launch html using Chrome at "--allow-file-access-from-files" mode?
In mozilla set the about:config key security.fileuri.strict_origin_policy to false.
Again, these are options for loading local files without a webserver, but setting up a webserver is a relatively simple task that is the most recommended route.
you'll need to run a local server like python's SimpleHTTPServer to get this to work locally. once you've got it installed, it's as simple as running a single command in your terminal.
however, since you said that your end users should be able to access it through the browser, do you mean that you'll host it online? if so, they'll be able to view it correctly on the server
Notice how in the first example the data in hard coded into the html page with the variable name data? The data is already here so you won't need a server to go and fetch the data. On the other hand, in second example the data is not hardcoded and is fetched with a server. If you want this to work like the first example you will have to hard code the data into the web page.
You may want to use SERVED by Ian Johnson, its pretty good.
http://enjalot.github.io/served/
Related
I was used to handle data using PHP + PostGreSQL and, after a SQL query, print data in table using
while($var= pg_fetch_assoc($result)){
echo <<<PRINT
<tr>
<td>{$var['id']}</td>
<td>{$var['name']}</td>
<td>{$var['surname']}</td>
<td>{$var['placement']}</td>
</tr>
PRINT;
Now I have a similar problem but I have to handle JSon files only using JavaScript and no JQueries/AJAX syntax. I made some reasearch and found out that seems not possible to load data using JavaScript for security reasons, but it feels kinda odd since you can manipulate all kind of media-type files.. and you cannot get JSon text files from your disk.
So, is it really possible to load JSon files using JavaScript and then being able to manipulate it ciclicaly?
Well, depends, if you mean a local .JSON file you could simply use require to get the object, to manipulate it you could either use fs or klaw
Deal with files on the PC, form the browser
Maybe you should test something from the File Web API.
Search for "File" here.
Deal with files on a server, form the browser
You publish your JSON at some URL and then GET the JSON with AJAX.
See: https://www.w3schools.com/xml/ajax_intro.asp
You can modify files with http protocols.
I paste this link, to make a mini web server https://sourceforge.net/projects/miniweb/
First of all you can't access a local file directly from the browser. File should be served over a local server, specially if you are using Chrome. Since Chromes security is much tighter than Firefox or others, loading anything using xhr, Josn, Xml etc is pretty much all locked down.
you can use simply use apache, python or node to set up a simple local server.
Then use Fetch API. All modern browsers support Fetch API except Internet NOBODY USING Explorer.
fetch('/path/to/test.json')
.then(response => response.json())
.then(json => console.log(json));
done..! hope it helps.
I've built a simple html page with javascript in a separate file, called on a button press.
I've opened the html file in chrome, and the path resembles: file:///home/tom/projects/index.html
The javascript needs to read a JSON file (file:///home/tom/projects/mydata.json) which is in the same directory, using a hardcoded path.
I'm really struggling to do this. As I understand, this is because I'm using client side js (meaning I can't use the fs library for example), which is limiting my options.
According to the question here, I can't load the file if I use the URL in the format: file:///home/to.... as it gives me the error:
Cross origin requests are only supported for protocol schemes: HTTP, data, chrome, chrome-extension, https.
If I start an HTTP-server, as the answer suggests, I can use server-side modules, but if possible I would like to avoid this.
I've noticed many answers that suggest using a dialog box like this:
var selectedFile = document.getElementById('input').files[0];
function readFile (file_path) {
var reader = new FileReader();
reader.readAsText(file_path);
console.log(reader.substring(0, 100));
};
but I can't make this work with a path in the form: file:///home/tom/projects/mydata.json
Is there a way to load a .json file from a file:///home/to.... format URL using client-side javascript, with a hardcoded path (ie not asking the user to select the file from a selection box)?
This is a deliberate security restriction, to stop a user from being given, and then opening, a HTML page which then tries to read their disk.
Run your page in a webserver (as that question suggested) then you can either load the JSON from a URL (e.g. something like http://localhost/projects/mydata.json) using JavaScript, or use a server-side language to fetch it and display it inside the rendered HTML. Either way will work, the first way is probably simpler and closest to what you've got now.
It's always far better to serve HTML pages from a HTTP server, the way it's intended to be.
i have a c++ file which reads values from a sensor and I want to display those values on a website dynamically. So Im looking for a way to pass these values(integers) from my cpp file to an javascript which displays them on the site.
My first, simple try was to write the values into a js file as variables every second from my cpp script. The Js then uses this file as a source and displays its variables on the site:
cpp:
fprintf(file, "var mx=%d, my=%d, mz=%d, ax=%d, ay=%d, az=%d, gx=%d, gy=%d, gz=%d;\n",
imu.raw_m[0], imu.raw_m[1], imu.raw_m[2], // M = Magnetometer
imu.raw_a[0], imu.raw_a[1], imu.raw_a[2], // A = Accelerometer
imu.raw_g[0], imu.raw_g[1], imu.raw_g[2] // G = Gyroscope
);
html/js:
<script src="./imu.js" type="text/javascript"></script>
The Problem now is of course, that I need to refresh the page all the time, because the imu.js file is cached by the website.
I'd rather have a way to directly pass to integers from the cpp file to the js script. I read something about json or Googles V8 script. But I'd like to hear your suggestions first.
By the way, Im running this on a raspi, if this is important.
Thanks for your help
EDIT:
I'm goning to try it with a mysql database, in which my cpp file writes the data from the sensor with Connector/c++ from http://dev.mysql.com/doc/connector-cpp/en/ and my website reads them.
You could compile your C++ code into a Node.js plugin, you can then register a JavaScript function with your plugin which the C++ calls when it updates the value. That way you can pass values directly from C++ into Javascript in a managed and controlled way.
Node.js has the added benefit of being able to host your webpage and do all the Websocket and HTTP stuff that can be a pain in C++.
You do not have to refresh if your script is smart about how to access the data file! In case you do have a webserver at hand: Take care that your data file is accessible by your webserver and then let your script request the file via ajax (link to w3schools)
I'm doing something similar on a BeagleBone Black. With websocketd you can turn pretty much any program into a websocket endpoint and then send data via stdin and stdout commands. This would be a particularly good solution for you since websockets are designed to handle information that's constantly changing.
I have been trying to render a map offline on an android device. I am trying to use d3 for this and any leads and suggestions will go a long way in helping me out.
Can I use d3 and the geojson/topojson files of the region to plot the map on the browser? However, Is there a way to do this without an app server? As of now d3 reads a json through the function d3.json() which needs an app server in itself. Is there a way in which d3 can read the json file directly from the local file path instead of a URL?
Any other direction to approach this problem will be appreciated. Awaiting your response.
Regards,
Jones
This is not possible.
d3.json is meant to load data through HTTP. As a workaround, you could set up a local server to serve the data over HTTP.
This is possible. I have done something like this.
For me, I used an app server but I pushed the JSON string into the HTML and fetched it directly using JavaScript. The code is something like this:
var root = treeData = JSON.parse($('#json').val());
function visit(parent, visitFn, childrenFn) {
//....
visit(treeData, function(d) {
//....
Have you considered using an approach like IndexedDB to cache the json? This way you could load the json into IndexedDB on the first page load or while you have internet connectivity, and then retrieve it from the store when you are offline.
I have a python 2.7 app on Google Appengine. One of the JS files is served via a python script, not a standard static handler. The app.yaml config is shown below:
- url: /js/foo.js
script: python.js.write_javascript.app
secure: optional
The request for foo.js is part of a code snippet clients, of our service, place on their website, so it can't really be updated. python.js.write_javascript.app basically just reads in a JS template file, substitutes in a few customer specific values and prints to the browser.
What I'm wondering is, how do we set the correct headers so this request is cached correctly. Without any custom headers, appengine's default is to tell the browser never to cache this. This is obviously undesirable because it creates unnecessary load on our app.
Ideally, I would like to have browsers make a new request only when the template has been updated. Another option would be to cache per session.
Thanks
Well
It looks like Google handles this automatically. I just print it, using the correct JavaScript headers but without any cache headers and Google's CDN caches it for me. I'm not sure what the default cache lifetime is but I saw no increase in instances or cost by implementing this.
It seems Google just takes care of it for me.