Как я могу использовать данные дерева D3 в VEGA Api?

#javascript #d3.js #vega

#javascript #d3.js #вега

Вопрос:

Я пытаюсь отобразить данные дерева D3 с помощью Vega API.

В документации по дереву Vega указано, что Vega использует иерархию дерева d3. Это говорит о том, что это должно быть возможно. Страница Vega даже содержит ссылку на иерархию D3, которая выглядит следующим образом:

 {
"name": "Eve",
  "children": [
    {
      "name": "Cain"
    },
    {
      "name": "Seth",
      "children": [
        {
          "name": "Enos"
        },
        {
          "name": "Noam"
        }
      ]
    },
    {
      "name": "Abel"
    },
    {
      "name": "Awan",
      "children": [
        {
          "name": "Enoch"
        }
      ]
    },
    {
      "name": "Azura"
    }
  ]
}
 

Но использование этого непосредственно в древовидной диаграмме Vega не работает.

Собственный пример дерева Vega включает в себя файл данных, который действительно работает, но формат данных выглядит совершенно иначе. Есть ли способ преобразовать иерархию данных D3 в формат, который поддерживает Vega? В документах Vega говорится о преобразованиях, но я не могу найти пример.

Требуемый формат Vega выглядит следующим образом. Он использует идентификаторы, чтобы узнать, кто является родительским узлом, вместо вложенных массивов.

 [
{
    "id": 1,
    "name": "flare"
},
{
    "id": 2,
    "name": "analytics",
    "parent": 1
},
{
    "id": 3,
    "name": "cluster",
    "parent": 2
},
{
    "id": 4,
    "name": "AgglomerativeCluster",
    "parent": 3,
    "size": 3938
},
{
    "id": 5,
    "name": "CommunityStructure",
    "parent": 3,
    "size": 3812
}
 

Как я могу использовать древовидные данные в формате D3 в Vega?

Ответ №1:

Я не пробовал это с Vega, но вы можете преобразовать иерархию с помощью небольшой вспомогательной функции следующим образом:

 data = {
"name": "Eve",
  "children": [
    {
      "name": "Cain"
    },
    {
      "name": "Seth",
      "children": [
        {
          "name": "Enos"
        },
        {
          "name": "Noam"
        }
      ]
    },
    {
      "name": "Abel"
    },
    {
      "name": "Awan",
      "children": [
        {
          "name": "Enoch"
        }
      ]
    },
    {
      "name": "Azura"
    }
  ]
};

console.log(flatten(data));

function flatten(hierarchy) {
  let ar = [];
  let i = 0;
  
  let hierarchyWithID = d3.hierarchy(hierarchy).each(d => d.id = i  );
  
  ar = hierarchyWithID.descendants().map(d => {
    let obj = {};
    obj.name = d.data.name;
    obj.id = d.id;
    if (d.parent) { obj.parent = d.parent.id;}
    if (d.size) { obj.size = d.size;}
    return obj;
  });
  
  return ar;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> 

или, альтернативно, версия без функций из d3.js (присвоение разных идентификаторов):

 data = {
"name": "Eve",
  "children": [
    {
      "name": "Cain"
    },
    {
      "name": "Seth",
      "children": [
        {
          "name": "Enos"
        },
        {
          "name": "Noam"
        }
      ]
    },
    {
      "name": "Abel"
    },
    {
      "name": "Awan",
      "children": [
        {
          "name": "Enoch"
        }
      ]
    },
    {
      "name": "Azura"
    }
  ]
};

console.log(flatten2(data));

function flatten2(obj) {
  let id = 0;
  return _flatten2(obj);

  function _flatten2(obj, ar = [], parentID = -1) {
    let node = {};
      node.id = id  ;
      node.name = obj.name;
      if (parentID !== -1) { node.parent = parentID;}
      if (obj.size) { node.size = obj.size;}
      ar.push(node);

      if (obj.children) {
        for (let child of obj.children) {
          _flatten2(child, ar, node.id);
        }
      }
    return ar;
  }
} 

Комментарии:

1. Можно ли преобразовать данные без необходимости загрузки скрипта D3?

2. Я только что добавил функцию, основанную на обычном javascript