Force Directed Graph Error, "Unable to read the 'Push' property from Undefined"

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>
+4
source share
2 answers

The API docs have:

Note: the values ​​of the source and target attributes can be initially specified as indices in an array of nodes; they will be replaced by links after starting the call.

An array of links must reference nodes either by index or by reference to node objects. In your working example, this is done when creating nodes from links:

link.source =                                   // (3)
    nodes[link.source] ||                       // (1)
    (nodes[link.source] = {name: link.source}); // (2)

(1) node link.source, H, node nodes, . nodes, ||, (2) node . (1) || (2) node, (3) link.source. , , . :

[
  {source: { name: 'H' }, target: { name: 'I' }},
  {source: { name: 'H' }, target: { name: 'J' }},
  {source: { name: 'I' }, target: { name: 'J' }},
  {source: { name: 'J' }, target: { name: 'K' }},
];

source target, node.


, , D3, :

var links = [
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 1, target: 2},
    {source: 2, target: 3},
];

var nodes = [ 
    {name: 'H'},
    {name: 'I'},
    {name: 'J'},
    {name: 'K'},
];

, , :

var width = 600,
    height = 400;

var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height)

var links = [
    {source: 0, target: 1},
    {source: 0, target: 2},
    {source: 1, target: 2},
    {source: 2, target: 3},
];

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 src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Hide result
+2

, My source , , .

+2

Source: https://habr.com/ru/post/1650973/


All Articles