D3 Bar Graph example does not work locally

I am very new to D3 and wanted to see how the example will work locally. I copied and pasted the histogram code into the local index.html file, and also copied the data.tsv file. For some reason, absolutely nothing appears when I open the file in the browser! I tried changing the src script to "d3 / d3.v3.min.js" because this is the folder where d3 is loaded into. However, this does not work either. For each example I tried, I have yet to successfully review the D3 example. Help will be appreciated!

The index.html code is as follows:

<meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: steelblue; } .x.axis path { display: none; } </style> <body> <script src="d3/d3.v3.min.js"></script> <script> var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var formatPercent = d3.format(".0%"); var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(formatPercent); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.tsv("data.tsv", type, function(error, data) { x.domain(data.map(function(d) { return d.letter; })); y.domain([0, d3.max(data, function(d) { return d.frequency; })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Frequency"); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.letter); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.frequency); }) .attr("height", function(d) { return height - y(d.frequency); }); }); function type(d) { d.frequency = +d.frequency; return d; } </script> 

and data.tsv has the following format: writing frequency A.08167 B.01492 C.02780 D.04253 E.12702 F.02288 G.02022 H.06094 I.06973

+7
javascript html local
source share
3 answers

The d3.tsv method makes an AJAX request for the data. In most browsers, this will not work locally due to Same Origin Policy , which usually prohibits AJAX requests to file:/// URL.

To get an example of using AJAX working locally, you will need a local web server. If you have Python, run

 > python -m SimpleHTTPServer 

from the command line in the directory where your files will do this. If you prefer node.js try http-server .

+14
source share

As an alternative, and I myself was suggested by Lars Kottoff when trying to work with .tsv / .csv files, you can directly work for this:

http://plnkr.co/

This allows you to work with all the .json / .tsv / .csv files that you like and share them with people for collaboration. You can do this anonymously or not, the important thing is that you do not lose the HTTP address of your plunker created then.

It should be noted that you cannot directly upload files as you would on an FTP server, but you should:

  • Click "new file"
  • Enter the name of your .csv / .tsv / .json file specified in your code (including the extension)
  • Copy and paste the code contained in this file as it is.
  • Do not forget to update the names of your .css / .js, if necessary, to match your index.html
+1
source share

As already mentioned, you most likely encounter a CORS problem with XHR in the d3 library for an external resource for analyzing JSON data.

However, here is another solution: use JSONP and Express / Node.js in combination with the jQuery function to trigger a client request for JSON instead of using the original shell for d3 functions.

I had to remove the original d3.json wrapper and fill in the adjacency diagrams with the data from the request. Start by cloning or downloading jsonp-d3-experiment and start the server using node server.js . Of course, you must install Node.js globally, starting with Node Packaged Modules (npm). Copy your program to a subdirectory.

Put your JSON data in the jsonp-d3-experiment directory and modify server.js to redirect the request to your data:

 // Return data from callback server.get('/example', function(req, res) { // Read the JSON data and send to JSONP response readJSON('example.json', function (e, json) { if (e) { throw e; } res.jsonp(json); }); }); 

Below is the code that I modified for the match matrix. I moved the entire script to $.getJSON and completely removed the d3.json function.

 <script> $.getJSON("http://localhost:8080/example?callback=?", function(result){ miserables = result; var margin = { top: 80, right: 0, bottom: 10, left: 80 }, width = 720, height = 720; var x = d3.scale.ordinal().rangeBands([0, width]), z = d3.scale.linear().domain([0, 4]).clamp(true), c = d3.scale.category10().domain(d3.range(10)); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .style("margin-left", -margin.left + "px") .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var matrix = [], nodes = miserables.nodes, n = nodes.length; // Compute index per node. nodes.forEach(function(node, i) { node.index = i; node.count = 0; matrix[i] = d3.range(n).map(function(j) { return { x: j, y: i, z: 0 }; }); }); // Convert links to matrix; count character occurrences. miserables.links.forEach(function(link) { matrix[link.source][link.target].z += link.value; matrix[link.target][link.source].z += link.value; matrix[link.source][link.source].z += link.value; matrix[link.target][link.target].z += link.value; nodes[link.source].count += link.value; nodes[link.target].count += link.value; }); // Precompute the orders. var orders = { name: d3.range(n).sort(function(a, b) { return d3.ascending(nodes[a].name, nodes[b].name); }), count: d3.range(n).sort(function(a, b) { return nodes[b].count - nodes[a].count; }), group: d3.range(n).sort(function(a, b) { return nodes[b].group - nodes[a].group; }) }; // The default sort order. x.domain(orders.name); svg.append("rect") .attr("class", "background") .attr("width", width) .attr("height", height); var row = svg.selectAll(".row") .data(matrix) .enter().append("g") .attr("class", "row") .attr("transform", function(d, i) { return "translate(0," + x(i) + ")"; }) .each(row); row.append("line") .attr("x2", width); row.append("text") .attr("x", -6) .attr("y", x.rangeBand() / 2) .attr("dy", ".32em") .attr("text-anchor", "end") .text(function(d, i) { return nodes[i].name; }); var column = svg.selectAll(".column") .data(matrix) .enter().append("g") .attr("class", "column") .attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(-90)"; }); column.append("line") .attr("x1", -width); column.append("text") .attr("x", 6) .attr("y", x.rangeBand() / 2) .attr("dy", ".32em") .attr("text-anchor", "start") .text(function(d, i) { return nodes[i].name; }); function row(row) { var cell = d3.select(this).selectAll(".cell") .data(row.filter(function(d) { return dz; })) .enter().append("rect") .attr("class", "cell") .attr("x", function(d) { return x(dx); }) .attr("width", x.rangeBand()) .attr("height", x.rangeBand()) .style("fill-opacity", function(d) { return z(dz); }) .style("fill", function(d) { return nodes[dx].group == nodes[dy].group ? c(nodes[dx].group) : null; }) .on("mouseover", mouseover) .on("mouseout", mouseout); } function mouseover(p) { d3.selectAll(".row text").classed("active", function(d, i) { return i == py; }); d3.selectAll(".column text").classed("active", function(d, i) { return i == px; }); } function mouseout() { d3.selectAll("text").classed("active", false); } d3.select("#order").on("change", function() { clearTimeout(timeout); order(this.value); }); function order(value) { x.domain(orders[value]); var t = svg.transition().duration(2500); t.selectAll(".row") .delay(function(d, i) { return x(i) * 4; }) .attr("transform", function(d, i) { return "translate(0," + x(i) + ")"; }) .selectAll(".cell") .delay(function(d) { return x(dx) * 4; }) .attr("x", function(d) { return x(dx); }); t.selectAll(".column") .delay(function(d, i) { return x(i) * 4; }) .attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(-90)"; }); } var timeout = setTimeout(function() { order("group"); d3.select("#order").property("selectedIndex", 2).node().focus(); }, 5000); }); </script> 

Note that the JSON data is now in result , so the easiest way to assign it was miserables .

Note. This solution requires jQuery.

Now you can locally open and visualize all your d3 visualizations without placing them on the server - just open them in your browser directly from the local file system.

NTN!

0
source share

All Articles