41

图库中的大多数示例都从 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 做一些事情,以便对其进行数据化,以便图表可以绑定到它。

更新

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

目前以下代码中断:

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

这导致:

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

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

4

6 回答 6

24

对于远程 data.json 替换:

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

和 :

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);
于 2013-04-02T13:35:54.340 回答
8

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

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

但是,您可以通过一个通用过程将 json 转换为数据。首先,您需要解析 json。这可以通过 javascript-standardJSON对象来完成。如果您的jsonJSON.parse(myJson)对象已经上传到客户端,请使用它来获取数据。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]});
    }
}

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

var i;
var data = [];

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

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

于 2014-02-27T21:41:52.613 回答
5

对于D3js v2v3(不确定是哪一个)。

声明你的数据集

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

doc 所述,您可以使用:

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

绑定它

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

Scott Murray 的 D3 教程#Binding data中的更多解释。

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

于 2013-04-02T13:03:23.760 回答
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 文件是“sankeygreenhouse.json”:

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

现在,在“graphData.js”中:

var graph = {
   "links": [
      {"source":"Agricultural Energy Use","target":"Carbon Dioxide","value":"1.4"},
于 2016-12-16T15:09:14.960 回答
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) {...

于 2018-06-27T17:41:16.157 回答
-2

为什么不简单地将您的 json 转换为 tsv,如 Rob所述

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

于 2015-03-21T12:08:20.127 回答