从简单的JSON字符串加载D3.js数据

时间:2013-04-02 12:56:08

标签: d3.js

图库中的大多数示例都是从TSV文件加载数据。

如何转换以下内容以使用本地json变量而不是TSV数据?

d3.tsv("data.tsv", function(error, data) {

    var myEntitiesJson = getEntitiesJson(); // <------ use this instead of "data"
    data.forEach(function(d) {
        d.frequency = +d.frequency;
    });

    x.domain(data.map(function(d) { return d.letter; }));
    y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

    ...

    svg.selectAll(".bar")
        .data(data)     // <----- bind to myEntities instead
}

据我所知,我只需要对我的entitiesJson做一些事情,以便 data-fy 它以便图表可以绑定到它。

更新

我正在取得一些进展。我从JSON插入了我的实体,图形开始呈现出新的形状。

目前以下代码中断:

svg.selectAll(".bar")
    .data(myEntities)  // <-- this is an array of objects
    .enter().append("rect")

这导致:

  

错误:属性y的值无效=“NaN”

     

错误:属性height的值无效=“NaN”

6 个答案:

答案 0 :(得分:19)

用于远程data.json 替换:

d3.tsv("data.tsv", function(error, data) {...}

with:

d3.json("data.json", function(error, data) {
    console.log(data); // this is your data
});

表示本地数据:

var myData = { {date:'2013-05-01', frequency:99},
               {date:'2013-05-02', frequency:24} };

function draw(data) {
    console.log(data); // this is your data
}

draw(myData);

答案 1 :(得分:8)

没有一种简单的方法可以对任何给定的json进行数据处理,因为并非所有json对象都是相同的形状

按形状,我的意思是数据的组织方式。例如,'{"foo" : 1, "bar" : 2}''{"names" : ["foo", "bar"], "values" : [1, 2]}'都可以用于存储相同的数据,但是一个将所有内容存储在一个对象中,其中对象键对应于数据点的名称,一个使用单独的数组存储名称和值,相应的条目具有公共数组索引。

然而,您可以通过一般的进程将json转换为数据。首先,你需要解析你的json。这可以使用javascript标准JSON对象完成。使用JSON.parse(myJson)从json对象获取数据(如果已经上传到客户端)。 d3.json(my/json/directory, fn(){})可以加载和解析你的json,所以如果你从服务器的其他地方加载它,这可能是让json进入对象的更好方法。

将json打包到javascript对象后,仍然需要对其进行数据处理,这将取决于您的数据。它期望的d3是某种形式的数组:[dataPoint1, dataPoint2, ...]。对于我上面给出的两个例子,你想要的数组看起来像这样:

[{'name' : 'foo', 'value' : 1}, {'name' : 'bar', 'value' : 2}]

我的数组中每个数据点都有一个元素,有两个属性:valuename。 (在您的示例中,您需要属性letterfrequency

对于我的每个例子,我都会使用不同的函数来创建数组。有了这条共同点:

var rawData = JSON.parse(myJson);

我的第一个json可以用这个函数打包:

var key;
var data = [];

for(key in rawData){
    if(rawData.hasOwnProperty(key)){
        data.push({'name' : key, 'value' : rawData[key]});
    }
}

对于第二个示例,我想循环遍历对象namesvalues的每个属性。我的代码可能如下所示:

var i;
var data = [];

for(i = 0; i < rawData.names.length; i++){
    data.push({'name' : rawData.names[i], 'value' : rawData.values[i]});
}

这两个版本都会产生我原始JSON的数据版本,然后我可以在d3中使用。

答案 2 :(得分:5)

适用于D3js v2v3(不确定哪一个)。

声明您的数据集

var dataset = { 
    "first-name": "Stack",
    "last-name": "Overflow",
}; // JSON object
var dataset = [ 5, 10, 15, 20, 25 ]; // or array

作为stated by the doc,您可以使用:

  

数组或对象的数组,或返回值数组的函数

绑定

d3.select("body").selectAll("p")
    .data(dataset)
    .enter()
    .append("p")
    .text("New paragraph!");

Scott Murray's D3's tutorial#Binding data的更多解释。

data()函数适用于选择,更多信息可以在官方文档中找到:selection.data([values[, key]])

答案 3 :(得分:1)

您可以将json更改为将数据分配给全局值的javascript文件。以https://bl.ocks.org/d3noob/5028304为例:

自:

<script>
.....
// load the data
d3.json("sankeygreenhouse.json", function(error, graph) {

    var nodeMap = {};
    graph.nodes.forEach(function(x) { nodeMap[x.name] = x; });

要:

<script src="graphData.js"></script>
<script>
.....
    var nodeMap = {};
    graph.nodes.forEach(function(x) { nodeMap[x.name] = x; });

请注意,我们已取消了对回调的需求。

json文件是&#34; sankeygreenhouse.json&#34;:

{
"links": [
  {"source":"Agricultural Energy Use","target":"Carbon Dioxide","value":"1.4"},

现在,在&#34; graphData.js&#34;:

var graph = {
   "links": [
      {"source":"Agricultural Energy Use","target":"Carbon Dioxide","value":"1.4"},

答案 4 :(得分:0)

只需将数据更改为这样的对象数组:

let data = [{"apples":53245,"oranges":200},{"apples":28479,"oranges":200},{"apples":19697,"oranges":200},{"apples":24037,"oranges":200},{"apples":40245,"oranges":200}]

并注释掉d3.tsv("data.tsv", function(error, data) {...

答案 5 :(得分:-1)

为什么不按照Rob here所描述的那样简单地将你的json转换为tsv?

d3期望数据或以另一种方式说需要特定格式的数据:tsv。解决问题的最简单方法是将数据从json格式化为tsv,这可以使用Rob的注释轻松完成。