关于javascript:D3条形图示例不在本地工作

D3 Bar Graph example not working locally

我对d3非常陌生,想看看一个例子如何在本地工作。我复制并粘贴了条形图代码到一个名为index.html的本地文件中,还复制了data.tsv。出于某种原因,当我在浏览器上打开文件时,绝对不会显示任何内容!我尝试将脚本src更改为"d3/d3.v3.min.js",因为这是我下载的d3所在的文件夹。然而,这也不起作用。对于我尝试过的每个示例,我都还没有成功地查看D3示例。我们将感谢您的帮助!

index.html代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<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">


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

data.tsv的格式如下:字母频率一点零八一六七B . 01492C 02780D 04253E. 12702F 02288g 02022H 06094我06973


d3.tsv方法发出Ajax数据请求。在大多数浏览器上,由于相同的源站策略,这在本地无法工作,因为该策略通常禁止Ajax对file:///URL的请求。

要获得一个使用本地运行的Ajax的示例,您需要一个本地Web服务器。如果你有Python,跑步

1
> python -m SimpleHTTPServer

从目录中的命令行和您的文件中就可以做到这一点。

如果您使用的是python 3

1
> python -m http.server 9000

如果您喜欢node.js,请尝试http服务器。


作为另一种选择,我是Lars Kotthoff在尝试使用.tsv/.csv文件时建议的,您可以直接为此工作:

网址:http://plnkr.co/

这使您能够处理所有您喜欢的.json/.tsv/.csv文件,并与人们共享这些文件进行协作。你可以匿名或者不匿名,重要的是你不会丢失你劫掠者的HTTP地址。

需要注意的一点是:您不能像在ftp服务器上那样直接上载文件,但您应该这样做:

  • 点击"新建文件"
  • 键入.csv/.tsv/.json的名称。代码中引用的文件(包括扩展名)
  • 拷贝并按原样粘贴此文件中包含的代码。
  • 别忘了如果需要,更新.css/.js的名称,以便与您的index.html

  • 如前所述,对于解析JSON数据的外部资源,您很可能会遇到D3库中XHR的CORS问题。

    但是,这里还有另一个解决方案:将jsonp和express/node.js与jquery函数结合使用来启动json的客户端请求,而不是使用D3函数的原始包装器。

    必须删除原来的d3.json包装器,并用来自请求的数据填充邻接图。首先克隆或下载jsonp-d3-experiment,然后使用node server.js启动服务器。当然,您需要在全局安装node.js,从node packaged modules(NPM)开始。将程序复制到子目录中。

    将您的JSON数据放在JSONP-D3-Experiment目录中,并修改server.js以将请求路由到您的数据:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 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);
      });
    });

    下面是我为共现矩阵修改的代码。我把整个脚本移入了$.getJSON,并完全删除了d3.json函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
        $.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);
          });

    注意,现在JSON数据在result中,所以最简单的事情就是将其分配给miserables

    注意:此解决方案需要jquery。

    现在,您应该能够在本地打开和呈现所有的d3可视化,而不需要将它们托管在服务器上——只需直接从本地文件系统在浏览器中打开它们。

    嗯!