如何从文件中调用JSON而不是内联多边缘D3示例

时间:2017-05-19 18:28:48

标签: javascript json d3.js

我正在关注此示例:http://bl.ocks.org/mbostock/1153292

我有一排排的JSON数据,如下所示:

{"source":"Michael Scott","target":"Jim Halpert","type":"pro"},
{"source":"Jim Halpert","target":"Dwight Schrute","type":"pro"}

呈现此数据的当前代码如下所示:

var links = [
{"source":"Michael Scott","target":"Jim Halpert","type":"pro"},
{"source":"Jim Halpert","target":"Dwight Schrute","type":"pro"}
];

var nodes = {};

links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
  link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

var width = 2000,
height = 1000;

var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(60)
.charge(-300)
.on("tick", tick)
.start();

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

svg.append("defs").selectAll("marker")
.data(["pro"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");

var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 6)
.call(force.drag);

var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; });

function tick() {
  path.attr("d", linkArc);
  circle.attr("transform", transform);
  text.attr("transform", transform);
}

function linkArc(d) {
  var dx = d.target.x - d.source.x,
  dy = d.target.y - d.source.y,
  dr = Math.sqrt(dx * dx + dy * dy);
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

function transform(d) {
  return "translate(" + d.x + "," + d.y + ")";
}

</script>

如何从外部data.json文件调用数据?我已经查看了所有其他相关的SO问题和其他D3示例,但我还没有能够得到任何工作。

我已尝试过(然后将所有对links的引用更改为data):

d3.json("data.json", function(error, data) {
});

以下是完整代码:

<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>

d3.json("data.json", function(error, data) {
});


var nodes = {};

data.forEach(function(link) {
  link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
  link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});

var width = 2000,
height = 1000;

var force = d3.layout.force()
.nodes(d3.values(nodes))
.data(data)
.size([width, height])
.linkDistance(60)
.charge(-300)
.on("tick", tick)
.start();

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

svg.append("defs").selectAll("marker")
.data(["pro"])
.enter().append("marker")
.attr("id", function(d) { return d; })
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");

var path = svg.append("g").selectAll("path")
.data(force.data())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 6)
.call(force.drag);

var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 8)
.attr("y", ".31em")
.text(function(d) { return d.name; });

function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
text.attr("transform", transform);
}

