0

I found this image from the Internet (link) and I think it was draw in R. I tried to reproduce this Figure and make it more or less similar with one from the above link. The code I used is as following:

    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

From this links it is possible to change the position of a node not only vertically, but also horizontally. Can we implement it in R?

Update 1: I can solve issue in question 2 by changing the source code of sankeyNetwork.js by using the code provide at this links. I do not know how to implement it through htmlwidgets (I am not familiar with JS; hence, just do trial and error!). I just need to copy the following code to the end of 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);
}
CJ Yetman
  • 8,373
  • 2
  • 24
  • 56
  • 1
    Your code is not reproducible... `name` is undefined. Also, SO is not a free consulting site where other people do your work for you. It's meant for asking precise questions about problems you can't solve, but hopefully you've at least attempted to solve them on your own. And ideally, it's something broad enough and generalized that the answer to your question might be useful to other people using this site. – CJ Yetman Sep 09 '18 at 16:32
  • 1
    @CJ Yetman. I am sorry for my boring question. I have tried to find the solution in also other websites. But it is not easy for me to be able to manage with JS, I usually only work with R only. I just try to learn a technique for visualization in R, not come here to ask people do my work. Thank you so much for your good advice. – user3045597 Sep 09 '18 at 17:30

1 Answers1

7

To enable horizontal movement of the nodes, along with the vertical movement, you could adapt d3noob's code to work, but it's not as easy as dropping in just their dragmove function declaration.

  1. It was written using D3v3, and networkD3 uses D3v4... and they're not entirely compatible.
  2. That function refers to a bunch of objects that are defined elsewhere, so the function on its own cannot work without knowing what these are: width, height, sankey, link, and path.

Here is one way of adapting it to work...

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));
  }
  '
)
CJ Yetman
  • 8,373
  • 2
  • 24
  • 56