I'm trying to create a basic sankey diagram using d3 libraries loaded from requirejs. In the past I've used the core d3 library and rendered everything fine, however in trying to load d3-sankey in this instance it doesn't seem to be registering. I've also tinkered around with the shim but I can't seem to figure out where the issue is specifically. Every time I try to load the attached code I get the error 'Uncaught TypeError: d3.sankey is not a function'.
I'm assuming the issue is the sequencing of libraries being loaded, but again I'm not sure how to resolve this. Can anyone help?
Codepen - https://codepen.io/quirkules/pen/wYoXxQ
// define URLs
require.config({
paths: {
cloudflare: 'https://cdnjs.cloudflare.com/ajax/libs'
},
map: {
'*': {
'd3': 'cloudflare/d3/4.8.0/d3',
'd3-timer': 'cloudflare/d3-timer/1.0.5/d3-timer',
'd3-array': 'cloudflare/d3-array/1.2.2/d3-array',
'd3-collection': 'cloudflare/d3-collection/1.0.5/d3-collection',
'd3-interpolate': 'cloudflare/d3-interpolate/1.3.0/d3-interpolate',
'd3-color': 'cloudflare/d3-color/1.2.1/d3-color',
'd3-shape': 'cloudflare/d3-shape/1.2.0/d3-shape',
'd3-path': 'cloudflare/d3-path/1.0.5/d3-path',
'd3-sankey': 'cloudflare/d3-sankey/0.7.1/d3-sankey'
}
},
shim : {
d3 : {
exports : 'd3'
},
'd3-sankey' : {
deps: ['d3']
}
}
});
// load d3
require(['d3', 'd3-timer', 'd3-array', 'd3-collection', 'd3-interpolate', 'd3-color', 'd3-shape', 'd3-sankey'], function(d3) {
//****** CREATE DIVS ******//
// Add the divs to the DOM
$(document.body)
.append('<div id="header"></div>')
.append('<div id="chart"></div>')
.append('<div id="footer"></div>');
//add text to the divs
document.getElementById("header").innerHTML = '<b>Title</b>';
// set the dimensions and margins of the graph
var margin = { top: 20, right: 20, bottom: 40, left: 50 },
width = d3.select('#chart').node().getBoundingClientRect().width - margin.left - margin.right,
height = d3.select('#chart').node().getBoundingClientRect().height - margin.top - margin.bottom;
//
var svg = d3.select("#chart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var graph = d3.sankey()
.nodeWidth(15)
.nodePadding(10)
.size([width, height]);
var path = graph.link();
var freqCounter = 1;
//****** END CREATE CHART ******//
});
Why use require?
If I load the following 2 scripts it fails at the line var path = graph.link();
, so d3.sankey
is known and a function.
Undo all use of require
and add
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-sankey/0.7.1/d3-sankey.min.js"></script>
d3.js
already contains most of the other modules, it does not contain d3-sankey
. For some reason d3.js
does not register the individual modules it contains with require()
, that's why require tries to load the modules d3-array
, d3-collection
, d3-shape
, d3-path
Maybe you have a version problem, how do you know which version of the individual modules belong to d3.v4.8.0.
Edit
If I load d3-sankey
after the other modules, the error disappears but if it works later on I don't know. (There are no links because there is no data processed by sankey.
require(['d3-selection', 'd3-timer', 'd3-array', 'd3-collection', 'd3-interpolate', 'd3-color', 'd3-shape'], function(d3) {
require(['d3-sankey'], function(dsankey) {
//****** CREATE DIVS ******//
// .....
var graph = dsankey.sankey()
.nodeWidth(15)
.nodePadding(10)
.size([width, height]);
//****** END CREATE CHART ******//
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With