включить горизонтальное перемещение узлов на графиках sankeyNetwork networkD3 - PullRequest
0 голосов
/ 09 сентября 2018

Я нашел это изображение из Интернета ( ссылка ), и я думаю, что оно было нарисовано в R. Я попытался воспроизвести этот рисунок и сделать его более или менее похожим на один из приведенных выше ссылок. Код, который я использовал, выглядит следующим образом:

    ID <- 0:24
    NodeGroup <- c(rep(1,8),2,5,rep(4,7),3,5,6,6,7,7,8,9)
    name <- c("29581k","5279k","4218k","1917k","1356k","Ventas diversas: 116","Venta diversa: 97","Venta de: 141","Venta totales: 42705","Contribucion marginal: 18183", "17531k","1744k","1326k","1208k","526k","459k","14k","IIBB: 1714","Costo: 22808","Gastos directos: 6734","Gastos distribudos: 2958","Resultado: 8851","Total Gastos: 9332","Imp. Gcias: 3098","Resultado Netto: 5.753")      

    nodes <- data.frame(ID, name, NodeGroup)
    nodes$NodeGroup <- as.character(nodes$NodeGroup)
    source <- c(0:7, rep(8,9), 10:16, rep(9,3), 19, 20, 21, 21)
    target <- c(rep(8,8), 17, 10:16, 9, rep(18,7), 19:21, rep(22, 2), 23, 24)
    value <- c(29581,5279,4218,1917,1356,116,97,141,1714,17531,1744,1326,1208,526,459,14,18138,17531,1744,1326,1208,526,459,14,6374,2958,8851,6374,2958,3098,5753)
    group <- c(1:8, rep(9,8), 10, rep(19,7), rep(18,3), rep(23,2), rep(22,2))
    links <- data.frame(source, target, value, group)
    links$group <- as.character(links$group)
    sn <- sankeyNetwork(Links=links, Nodes=nodes, Source='source', Target='target',
                Value='value', NodeID='name', fontSize=18, 
                NodeGroup = "NodeGroup",
                sinksRight = FALSE, 
                LinkGroup = "group",
                #nodeWidth = 40,
                #width=1500, height=500,
                #margin = list("right"=250),
                iterations = FALSE)
     sn

Из этой ссылки можно изменить положение узла не только по вертикали, но и по горизонтали. Можем ли мы реализовать это в R?

Обновление 1: я могу решить вопрос, заданный в вопросе 2, изменив исходный код sankeyNetwork.js, используя код, предоставленный по этим ссылкам . Я не знаю, как реализовать это через htmlwidgets (я не знаком с JS; следовательно, просто делайте проб и ошибок!). Мне просто нужно скопировать следующий код в конец sankeyNetwork.js.

function dragmove(d) {
    d3.select(this).attr("transform", 
        "translate(" + (
           d.x = Math.max(0, Math.min(width - d.dx, d3.event.x))
           ) + "," + (
           d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))
           ) + ")");
    sankey.relayout();
    link.attr("d", path);
}

1 Ответ

0 голосов
/ 10 сентября 2018

Чтобы включить горизонтальное перемещение узлов вместе с вертикальным перемещением, вы можете адаптировать код d3noob к работе, но это не так просто, как просто добавить объявление функции dragmove.

  1. Он был написан с использованием D3v3, а networkD3 использует D3v4 ... и они не полностью совместимы.
  2. Эта функция относится к группе объектов, которые определены в другом месте, поэтому сама функция не может работать, не зная, что это: width, height, sankey, link и path .

Вот один из способов приспособить его к работе ...

library(networkD3)
library(htmlwidgets)

ID <- 0:24
NodeGroup <- c(rep(1,8),2,5,rep(4,7),3,5,6,6,7,7,8,9)
name <- c("29581k","5279k","4218k","1917k","1356k","Ventas diversas: 116",
          "Venta diversa: 97","Venta de: 141","Venta totales: 42705",
          "Contribucion marginal: 18183", "17531k","1744k","1326k","1208k",
          "526k","459k","14k","IIBB: 1714","Costo: 22808",
          "Gastos directos: 6734", "Gastos distribudos: 2958","Resultado: 8851",
          "Total Gastos: 9332","Imp. Gcias: 3098","Resultado Netto: 5.753")      

nodes <- data.frame(ID, name, NodeGroup)
nodes$NodeGroup <- as.character(nodes$NodeGroup)
source <- c(0:7, rep(8,9), 10:16, rep(9,3), 19, 20, 21, 21)
target <- c(rep(8,8), 17, 10:16, 9, rep(18,7), 19:21, rep(22, 2), 23, 24)
value <- c(29581,5279,4218,1917,1356,116,97,141,1714,17531,1744,1326,1208,526,
           459,14,18138,17531,1744,1326,1208,526,459,14,6374,2958,8851,6374,
           2958,3098,5753)
group <- c(1:8, rep(9,8), 10, rep(19,7), rep(18,3), rep(23,2), rep(22,2))
links <- data.frame(source, target, value, group)
links$group <- as.character(links$group)
sn <- sankeyNetwork(Links=links, Nodes=nodes, Source='source', Target='target',
                    Value='value', NodeID='name', fontSize=18, 
                    NodeGroup = "NodeGroup",
                    sinksRight = FALSE, 
                    LinkGroup = "group",
                    #nodeWidth = 40,
                    #width=1500, height=500,
                    #margin = list("right"=250),
                    iterations = FALSE)

onRender(sn,
         '
  function(el, x) {
    var sankey = this.sankey;
    var path = sankey.link();
    var nodes = d3.selectAll(".node");
    var link = d3.selectAll(".link")
    var width = el.getBoundingClientRect().width - 40;
    var height = el.getBoundingClientRect().height - 40;

    window.dragmove = function(d) {
      d3.select(this).attr("transform", 
        "translate(" + (
           d.x = Math.max(0, Math.min(width - d.dx, d3.event.x))
            ) + "," + (
            d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))
          ) + ")");
      sankey.relayout();
      link.attr("d", path);
    };

    nodes.call(d3.drag()
      .subject(function(d) { return d; })
      .on("start", function() { this.parentNode.appendChild(this); })
      .on("drag", dragmove));
  }
  '
)
...