Загрузка данных D3.js из простой строки JSON
Большинство примеров в данных загрузки галереи из 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
}
Насколько я могу судить, мне просто нужно что-то сделать для своих сущностей Json, чтобы data-fy, чтобы диаграмма могла привязываться к ней.
UPDATE
Я продвигаюсь вперед. Я подключил свои сущности от JSON, и график начинает принимать новую форму.
В настоящее время разрывается следующий код:
svg.selectAll(".bar")
.data(myEntities) // <-- this is an array of objects
.enter().append("rect")
Это вызывает:
Ошибка: недопустимое значение для атрибута y = "NaN"
Ошибка: недопустимое значение для высоты атрибута = "NaN"
Ответы
Ответ 1
для удаленного 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);
Ответ 2
Существует не простой способ передачи данных по любому json, поскольку не все объекты json имеют одинаковую форму.
По форме я имею в виду способ организации данных. Например, для хранения одних и тех же данных могут использоваться как '{"foo" : 1, "bar" : 2}'
, так и '{"names" : ["foo", "bar"], "values" : [1, 2]}'
, но каждый хранит все в объекте, в котором ключи объекта соответствуют именам точек данных, а один использует отдельные массивы для хранения имен и значений, с соответствующими записями, имеющими общий индекс массива.
Существует, однако, общий процесс, который вы можете пройти, чтобы превратить json в данные. Во-первых, вам нужно проанализировать ваш json. Это можно сделать с помощью стандартного javascript-объекта JSON
. USe 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}]
У меня есть один элемент в моем массиве для каждой точки данных с двумя атрибутами: value
и name
. (В вашем примере вам нужны атрибуты letter
и frequency
)
Для каждого из моих примеров я бы использовал другую функцию для создания массива. С этой общей чертой:
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.
Ответ 3
Для D3js
v2
или v3
(не уверен, какой).
Объявите свой набор данных
var dataset = {
"first-name": "Stack",
"last-name": "Overflow",
}; // JSON object
var dataset = [ 5, 10, 15, 20, 25 ]; // or array
Как указанный в документе, вы можете использовать либо:
массив чисел или объектов или функция, возвращающая массив значений
Привязать его
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("New paragraph!");
Больше объяснений в Учебник Scott Murray D3 # Связывание данных.
Функция data() применяется к выбору, дополнительную информацию можно найти в официальной документации: selection.data([values [, key]]).
Ответ 4
Вы можете изменить json в файл javascript, который присваивает данные глобальному значению. В качестве примера возьмем https://bl.ocks.org/d3noob/5028304:
From:
<script>
.....
// load the data
d3.json("sankeygreenhouse.json", function(error, graph) {
var nodeMap = {};
graph.nodes.forEach(function(x) { nodeMap[x.name] = x; });
To:
<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"},
Ответ 5
Почему бы просто не преобразовать json в tsv, как описано Rob здесь?
d3 ожидает, что данные или, по другому, нуждаются в данных в определенном формате: tsv. Самый простой способ решить вашу проблему - просто форматировать ваши данные от json до tsv, что можно легко сделать с помощью комментариев Rob.