2014-02-03 3 views
10

Проблема, с которой я столкнулся с использованием реализации d3 sankey, заключается в том, что нет способа указать, где на оси x находится узел. Я прорывался через источник, и на самом деле нет «чистого» способа указать значение x в разумном масштабе (например, 1-5, где ширина карты - 5 узлов). Я создаю что-то, что можно использовать как плановик курса для обучения, поэтому значение x будет соответствовать семестру. Предположим, что у меня был курс, который я не мог взять до своего второго курса в колледже, это было бы на уровне х 3 (1/2 - первокурсник, 3/4 второкурсник и т. Д.). Проблема в том, что если нет ничего, что связано с этим курсом заранее, оно всегда будет на x из 1, поэтому я хотел бы нажать его вправо двумя пробелами.d3 диаграммы sankey - узел позиции вручную вдоль оси x

Я заметил, что значение x в фактической диаграмме sankey не отражает количество узлов на нем, поэтому это немного сложно сделать.

Я также столкнулся с this question, и я понимаю, что по умолчанию диаграмма не позволит мне позиционировать узел. У меня нет проблем с настройкой примера sankey.js, чтобы выполнить это, но в настоящее время я придерживаюсь того, как это сделать.

+0

Существует билет на это: https://github.com/d3/d3-plugins/issues/88 – Thilo

+0

Спасибо, что открыли его @ Тило! – Seiyria

ответ

14

Это возможно. См. Это JSFiddle.

enter image description here

computeNodeBreadths функция в sankey.js может быть модифицирована, чтобы искать явные х позиции, который был назначен на узел (node.xPos):

function computeNodeBreadths() { 
    var remainingNodes = nodes, 
     nextNodes, 
     x = 0; 

    while (remainingNodes.length) { 
     nextNodes = []; 
     remainingNodes.forEach(function(node) { 

     if (node.xPos) 
      node.x = node.xPos; 
     else 
      node.x = x; 

     node.dx = nodeWidth; 
     node.sourceLinks.forEach(function(link) { 
      nextNodes.push(link.target); 
     }); 
     }); 
     remainingNodes = nextNodes; 
     ++x; 
    } 

    // 
    moveSinksRight(x); 
    scaleNodeBreadths((width - nodeWidth)/(x - 1)); 
    } 

Тогда все, что вы необходимо указать xPos на нужных узлах. В приведенном выше примере я установил xPos = 1 на node2. См GetData() в примере JSFiddle:

... }, { 
     "node": 2, 
     "name": "node2", 
     "xPos": 1 
    }, { ... 
+0

Спасибо. Я попробовал это, но я думаю, мне нужно было сделать еще несколько настроек в моем наборе данных, чтобы он действительно работал. Ваш пример подтвердил это и очень помог мне! – Seiyria

+0

@ Грег Росс - спасибо за решение. Есть ли способ настроить раковины, чтобы НЕ быть на правой стороне svg? Я заметил, что не могу переопределить позицию узла 3 в JSFiddle: http://jsfiddle.net/88Akd/. Спасибо. – NickBraunagel

+2

Эй @ НикБраунагель - Хорошее место. Если вы закомментируете 'moveSinksRight (x);' в строке 137 в скрипаче, вы можете разместить узел приемника, где хотите. –

3

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

sankey.layout = function(iterations) { 
    computeNodeLinks(); 
    computeNodeValues(); 
    computeNodeBreadths(); 
    computeNodeDepths(iterations); 
    computeAbsolutePositions(); // add this in sankey.js file 
    computeLinkDepths(); 
    return sankey; 
}; 

И добавить сами позиции:

function computeAbsolutePositions() { 
    nodes[0].x = 0; 
    nodes[0].y = 0; 
    nodes[1].x = 260; 
    nodes[1].y = 0; 
}; 

Пожалуйста, обратите внимание, что вы должны будете сам против позиции прямоугольников, когда вы жёстко их так, как и контрольных функции ни столкновений, первоначально используемых sankey.js используются в это пример.

Надеюсь, что это может помочь кому-то!

1

Назовем координату x layer. layer=0 будет левым краем, а layer=n будет правильным краем. В файле JSON в поле nodes добавьте пару ключ-значение layer: your_desired_x_as_integer.

Затем зайдите в файл sankey.js и найдите функцию componentsByBreadth.forEach. Заменить строку node.x = component.x + node.x; с:

if (node.layer) node.x=node.layer; 
else node.x = component.x + node.x; 

Вы можете определить плотность слоев, как это также, например, узлы, размещенные на слоях 0,1,2 или 0,4,8, будут иметь центральный узел и два по краям ширины санки, но 0,1,5 не будут иметь.

Если вам нужна дополнительная помощь, эта особенность, среди многих других входит в мое приложение D3 Сэнки: http://sankey.csaladen.es

Смежные вопросы