L'exemple de graphique à barres D3 ne fonctionne pas localement

Je suis très nouveau pour D3 et je voulais voir comment un exemple fonctionnerait localement. J'ai copié et collé le code graphique de barre dans un fichier local appelé index.html, et j'ai également copié sur data.tsv. Pour une raison quelconque, absolument rien ne s'affiche lorsque j'ouvre le fichier sur un navigateur! J'ai essayé de changer le script src en "d3 / d3.v3.min.js" car c'est le dossier que j'ai téléchargé. Cependant, cela ne fonctionne pas non plus. Pour chaque exemple que j'ai essayé, je n'ai pas encore vérifié avec succès un exemple D3. L'aide serait appréciée!

Le code index.html est le suivant:

<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> 

Et le data.tsv est dans le format suivant: fréquence de la lettre A .08167 B .01492 C .02780 D .04253 F .07092 F .02288 G .02022 H .06094 I .06973

La méthode d3.tsv effectue une requête AJAX pour les données. Sur la plupart des navigateurs, cela ne fonctionnera pas localement en raison de la même politique d'origine , qui interdit généralement les requêtes AJAX de file:/// urls.

Pour obtenir un exemple qui utilise AJAX en cours d'exécution local, vous aurez besoin d'un serveur Web local. Si vous avez Python, en cours d'exécution

 > python -m SimpleHTTPServer 

À partir de la ligne de commande dans le répertoire, vos fichiers le feront. Si vous préférez node.js, essayez http-server .

Comme alternative, et je l'ai été suggéré par Lars Kotthoff lors de la tentative de travailler avec les fichiers .tsv / .csv, vous pouvez travailler directement à cet effet sur:

http://plnkr.co/

Cela vous permet de travailler avec tous les fichiers .json / .tsv / .csv que vous aimez et de les partager avec des personnes pour la collaboration. Vous pouvez le faire de manière anonyme ou non, ce qui compte, c'est que vous ne perdez pas l'adresse HTTP générée à l'origine de votre plunker.

Une chose à faire attention: vous ne pouvez pas télécharger directement les fichiers comme vous le feriez sur un serveur FTP, mais vous devriez plutôt:

  1. Cliquez sur "nouveau fichier"
  2. Tapez le nom de votre fichier .csv / .tsv / .json tel que mentionné dans votre code (y compris l'extension)
  3. Copiez et collez le code contenu dans ce fichier tel quel.
  4. N'oubliez pas de mettre à jour les noms de vos .css / .js si nécessaire pour que la correspondance avec celle de votre index.html

Comme vous l'avez déjà indiqué, vous rencontrez probablement un problème de CORS avec le XHR dans la bibliothèque d3 pour une ressource externe pour analyser les données JSON.

Cependant, voici une autre solution: utilisez JSONP et Express / Node.js en conjonction avec une fonction jQuery pour lancer une demande côté client pour JSON, au lieu d'utiliser le wrapper d'origine pour les fonctions d3.

A dû supprimer l'enveloppe originale d3.json et remplir les diagrammes d'adjacence avec les données de la demande. Commencez par cloner ou télécharger jsonp-d3-experiment et démarrer le serveur en utilisant node server.js . Bien sûr, vous devez installer Node.js globalement, en commençant par Node Packaged Modules (npm). Copiez votre programme dans un sous-répertoire.

Mettez vos données JSON dans l'annuaire jsonp-d3-experiment et modifiez server.js pour acheminer la demande vers vos données:

 // 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); }); }); 

Voici le code que j'ai modifié pour une matrice de co-occurrence. J'ai déplacé le script entier en $.getJSON et $.getJSON supprimé d3.json fonction d3.json .

 <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> 

Notez que maintenant les données JSON sont en result , donc la chose la plus simple à faire était de l'affecter à des miserables .

Remarque: jQuery est requis pour cette solution.

Maintenant, vous devriez pouvoir ouvrir et publier toutes vos visualisations d3 sans les héberger sur un serveur – simplement les ouvrir dans votre navigateur directement à partir de votre système de fichiers local.

HTH!