ricklupton / d3-sankey-diagram

Sankey diagram for d3
https://ricklupton.github.io/d3-sankey-diagram
MIT License
107 stars 35 forks source link

Direction not consistent when grouping nodes #13

Open StrijnKames opened 6 years ago

StrijnKames commented 6 years ago

Hi @ricklupton ,

Really great visualization!

When grouping nodes the direction of the links seem to do whatever direction suits best. I would like them to always go right side out left side in. In many cases this is going OK but in this example the diagram doing it (for me) the wrong way.

image

Is there any way in correcting this?

I tried direction: "r" on the nodes with no success.

This is part(!) of my JSON:"

{
    "nodes": [{
            "id": "01 - Homepage",
            "direction": "r"
        },
        {
            "id": "02 - Park - Homepages",
            "direction": "r"
        },
        {
            "id": "03 - Park - Content pages",
            "direction": "r"
        },
        {
            "id": "04 - Park - Acco(detail)",
            "direction": "r"
        }
    ],
    "links": [{
            "source": "Enter",
            "target": "02 - Park - Homepages",
            "value": 64223,
            "type": "enter"
        },
        {
            "source": "02 - Park - Homepages",
            "target": "04 - Park - Acco(detail)",
            "value": 55397,
            "type": "homepage"
        },
        {
            "source": "04 - Park - Acco(detail)",
            "target": "Exit",
            "value": 45991,
            "type": "exit"
        },
        {
            "source": "02 - Park - Homepages",
            "target": "Exit",
            "value": 38980,
            "type": "exit"
        },
        {
            "source": "Enter",
            "target": "01 - Homepage",
            "value": 34687,
            "type": "enter"
        },
        {
            "source": "02 - Park - Homepages",
            "target": "03 - Park - Content pages",
            "value": 30135,
            "type": "homepage"
        }
    ],
    "groups": [{
            "type": "Group",
            "title": "Enter",
            "bundle": null,
            "id": "Enter",
            "nodes": ["Enter"],
            "def_pos": null
        },
        {
            "type": "Group",
            "title": "Broad - Shopping",
            "bundle": null,
            "id": "Broad",
            "nodes": ["01 - Homepage", "05 - Theme - Home", "06 - Theme - Content", "07 - Offer - Overview", "08 - Offer - Detail", "09 - Search - Lists results", "11 - Maps", "14 - Site-Content"],
            "def_pos": null
        },
        {
            "type": "Group",
            "title": "Narrow - Shopping",
            "bundle": null,
            "id": "Narrow",
            "nodes": ["02 - Park - Homepages", "03 - Park - Content pages", "04 - Park - Acco(detail)", "15 - Compare"],
            "def_pos": null
        },
        {
            "type": "Group",
            "title": "Booking",
            "bundle": null,
            "id": "Booking",
            "nodes": ["12 - IBE", "17 - My Vacation", "NoMatch"],
            "def_pos": null
        },
        {
            "type": "Group",
            "title": "Pre Holiday",
            "bundle": null,
            "id": "Pre Holiday",
            "nodes": ["13 - My Account"],
            "def_pos": null
        },
        {
            "type": "Group",
            "title": "Exit",
            "bundle": null,
            "id": "Exit",
            "nodes": ["Exit"],
            "def_pos": null
        }
    ],
    "order": [
        [
            ["Enter"],
            [],
            []
        ],
        [
            ["01 - Homepage", "05 - Theme - Home", "06 - Theme - Content", "07 - Offer - Overview", "08 - Offer - Detail", "09 - Search - Lists results", "11 - Maps", "14 - Site-Content"],
            [],
            []
        ],
        [
            ["02 - Park - Homepages", "03 - Park - Content pages", "04 - Park - Acco(detail)", "15 - Compare"],
            [],
            []
        ],
        [
            ["12 - IBE", "17 - My Vacation", "NoMatch"],
            [],
            []
        ],
        [
            ["13 - My Account"],
            [],
            []
        ],
        [
            ["Exit"],
            [],
            []
        ]
    ],
    "rankSets": [{
            "type": "min",
            "nodes": ["Enter"]
        },
        {
            "type": "min",
            "nodes": ["01 - Homepage", "05 - Theme - Home", "06 - Theme - Content", "07 - Offer - Overview", "08 - Offer - Detail", "09 - Search - Lists results", "11 - Maps", "14 - Site-Content"]
        },
        {
            "type": "min",
            "nodes": ["02 - Park - Homepages", "03 - Park - Content pages", "04 - Park - Acco(detail)", "15 - Compare"]
        },
        {
            "type": "min",
            "nodes": ["12 - IBE", "17 - My Vacation", "NoMatch"]
        },
        {
            "type": "min",
            "nodes": ["13 - My Account"]
        }, {
            "type": "min",
            "nodes": ["Exit"]
        }
    ]
}
ricklupton commented 6 years ago

Hi, glad you're finding it useful, and thanks for reporting this! I think it's a bug. Here's a simple example that shows the same problem. The problem is with links that go between nodes in the same "layer"/"rank", i.e. nodes that are vertically above and below each other.

A workaround would be to add an intermediate node with direction: 'l', like this example. You could do this by hand, or else I don't know if you've seen floWeaver -- it provides a framework for specifying & aggregating these kinds of intermediate nodes, as well as giving you some more powerful aggregation and grouping, which might be useful for this kind of data.

ricklupton commented 6 years ago

Steps needed to fix:

  1. Add a test, probably in test/linkPath-test.js, with two nodes with the same x coordinate, checking that the link leaves & enters from the appropriate side.
  2. Fix some logic, probably in src/linkPath.js
StrijnKames commented 6 years ago

Hi @ricklupton,

thanks for the answers I will look into this as soon as possible!