Requesting help to port Sankey example to Observable | learning through examples

Dear Observable Community:

I continue to learn Observable by porting examples from bl.ocks. Currently I am working on a port of d3noob’s ‘Sankey Diagram with v4’, which I would like to get working with d3 version 5.

With Tom and Mike’s help, I’ve learned a few ways to append an object to the DOM. I have tried out a couple different approaches , but to no avail.

When I try:

var svg = d3.select(DOM.element('svg'))
... // code goes here
return svg.node();

I am returned a message reading SVGGElement {}

When I try:

 var container = html`<svg></svg>`;
 var svg = d3.select(container)
... // code goes here
return container;

I get an empty box.

Could someone please help me to better understand what’s going on? Might this be a problem with how the chart referring in data?

Here’s my workbook attempt:

I have tried to look at the Sankey examples already on Observable, but haven’t yet figured it out. For reference, these are:

Thanks in advance for your kind help and support!

Sincerely,

Aaron

you can use

const s = DOM.svg(width, height)
yield s;
const svg = d3.select(s);

Also for the data you will need to replace the d3.json(…) line by

d3.json("https://gist.githubusercontent.com/d3noob/013054e8d7807dff76247b81b0e29030/raw/001ef0f23a70f4cc3711f1aa505c12e284430d27/sankey.json").then(function(graph) {

Thank you, Fil.

With regard to the data line, any guidance on referencing the JSON locally? I would like to play around with the data and find it easier to do so within Observable than working through gists.

At present observablehq doesn’t offer this possiblity. However you can declare a (smallish) data set as an object directly in code.

So maybe create a specific notebook “toy data sets” with

sankey = ({
"nodes":[
{"node":0,"name":"node0"},
{"node":1,"name":"node1"},
{"node":2,"name":"node2"},
{"node":3,"name":"node3"},
{"node":4,"name":"node4"}
],
"links":[
{"source":0,"target":2,"value":2},
{"source":1,"target":2,"value":2},
{"source":1,"target":3,"value":2},
{"source":0,"target":4,"value":2},
{"source":2,"target":3,"value":2},
{"source":2,"target":4,"value":2},
{"source":3,"target":4,"value":4}
]})

publish it, then do

import { sankey } from "@aaronkyle/toy-data-sets"

and you can then use sankey directly (without going through d3.json).

Thanks again, Fil.

Unfortunately, I am not sure that I am following. I haven’t yet gotten the chart to render.

I managed to get another Sankey example working:

This example is able to ‘read in’ (if this is the right term) local JSON data using:

var graph = (data)

… It links the chart to an HTML page element <p id="chart"> using

var svg = d3.select("#chart").append("svg")

Unfortunately I also have been unsuccessful getting this method to work in producing the visualization in my port to d3noob example.

Any thoughts?

1 Like

Wow! So fast! Thank you for this example and for your help!

As a follow-up question, any idea why the nodes are black in observable, whereas they are assigned color in d3noob’s example?

d3.schemeCategory20 does not exist anymore in v5 (see d3/CHANGES.md at master · d3/d3 · GitHub )
I replaced it with d3.schemeCategory10 and colors are back :slight_smile:

1 Like

Here’s my port:

1 Like