function linkArc(d) {
var dx = d.target.x - d.source.x,
  dy = d.target.y - d.source.y,
  dr = Math.sqrt(dx * dx + dy * dy);
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

function transform(d) {
  return "translate(" + d.x + "," + d.y + ")";
}

</script>

这导致此行Uncaught Reference Error: "data" is not defined出现错误data.forEach(function(link) {data.jsonindex.html

位于同一目录中

我已经尝试了各种其他实现,我从blocks.org上的其他D3示例中选择了。任何和所有的见解将不胜感激。如果有任何我可以做的改进我的问题,请告诉我!

1 个答案:

答案 0 :(得分:2)

以下是您的数据的工作示例。您需要做一些事情才能使它与外部json文件一起使用。

  1. 请务必在d3.json来电中包含所有代码。

  2. 由于我们使用变量链接来保存我们的所有数据,因此您需要将其设置为等于data来自d3.json调用的var data_url = "https://api.myjson.com/bins/10kk91"; d3.json(data_url, function(error, data){ var links = data; //set links equal to data which is returned from d3.json var nodes = {}; // Compute the distinct nodes from the links. links.forEach(function(link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); }); var width = 960, height = 500; var force = d3.layout.force() .nodes(d3.values(nodes)) .links(links) .size([width, height]) .linkDistance(60) .charge(-300) .on("tick", tick) .start(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); // Per-type markers, as they don't inherit styles. svg.append("defs").selectAll("marker") .data(["suit", "licensing", "resolved"]) .enter().append("marker") .attr("id", function(d) { return d; }) .attr("viewBox", "0 -5 10 10") .attr("refX", 15) .attr("refY", -1.5) .attr("markerWidth", 6) .attr("markerHeight", 6) .attr("orient", "auto") .append("path") .attr("d", "M0,-5L10,0L0,5"); var path = svg.append("g").selectAll("path") .data(force.links()) .enter().append("path") .attr("class", function(d) { return "link " + d.type; }) .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); var circle = svg.append("g").selectAll("circle") .data(force.nodes()) .enter().append("circle") .attr("r", 6) .call(force.drag); var text = svg.append("g").selectAll("text") .data(force.nodes()) .enter().append("text") .attr("x", 8) .attr("y", ".31em") .text(function(d) { return d.name; }); // Use elliptical arc path segments to doubly-encode directionality. function tick() { path.attr("d", linkArc); circle.attr("transform", transform); text.attr("transform", transform); } function linkArc(d) { var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx * dx + dy * dy); return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; } function transform(d) { return "translate(" + d.x + "," + d.y + ")"; } }); //end d3.json call

  3. 检查下面的工作代码:

    .link {
      fill: none;
      stroke: #666;
      stroke-width: 1.5px;
    }
    
    #licensing {
      fill: green;
    }
    
    .link.licensing {
      stroke: green;
    }
    
    .link.resolved {
      stroke-dasharray: 0,2 1;
    }
    
    circle {
      fill: #ccc;
      stroke: #333;
      stroke-width: 1.5px;
    }
    
    text {
      font: 10px sans-serif;
      pointer-events: none;
      text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    /**
     * The same timestamp MUST appear in each fragment of a given frame.
     * The RTP marker bit MUST be set in the last packet of a frame.
     * @param[in] *udp The UDP socket to send the RTP packet over
     * @param[in] *Jpeg JPEG encoded image byte buffer
     * @param[in] JpegLen The length of the byte buffer
     * @param[in] m_SequenceNumber RTP sequence number
     * @param[in] m_Timestamp Timestamp of the image in usec
     * @param[in] m_offset 3 byte fragmentation offset for fragmented images
     * @param[in] marker_bit RTP marker bit
     * @param[in] w The width of the JPEG image
     * @param[in] h The height of the image
     * @param[in] format_code 0 for YUV422 and 1 for YUV421
     * @param[in] quality_code The JPEG encoding quality
     * @param[in] has_dri_header Whether we have an DRI header or not
     */
    static void rtp_packet_send(
      struct UdpSocket *udp,
      uint8_t *Jpeg, int JpegLen,
      uint32_t m_SequenceNumber, uint32_t m_Timestamp,
      uint32_t m_offset, uint8_t marker_bit,
      int w, int h,
      uint8_t format_code, uint8_t quality_code,
      uint8_t has_dri_header)
    {
    
    #define KRtpHeaderSize 12           // size of the RTP header
    #define KJpegHeaderSize 8           // size of the special JPEG payload header
    
      uint8_t     RtpBuf[2048];
      int         RtpPacketSize = JpegLen + KRtpHeaderSize + KJpegHeaderSize;
    
      memset(RtpBuf, 0x00, sizeof(RtpBuf));
    
      /*
       The RTP header has the following format:
    
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |V=2|P|X|  CC   |M|     PT      |       sequence number         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                           timestamp                           |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           synchronization source (SSRC) identifier            |
       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
       |            contributing source (CSRC) identifiers             |
       |                             ....                              |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       * */
    
      m_Timestamp *= 9 / 100; // convert timestamp to units of 1 / 90000 Hz
      // Prepare the 12 byte RTP header
      RtpBuf[0]  = 0x80;                               // RTP version
      RtpBuf[1]  = 0x1a + (marker_bit << 7);           // JPEG payload (26) and marker bit
      RtpBuf[2]  = m_SequenceNumber >> 8;
      RtpBuf[3]  = m_SequenceNumber & 0x0FF;           // each packet is counted with a sequence counter
      RtpBuf[4]  = (m_Timestamp & 0xFF000000) >> 24;   // each image gets a timestamp
      RtpBuf[5]  = (m_Timestamp & 0x00FF0000) >> 16;
      RtpBuf[6]  = (m_Timestamp & 0x0000FF00) >> 8;
      RtpBuf[7]  = (m_Timestamp & 0x000000FF);
      RtpBuf[8]  = 0x13;                               // 4 byte SSRC (sychronization source identifier)
      RtpBuf[9]  = 0xf9;                               // we just an arbitrary number here to keep it simple
      RtpBuf[10] = 0x7e;
      RtpBuf[11] = 0x67;
    
      /* JPEG header", are as follows:
       *
       * http://tools.ietf.org/html/rfc2435
    
        0                   1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       | Type-specific |              Fragment Offset                  |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |      Type     |       Q       |     Width     |     Height    |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       */
    
      // Prepare the 8 byte payload JPEG header
      RtpBuf[12] = 0x00;                               // type specific
      RtpBuf[13] = (m_offset & 0x00FF0000) >> 16;      // 3 byte fragmentation offset for fragmented images
      RtpBuf[14] = (m_offset & 0x0000FF00) >> 8;
      RtpBuf[15] = (m_offset & 0x000000FF);
      RtpBuf[16] = 0x00;                             // type: 0 422 or 1 421
      RtpBuf[17] = 60;                               // quality scale factor
      RtpBuf[16] = format_code;                      // type: 0 422 or 1 421
      if (has_dri_header) {
        RtpBuf[16] |= 0x40;  // DRI flag
      }
      RtpBuf[17] = quality_code;                     // quality scale factor
      RtpBuf[18] = w / 8;                            // width  / 8 -> 48 pixel
      RtpBuf[19] = h / 8;                            // height / 8 -> 32 pixel
      // append the JPEG scan data to the RTP buffer
      memcpy(&RtpBuf[20], Jpeg, JpegLen);
    
      //udp_socket_send_dontwait(udp, RtpBuf, RtpPacketSize);   // uncomment after done testing reconstruct rtp packet
    
    
    };
    struct JPEGDepay{
        int width;
        int height;
        int framerate;
        int framerate_denom;
        bool discontl;
    };