Создать (многоуровневый) формат данных flare.json от плоского json

У меня есть плоская файловая структура json, например:

[
 { "name" : "ABC", "parent":"DEF", "relation": "ghi", "depth": 1 },
 { "name" : "DEF", "parent":"null", "relation": "null", "depth": 0 },
 { "name" : "new_name", "parent":"ABC", "relation": "rel", "depth": 2 }
 ....
 ....
 ]

И то, что я хочу, это вложенная файловая структура, например:

[ 
 {
   "name": "DEF",
   "parent": "null",
   "relation": "null",
   "children": [
                 { "name": "ABC",
                   "parent": "DEF",
                   "relation": "ghi",
                   "children": [
                                 "name": "new_name",
                                 ...
                                 "children": []
                               ]
                 }
               ]
  }
 ]

Нет предела тому, сколько уровней должно пройти. Ток max у меня равен 30. Нет ограничений на количество детей, которые могут иметь a node. Например. Корень node имеет все остальные в качестве своих дочерних элементов.

Что я пробовал до сих пор?

  • Читайте о d3.nest() и о том, как он может гнездиться, но не идеально. https://groups.google.com/forum/?fromgroups=#!topic/d3-js/L3UeeUnNHO8/discussion

  • Написал для этого python script, но он застрял с нулевыми значениями, а также потому, что данные не ограничены (каждый день увеличивается вдвое), поэтому он очень медленный.

  • Я пробовал настройку с направленной силой, и она работала очень хорошо, но я хочу добавить еще один макет, который упрощает визуализацию.

  • Я мог бы пойти с некоторыми другими скриптами python, но они, похоже, не переносят другую информацию, кроме "имя" и "дети".

  • Я читал это: http://blog.pixelingene.com/2011/07/building-a-tree-diagram-in-d3-js/ но они также имеют правильные данные формата в первую очередь. То, что я намереваюсь создать, http://bl.ocks.org/mbostock/4339083.

Источником данных является база данных MS SQL Server, которую я извлекаю и обрабатываю через python. Пожалуйста, помогите! я застрял в этом в течение последних 2 недель.

Спасибо

Ответ 1

Здесь одна реализация, в Javascript: http://jsfiddle.net/9FqKS/

Вы начинаете с создания карты на основе имени для удобного поиска. Существует несколько различных способов сделать это: в этом случае я использую метод .reduce, который начинается с пустого объекта и выполняет итерацию по массиву data, добавляя запись для каждого node:

// create a {name: node} map
var dataMap = data.reduce(function(map, node) {
    map[node.name] = node;
    return map;
}, {});

Это эквивалентно:

var dataMap = {};
data.forEach(function(node) {
    dataMap[node.name] = node;
});

(Я иногда думаю, что сокращение более элегантное.) Затем итеративно добавьте каждый дочерний элемент к родителям или корневому массиву, если не найдено ни одного родителя:

// create the tree array
var tree = [];
data.forEach(function(node) {
    // find parent
    var parent = dataMap[node.parent];
    if (parent) {
        // create child array if it doesn't exist
        (parent.children || (parent.children = []))
            // add node to parent child array
            .push(node);
    } else {
        // parent is null or missing
        tree.push(node);
    }
});

Если ваше дерево не огромно, я не думаю, что это должно быть слишком дорого, поэтому вы должны иметь возможность делать это на стороне клиента (если вы не можете, у вас может быть слишком много данных, в любом случае).