{"id":15760448,"url":"https://github.com/d3/d3-sankey","last_synced_at":"2025-05-14T04:07:34.751Z","repository":{"id":37276499,"uuid":"47321555","full_name":"d3/d3-sankey","owner":"d3","description":"Visualize flow between nodes in a directed acyclic network.","archived":false,"fork":false,"pushed_at":"2023-11-13T19:08:44.000Z","size":1140,"stargazers_count":866,"open_issues_count":35,"forks_count":259,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-05-09T03:39:10.293Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://observablehq.com/collection/@d3/d3-sankey","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-03T09:25:01.000Z","updated_at":"2025-05-07T02:08:29.000Z","dependencies_parsed_at":"2022-07-12T11:19:56.029Z","dependency_job_id":"816eabfd-1e95-44f5-8b34-65be5579fc9f","html_url":"https://github.com/d3/d3-sankey","commit_stats":{"total_commits":108,"total_committers":12,"mean_commits":9.0,"dds":0.2685185185185185,"last_synced_commit":"bb7233ea0004669878d922e55fe83084ef3cb555"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3%2Fd3-sankey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3%2Fd3-sankey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3%2Fd3-sankey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d3%2Fd3-sankey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d3","download_url":"https://codeload.github.com/d3/d3-sankey/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069216,"owners_count":22009511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-04T10:58:02.645Z","updated_at":"2025-05-14T04:07:34.655Z","avatar_url":"https://github.com/d3.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# d3-sankey\n\nSankey diagrams visualize the directed flow between nodes in an acyclic network. For example, this diagram shows a possible scenario of UK energy production and consumption in 2050:\n\n[\u003cimg alt=\"Sankey diagram\" src=\"https://raw.githubusercontent.com/d3/d3-sankey/master/img/energy.png\" width=\"960\"\u003e](https://observablehq.com/@d3/sankey-diagram)\n\nSource: Department of Energy \u0026 Climate Change, Tom Counsell.\n\n**For an interactive editor, see [Flow-o-Matic](https://observablehq.com/@mbostock/flow-o-matic).**\n\n## Installing\n\nIf you use NPM, `npm install d3-sankey`. Otherwise, download the [latest release](https://github.com/d3/d3-sankey/releases/latest). You can also load directly from [unpkg.com](https://unpkg.com/d3-sankey/). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported:\n\n```html\n\u003cscript src=\"https://unpkg.com/d3-array@1\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/d3-collection@1\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/d3-path@1\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/d3-shape@1\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/d3-sankey@0\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n\nvar sankey = d3.sankey();\n\n\u003c/script\u003e\n```\n\n## API Reference\n\n\u003ca href=\"#sankey\" name=\"sankey\"\u003e#\u003c/a\u003e d3.\u003cb\u003esankey\u003c/b\u003e() [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nConstructs a new Sankey generator with the default settings.\n\n\u003ca href=\"#_sankey\" name=\"_sankey\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e(\u003ci\u003earguments\u003c/i\u003e…) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nComputes the node and link positions for the given *arguments*, returning a *graph* representing the Sankey layout. The returned *graph* has the following properties:\n\n* *graph*.nodes - the array of [nodes](#sankey_nodes)\n* *graph*.links - the array of [links](#sankey_links)\n\n\u003ca href=\"#sankey_update\" name=\"sankey_update\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003eupdate\u003c/b\u003e(\u003ci\u003egraph\u003c/i\u003e) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nRecomputes the specified *graph*’s links’ positions, updating the following properties of each *link*:\n\n* *link*.y0 - the link’s vertical starting position (at source node)\n* *link*.y1 - the link’s vertical end position (at target node)\n\nThis method is intended to be called after computing the initial [Sankey layout](#_sankey), for example when the diagram is repositioned interactively.\n\n\u003ca name=\"sankey_nodes\" href=\"#sankey_nodes\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003enodes\u003c/b\u003e([\u003ci\u003enodes\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *nodes* is specified, sets the Sankey generator’s nodes accessor to the specified function or array and returns this Sankey generator. If *nodes* is not specified, returns the current nodes accessor, which defaults to:\n\n```js\nfunction nodes(graph) {\n  return graph.nodes;\n}\n```\n\nIf *nodes* is specified as a function, the function is invoked when the Sankey layout is [generated](#_sankey), being passed any arguments passed to the Sankey generator. This function must return an array of nodes. If *nodes* is not a function, it must be a constant array of *nodes*.\n\nEach *node* must be an object. The following properties are assigned by the [Sankey generator](#_sankey):\n\n* *node*.sourceLinks - the array of outgoing [links](#sankey_links) which have this node as their source\n* *node*.targetLinks - the array of incoming [links](#sankey_links) which have this node as their target\n* *node*.value - the node’s value; this is the sum of *link*.value for the node’s incoming [links](#sankey_links), or *node*.fixedValue if defined\n* *node*.index - the node’s zero-based index within the array of nodes\n* *node*.depth - the node’s zero-based graph depth, derived from the graph topology\n* *node*.height - the node’s zero-based graph height, derived from the graph topology\n* *node*.layer - the node’s zero-based column index, corresponding to its horizontal position\n* *node*.x0 - the node’s minimum horizontal position, derived from *node*.depth\n* *node*.x1 - the node’s maximum horizontal position (*node*.x0 + [*sankey*.nodeWidth](#sankey_nodeWidth))\n* *node*.y0 - the node’s minimum vertical position\n* *node*.y1 - the node’s maximum vertical position (*node*.y1 - *node*.y0 is proportional to *node*.value)\n\nSee also [*sankey*.links](#sankey_links).\n\n\u003ca name=\"sankey_links\" href=\"#sankey_links\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003elinks\u003c/b\u003e([\u003ci\u003elinks\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *links* is specified, sets the Sankey generator’s links accessor to the specified function or array and returns this Sankey generator. If *links* is not specified, returns the current links accessor, which defaults to:\n\n```js\nfunction links(graph) {\n  return graph.links;\n}\n```\n\nIf *links* is specified as a function, the function is invoked when the Sankey layout is [generated](#_sankey), being passed any arguments passed to the Sankey generator. This function must return an array of links. If *links* is not a function, it must be a constant array of *links*.\n\nEach *link* must be an object with the following properties:\n\n* *link*.source - the link’s source [node](#sankey_nodes)\n* *link*.target - the link’s target [node](#sankey_nodes)\n* *link*.value - the link’s numeric value\n\nFor convenience, a link’s source and target may be initialized using numeric or string identifiers rather than object references; see [*sankey*.nodeId](#sankey_nodeId). The following properties are assigned to each link by the [Sankey generator](#_sankey):\n\n* *link*.y0 - the link’s vertical starting position (at source node)\n* *link*.y1 - the link’s vertical end position (at target node)\n* *link*.width - the link’s width (proportional to *link*.value)\n* *link*.index - the zero-based index of *link* within the array of links\n\n\u003ca name=\"sankey_linkSort\" href=\"#sankey_linkSort\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003elinkSort\u003c/b\u003e([\u003ci\u003esort\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *sort* is specified, sets the link sort method and returns this Sankey generator. If *sort* is not specified, returns the current link sort method, which defaults to *undefined*, indicating that vertical order of links within each node will be determined automatically by the layout. If *sort* is null, the order is fixed by the input. Otherwise, the specified *sort* function determines the order; the function is passed two links, and must return a value less than 0 if the first link should be above the second, and a value greater than 0 if the second link should be above the first, or 0 if the order is not specified.\n\n\u003ca name=\"sankey_nodeId\" href=\"#sankey_nodeId\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003enodeId\u003c/b\u003e([\u003ci\u003eid\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *id* is specified, sets the node id accessor to the specified function and returns this Sankey generator. If *id* is not specified, returns the current node id accessor, which defaults to the numeric *node*.index:\n\n```js\nfunction id(d) {\n  return d.index;\n}\n```\n\nThe default id accessor allows each link’s source and target to be specified as a zero-based index into the [nodes](#sankey_nodes) array. For example:\n\n```js\nvar nodes = [\n  {\"id\": \"Alice\"},\n  {\"id\": \"Bob\"},\n  {\"id\": \"Carol\"}\n];\n\nvar links = [\n  {\"source\": 0, \"target\": 1}, // Alice → Bob\n  {\"source\": 1, \"target\": 2} // Bob → Carol\n];\n```\n\nNow consider a different id accessor that returns a string:\n\n```js\nfunction id(d) {\n  return d.id;\n}\n```\n\nWith this accessor, you can use named sources and targets:\n\n```js\nvar nodes = [\n  {\"id\": \"Alice\"},\n  {\"id\": \"Bob\"},\n  {\"id\": \"Carol\"}\n];\n\nvar links = [\n  {\"source\": \"Alice\", \"target\": \"Bob\"},\n  {\"source\": \"Bob\", \"target\": \"Carol\"}\n];\n```\n\nThis is particularly useful when representing graphs in JSON, as JSON does not allow references. See [this example](https://bl.ocks.org/mbostock/f584aa36df54c451c94a9d0798caed35).\n\n\u003ca name=\"sankey_nodeAlign\" href=\"#sankey_nodeAlign\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003enodeAlign\u003c/b\u003e([\u003ci\u003ealign\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *align* is specified, sets the node [alignment method](#alignments) to the specified function and returns this Sankey generator. If *align* is not specified, returns the current node alignment method, which defaults to [d3.sankeyJustify](#sankeyJustify). The specified function is evaluated for each input *node* in order, being passed the current *node* and the total depth *n* of the graph (one plus the maximum *node*.depth), and must return an integer between 0 and *n* - 1 that indicates the desired horizontal position of the node in the generated Sankey diagram.\n\n\u003ca name=\"sankey_nodeSort\" href=\"#sankey_nodeSort\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003enodeSort\u003c/b\u003e([\u003ci\u003esort\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *sort* is specified, sets the node sort method and returns this Sankey generator. If *sort* is not specified, returns the current node sort method, which defaults to *undefined*, indicating that vertical order of nodes within each column will be determined automatically by the layout. If *sort* is null, the order is fixed by the input. Otherwise, the specified *sort* function determines the order; the function is passed two nodes, and must return a value less than 0 if the first node should be above the second, and a value greater than 0 if the second node should be above the first, or 0 if the order is not specified.\n\n\u003ca name=\"sankey_nodeWidth\" href=\"#sankey_nodeWidth\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003enodeWidth\u003c/b\u003e([\u003ci\u003ewidth\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *width* is specified, sets the node width to the specified number and returns this Sankey generator. If *width* is not specified, returns the current node width, which defaults to 24.\n\n\u003ca name=\"sankey_nodePadding\" href=\"#sankey_nodePadding\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003enodePadding\u003c/b\u003e([\u003ci\u003epadding\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *padding* is specified, sets the vertical separation between nodes at each column to the specified number and returns this Sankey generator. If *padding* is not specified, returns the current node padding, which defaults to 8.\n\n\u003ca name=\"sankey_extent\" href=\"#sankey_extent\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003eextent\u003c/b\u003e([\u003ci\u003eextent\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *extent* is specified, sets the extent of the Sankey layout to the specified bounds and returns the layout. The *extent* bounds are specified as an array \\[\\[\u003ci\u003ex0\u003c/i\u003e, \u003ci\u003ey0\u003c/i\u003e\\], \\[\u003ci\u003ex1\u003c/i\u003e, \u003ci\u003ey1\u003c/i\u003e\\]\\], where *x0* is the left side of the extent, *y0* is the top, *x1* is the right and *y1* is the bottom. If *extent* is not specified, returns the current extent which defaults to [[0, 0], [1, 1]].\n\n\u003ca name=\"sankey_size\" href=\"#sankey_size\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003esize\u003c/b\u003e([\u003ci\u003esize\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nAn alias for [*sankey*.extent](#sankey_extent) where the minimum *x* and *y* of the extent are ⟨0,0⟩. Equivalent to:\n\n```js\nsankey.extent([[0, 0], size]);\n```\n\n\u003ca name=\"sankey_iterations\" href=\"#sankey_iterations\"\u003e#\u003c/a\u003e \u003ci\u003esankey\u003c/i\u003e.\u003cb\u003eiterations\u003c/b\u003e([\u003ci\u003eiterations\u003c/i\u003e]) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankey.js \"Source\")\n\nIf *iterations* is specified, sets the number of relaxation iterations when [generating the layout](#_sankey) and returns this Sankey generator. If *iterations* is not specified, returns the current number of relaxation iterations, which defaults to 6.\n\n### Alignments\n\nSee [*sankey*.nodeAlign](#sankey_nodeAlign).\n\n\u003ca name=\"sankeyLeft\" href=\"#sankeyLeft\"\u003e#\u003c/a\u003e d3.\u003cb\u003esankeyLeft\u003c/b\u003e(\u003ci\u003enode\u003c/i\u003e, \u003ci\u003en\u003c/i\u003e) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/align.js \"Source\")\n\n[\u003cimg alt=\"left\" src=\"https://raw.githubusercontent.com/d3/d3-sankey/master/img/align-left.png\" width=\"480\"\u003e](https://observablehq.com/@d3/sankey-diagram?align=left)\n\nReturns *node*.depth.\n\n\u003ca name=\"sankeyRight\" href=\"#sankeyRight\"\u003e#\u003c/a\u003e d3.\u003cb\u003esankeyRight\u003c/b\u003e(\u003ci\u003enode\u003c/i\u003e, \u003ci\u003en\u003c/i\u003e) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/align.js \"Source\")\n\n[\u003cimg alt=\"right\" src=\"https://raw.githubusercontent.com/d3/d3-sankey/master/img/align-right.png\" width=\"480\"\u003e](https://observablehq.com/@d3/sankey-diagram?align=right)\n\nReturns *n* - 1 - *node*.height.\n\n\u003ca name=\"sankeyCenter\" href=\"#sankeyCenter\"\u003e#\u003c/a\u003e d3.\u003cb\u003esankeyCenter\u003c/b\u003e(\u003ci\u003enode\u003c/i\u003e, \u003ci\u003en\u003c/i\u003e) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/align.js \"Source\")\n\n[\u003cimg alt=\"center\" src=\"https://raw.githubusercontent.com/d3/d3-sankey/master/img/align-center.png\" width=\"480\"\u003e](https://observablehq.com/@d3/sankey-diagram?align=center)\n\nLike [d3.sankeyLeft](#sankeyLeft), except that nodes without any incoming links are moved as right as possible.\n\n\u003ca name=\"sankeyJustify\" href=\"#sankeyJustify\"\u003e#\u003c/a\u003e d3.\u003cb\u003esankeyJustify\u003c/b\u003e(\u003ci\u003enode\u003c/i\u003e, \u003ci\u003en\u003c/i\u003e) [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/align.js \"Source\")\n\n[\u003cimg alt=\"justify\" src=\"https://raw.githubusercontent.com/d3/d3-sankey/master/img/energy.png\" width=\"480\"\u003e](https://observablehq.com/@d3/sankey-diagram)\n\nLike [d3.sankeyLeft](#sankeyLeft), except that nodes without any outgoing links are moved to the far right.\n\n### Links\n\n\u003ca name=\"sankeyLinkHorizontal\" href=\"#sankeyLinkHorizontal\"\u003e#\u003c/a\u003e d3.\u003cb\u003esankeyLinkHorizontal\u003c/b\u003e() [\u003c\u003e](https://github.com/d3/d3-sankey/blob/master/src/sankeyLinkHorizontal.js \"Source\")\n\nReturns a [horizontal link shape](https://github.com/d3/d3-shape/blob/master/README.md#linkHorizontal) suitable for a Sankey diagram. The [source accessor](https://github.com/d3/d3-shape/blob/master/README.md#link_source) is defined as:\n\n```js\nfunction source(d) {\n  return [d.source.x1, d.y0];\n}\n```\n\nThe [target accessor](https://github.com/d3/d3-shape/blob/master/README.md#link_target) is defined as:\n\n```js\nfunction target(d) {\n  return [d.target.x0, d.y1];\n}\n```\n\nFor example, to render the links of a Sankey diagram in SVG, you might say:\n\n```js\nsvg.append(\"g\")\n    .attr(\"fill\", \"none\")\n    .attr(\"stroke\", \"#000\")\n    .attr(\"stroke-opacity\", 0.2)\n  .selectAll(\"path\")\n  .data(graph.links)\n  .join(\"path\")\n    .attr(\"d\", d3.sankeyLinkHorizontal())\n    .attr(\"stroke-width\", function(d) { return d.width; });\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd3%2Fd3-sankey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd3%2Fd3-sankey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd3%2Fd3-sankey/lists"}