I am new to coding and recently started using d3 to create a force-oriented graph. I successfully generated four node graphs using links to display nodes. However, when I explicitly list the nodes, I get the error message "Uncaught TypeError: Cannot read the push property from undefined (d3.v3.min.js)." I studied the answers to the following two similar questions, but could not solve this problem using the answers. I tried to remove as many irrelevant functions as possible, thanks.
JavaScript error "Uncaught TypeError: Unable to call the 'push' method from undefined" D3.js
Uncaught TypeError: Unable to call the 'push' method from undefined (d3 force layout)
Incorrect schedule with forced configuration:
<script type="text/javascript" src="d3.v3.min.js"> </script>
<script>
var width = 900,
height = 590;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
var links = [
{source: 'H', target: 'I'},
{source: 'H', target: 'J'},
{source: 'I', target: 'J'},
{source: 'J', target: 'K'},
];
var nodes = [
{name: 'H'},
{name: 'I'},
{name: 'J'},
{name: 'K'},
];
var force = d3.layout.force()
.size([width, height])
.nodes(d3.values(nodes))
.links(links)
.on('tick', tick)
.linkDistance(100)
.gravity(.15)
.friction(.8)
.linkStrength(1)
.charge(-425)
.chargeDistance(600)
.start();
var link = svg.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link');
var node = svg.selectAll('.node')
.data(force.nodes())
.enter().append('circle')
.attr('class', 'node')
.attr('r', width * 0.01)
function tick(e) {
node.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.call(force.drag);
link.attr('x1', function(d) { return d.source.x; })
.attr('y1', function(d) { return d.source.y; })
.attr('x2', function(d) { return d.target.x; })
.attr('y2', function(d) { return d.target.y; });
};
</script>
Work with a radiation pattern with a constant speed:
<script type="text/javascript" src="d3.v3.min.js"> </script>
<script>
var width = 900,
height = 590;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
var links = [
{source: 'H', target: 'I'},
{source: 'H', target: 'J'},
{source: 'I', target: 'J'},
{source: 'J', target: 'K'},
];
var nodes = {};
links.forEach(function(link) {
link.source = nodes[link.source] ||
(nodes[link.source] = {name: link.source});
link.target = nodes[link.target] ||
(nodes[link.target] = {name: link.target});
});
var force = d3.layout.force()
.size([width, height])
.nodes(d3.values(nodes))
.links(links)
.on('tick', tick)
.linkDistance(100)
.gravity(.15)
.friction(.8)
.linkStrength(1)
.charge(-425)
.chargeDistance(600)
.start();
var link = svg.selectAll('.link')
.data(links)
.enter().append('line')
.attr('class', 'link');
var node = svg.selectAll('.node')
.data(force.nodes())
.enter().append('circle')
.attr('class', 'node')
.attr('r', width * 0.01)
function tick(e) {
node.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; })
.call(force.drag);
link.attr('x1', function(d) { return d.source.x; })
.attr('y1', function(d) { return d.source.y; })
.attr('x2', function(d) { return d.target.x; })
.attr('y2', function(d) { return d.target.y; });
};
</script>