3

Anyone managed to make the example

Sankey diagram with horizontal and vertical node movement

work in v4

since sankey.relayout() is not available anymore d3.drag has no .origin anymore.

My attempt do the wildest things while attempting to drag a node and since some behaviors have changed in both sankey and drag specifications I'm unable to figure how to migrate the example to v4.

var graph = { "nodes": [...], "links": [...] }; 
var layout = d3.sankey();

layout
    .extent([[1, 1], [width - 1, height - 6]])
    .nodeId(function (d) {
        return d.id;
    })
    .nodeWidth(12)
    .nodePadding(padding)
    .nodeAlign(d3.sankeyRight)

layout(graph);

// Add Links
var link = svg.append("g")
    .attr("fill", "none")
    .selectAll(".link")
      .data(graph.links)
      .enter()
      .append("g")
      .attr("class", "link")

link.append("path")
.attr("d", d3.sankeyLinkHorizontal())
.attr("stroke", "#000")
.style("stroke-width", function (d) {
    return d.width;
})
    .append("title")
    .text("Some text");


// Drag behavior for node elements
var drag = d3.drag()
   //.origin(function (d) { return d; }) // Deprecated but maybe unnecessary
   .on("drag", dragmove)

// Add nodes
var node = svg.append("g")
        .selectAll(".node")
          .data(graph.nodes)
          .enter()
            .append("g")  
            .attr("transform", function (d) {
                return "translate(" + [d.x0, d.y0] + ")";
            })
            .call(drag)  // The g element should be now draggable

// Add element inside g element
node.append("rect")
    .attr("height", function (d) { return d.y1 - d.y0; })
    .attr("width", function (d) { return d.x1 - d.x0; })
    .attr("fill", ...)

node.append("text")
    .attr("x", function (d) { return (d.x1 - d.x0) - 6; })
    .attr("y", function (d) { return (d.y1 - d.y0) / 2; })
    .attr("dy", "0.35em")
    .attr("text-anchor", "end")
    .text(function (d) { return d.name; })
    .filter(function (d) { return d.x0 < width / 2; })
    .attr("x", function (d) { return (d.x1 - d.x0) + 6 })
    .attr("text-anchor", "start");


// Called by d3.drag
function dragmove(d) { 

        var dx = Math.round(d.x = Math.max(0, Math.min(width , evt.x)));
        var dy = Math.round(d.y = Math.max(0, Math.min(height, evt.y)));

        d3.select(this).attr("transform", "translate(" + [dx, dy] + ")")

        // Now should redraw the links but 
        sankey.relayout(); // not a function anymore.


        // path references sankey.link() that is also deprecated in v4 in 
        // favour of d3.sankeyLinkHorizontal() ? (I'm not sure)
        // link references the g element containing the path elements 
        // classed .link
        link.attr("d", path);

};
Gavello
  • 1,399
  • 2
  • 13
  • 25
  • I guess you can replace the use of the `origin` method by using the `subject` method. See the example on [this answer](https://stackoverflow.com/a/38612402/5050917) or the  [`subject` method documentation](https://github.com/d3/d3-drag#drag_subject). – mgc Jan 24 '18 at 20:03
  • yes it can be substituted but in my specific case the issue is when the links have to be redrawn sankey relayout is deprecated and sankey.update(graph) does not the trick – Gavello Jan 26 '18 at 08:22
  • Hi @Gavello, can you look on this link https://github.com/d3/d3/blob/master/CHANGES.md , You will get what are the major changes they did for migration. – richard a Mar 20 '19 at 11:07
  • A bit late but this answer solved the problem for me: https://stackoverflow.com/a/64641203/1254877 – Gaet Apr 13 '21 at 10:38

0 Answers0