D3 диаграммы sankey - положение вручную node вдоль оси x

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

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

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

Ответ 1

Это возможно. Смотрите JSFiddle.

enter image description here

Функция computeNodeBreadths в sankey.js может быть изменена для поиска явной позиции x, которая была назначена node (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
    }, { ...

Ответ 2

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

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.

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

Ответ 3

Назовем 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, будут иметь центральный node и два по краям ширины санки, но 0,1,5 не будут иметь.

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

Ответ 4

может не быть чистым ответом, после которого вы можете явно изменить исходные и целевые атрибуты x, а затем обновить ссылки

http://bl.ocks.org/danharr/af796d91926d254dfe99