d3js> Ленивая загрузка данных по требованию - PullRequest
0 голосов
/ 24 октября 2018

В настоящее время я использую Роба d3js «сворачиваемое дерево» для визуализации отношений данных (пока все хорошо!).

Это хорошо работает со статическими данными, однако яхотелось бы динамически извлекать и загружать «дочерние» отношения, когда конечный узел разворачивается (/clicked).

например,

Когда rootраскрывается, и ProjectA раскрывается, и пользователь щелкает дочерний элемент ProjectB, затем дочерние элементы ProjectB (динамически) загружаются и отображаются (и т. д.).

Причиныжелая такого поведения:

  • уменьшение предварительной загрузки больших / сложных структур данных
  • рендеринг круговых структур данных

Я сейчас читаю d3js API Docs , но я все равно не вижу:

  • , указывающего динамический источник данных (например, функция, которая предоставляет родителя, возвращает потомков)
  • добавление дочерних узлов на основе события

Любые указатели приветствуются!

Пример / WIP: https://jsbin.com/davetij/edit?js,output

1 Ответ

0 голосов
/ 24 октября 2018

Решил, решение оказалось проще, чем я думал.

Я создал функцию lazyLoadChildren(..) для динамического заполнения дочерних узлов (на основе узла name) ...

то есть

const childrenLookup = {
    ProjectA: [
        {"name":"FOO"},
        {"name":"BAR"},
        {"name":"CAT"},
        {"name":"ProjectB"}
    ],
    ProjectB: [
        {"name":"FOO"},
        {"name":"BAR"},
        {"name":"CAT"},
        {"name":"ProjectA"}
    ]
}

const lazyLoadChildren = d => {
    const dynamicChildren = childrenLookup[d.name]
    if (isNotPresent(d.children) && isNotPresent(d._children) && isPresent(dynamicChildren)) {
        d.children = deepCopy(dynamicChildren)
    }
}

... затем я вызывал его для каждого дочернего элемента узла всякий раз, когда вызывалась функция expand(..) ...

т.е.

function expand(d, recurseFlag) {
    if (d._children) {
        d.children = d._children;
        // lazy load all children (collapsed)
        d.children.forEach(x => {
            lazyLoadChildren(x)
            collapse(x)
        })
        if (recurseFlag === true) {
            d._children.forEach(x => expand(x, recurseFlag));
        }
        d._children = null;
    }
}

Вот полный пример: https://jsbin.com/davetij/edit?output

...