D3 Bar Graph example not working locally

前端 未结 3 1034
灰色年华
灰色年华 2020-11-27 21:09

I am very new to D3, and wanted to see how an example would work locally. I copied and pasted the bar graph code to a local file called index.html, and also copied over the

相关标签:
3条回答
  • 2020-11-27 21:35

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

    http://plnkr.co/

    This enables you to work with all the .json / .tsv / .csv files you like, and share them with people for collaboration. You can do this anonymously or not, what matters is that you don't lose the then-generated HTTP address of your plunker.

    One thing to pay attention to: you cannot upload directly the files in the way you would do on an FTP server, but you should instead:

    1. Click on "new file"
    2. Type the name of your .csv / .tsv / .json file as referred to in your code (including the extension)
    3. Copy and paste the code contained in this file as is.
    4. Don't forget to update the names of your .css / .js if required so the match with that of your index.html
    0 讨论(0)
  • 2020-11-27 21:48

    The d3.tsv method makes an AJAX request for data. On most browsers, this won't work locally due to the Same Origin Policy, which generally prohibits AJAX requests to file:/// urls.

    To get an example that uses AJAX running locally, you'll need a local webserver. If you have Python, running

    > python -m SimpleHTTPServer
    

    from the command line in the directory with your files will do it.

    and if you are using python 3

    > python -m http.server 9000
    

    If you prefer node.js, try http-server.

    0 讨论(0)
  • 2020-11-27 21:54

    As already stated, you're most likely encountering a CORS issue with the XHR in the d3 library for an external resource to parse the JSON data.

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

    Had to remove the original d3.json wrapper and populate the adjacency diagrams with data from the request. Begin by cloning or downloading jsonp-d3-experiment and start the server using node server.js. Of course you need to have Node.js installed globally, beginning with Node Packaged Modules (npm). Copy your program into a subdirectory.

    Put your JSON data in the jsonp-d3-experiment directory and modify server.js to route 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 I modified for a co-occurrence matrix. I moved the entire script into $.getJSON and removed the d3.json function altogether.

    <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 d.z;
                }))
                .enter().append("rect")
                .attr("class", "cell")
                .attr("x", function(d) {
                  return x(d.x);
                })
                .attr("width", x.rangeBand())
                .attr("height", x.rangeBand())
                .style("fill-opacity", function(d) {
                  return z(d.z);
                })
                .style("fill", function(d) {
                  return nodes[d.x].group == nodes[d.y].group ? c(nodes[d.x].group) : null;
                })
                .on("mouseover", mouseover)
                .on("mouseout", mouseout);
            }
    
            function mouseover(p) {
              d3.selectAll(".row text").classed("active", function(d, i) {
                return i == p.y;
              });
              d3.selectAll(".column text").classed("active", function(d, i) {
                return i == p.x;
              });
            }
    
            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(d.x) * 4;
                })
                .attr("x", function(d) {
                  return x(d.x);
                });
    
              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>
    

    Notice that now the JSON data is in result, so the easiest thing to do was to assign it to miserables.

    Note: jQuery is required for this solution.

    Now you should be able to locally open and render all your d3 visualizations without hosting them on a server--simply open them in your browser straight from your local filesystem.

    HTH!

    0 讨论(0)
提交回复
热议问题