Невозможно прочитать свойство 'weight' из undefined и Невозможно прочитать свойство 'x' из undefined d3.js

1

Я создал скрипку для репликации проблемы: скрипка ссылки

До этого мы использовали хороший плоский json файл в нашем проекте. Новый файл, с которым я должен работать, гораздо более вложен.

Моя функция d3 выглядит так:

/* chart data */
// return data for relationships between database tables
returnTableRelationshipData = function(){

    var url = 'https://api.myjson.com/bins/7ovnb.json';
    d3.json(url, function(data){

        //find the node index
        function find(f){
          var i = -1
            data.p.nodes.forEach(function(node, index){
                node.x = 200 + Math.random()*200;
                node.y = 150 + Math.random()*200;
                if(node.properties.nodeID.val == f)
                    i = index;
            });
            return i;
        }

        //set the source and target index
        data.p.relationships.forEach(function(d){
            d.start = find(d.start);
            d.end = find(d.end);
        });

        // used to store the number of links between two nodes. 
        var mLinkNum = {};

        // sort links first
        sortLinks();                                

        // set up linkIndex and linkNumer, because it may possible multiple links share the same source and target node
        setLinkIndexAndNum();

        // check that we don't have empty or null values
        checkDataNotEmpty();

        var w = 1000;
        var h = 400;

        var force = d3.layout.force()
            .nodes(data.p.nodes)
            .links(data.p.relationships)
            .alpha(.1)
            .gravity(1)
            .charge(-10000)
            .size([w, h])
            .start();

        var svg = d3.select('.node-wrapper').append('svg')
            .attr('width', w)
            .attr('height', h);

        var path = svg.append('svg:g')
            .selectAll('path')
            .data(force.links())
            .enter().append('line')
            .attr('class', 'link')
            .attr('x1', function(d) {
                return d.start.x;
            })
            .attr('y1', function(d) {
                return d.start.y;
            })
            .attr('x2', function(d) {
                return d.end.x;
            })
            .attr('y2', function(d) {
                return d.end.y;
            });

        var node_drag = d3.behavior.drag()
            .on('dragstart', dragstart)
            .on('drag', dragmove)
            .on('dragend', dragend);

        var circle = svg.append('svg:g')
            .selectAll('circle')
            .data(force.nodes())
            .enter().append('svg:circle')
            .attr('r', 6)
            .call(node_drag);

        var text = svg.append('svg:g')                                
            .selectAll('g')
            .data(force.nodes())
            .enter().append('svg:g');

        text.append('svg:text')
            .text(function(d){ 
                return d.description;
            });

        force.on('tick', tick);

        function tick() {
            path.attr('x1', function(d) {
                return d.start.x;
            })
            .attr('y1', function(d) {
                return d.start.y;
            })
            .attr('x2', function(d) {
                return d.end.x;
            })
            .attr('y2', function(d) {
                return d.end.y;
            });

            circle.attr('transform', function(d){
                return 'translate(' + d.x + ',' + d.y + ')';
            });

            text.attr('transform', function(d){
                return 'translate(' + d.x + ',' + d.y + ')';
            });
        }

        function dragstart(d, i) {
            force.stop(); // stops the force auto positioning before you start dragging
        }

        function dragmove(d, i) {
            d.px += d3.event.dx;
            d.py += d3.event.dy;
            d.x += d3.event.dx;
            d.y += d3.event.dy;
            tick();
        }

        function dragend(d, i) {
            d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
            tick();
        }

        // sort the links by source, then target
        function sortLinks(){
            if(data.p.relationships != null){                         
                data.p.relationships.sort(function(a,b){
                    if(a.start > b.start){
                        return 1;
                    }else if(a.start < b.start){
                        return -1;
                    }else{
                        if(a.end > b.end){
                            return 1;
                        }if(a.end < b.end){
                            return -1;
                        }else{
                            return 0;
                        }
                    }
                });
            }
        }

        //any links with duplicate source and target get an incremented 'linknum'
        function setLinkIndexAndNum(){                              
            for(var i = 0; i < data.p.relationships.length; i++){
                if(i != 0 &&
                    data.p.relationships[i].start == data.p.relationships[i-1].start &&
                    data.p.relationships[i].end == data.p.relationships[i-1].end){
                    data.p.relationships[i].linkindex = data.p.relationships[i-1].linkindex + 1;
                }else{
                    data.p.relationships[i].linkindex = 1;
                }// save the total number of links between two nodes
                if(mLinkNum[data.p.relationships[i].end + ',' + data.p.relationships[i].start] !== undefined){
                    mLinkNum[data.p.relationships[i].end + ',' + data.p.relationships[i].start] = data.p.relationships[i].linkindex;
                }else{
                    mLinkNum[data.p.relationships[i].start + ',' + data.p.relationships[i].end] = data.p.relationships[i].linkindex;
                }
            }
        }

        function checkDataNotEmpty(){
            data.p.relationships.forEach(function(link, index, list) {
                if (typeof link.start === 'undefined') {
                    console.log('undefined link', data.p.nodes[link.start]);
                }
                if (typeof link.end === 'undefined') {
                    console.log('undefined source', data.p.nodes[link.end]);
                }
            });
        }

    });
}();

В соответствии с этим ответом, если я прокомментирую эти строки:

var force = d3.layout.force()
            //.nodes(data.p.nodes)
            //.links(data.p.relationships)
            .alpha(.1)
            .gravity(1)
            ...

Затем объект svg добавляется к html.

Ответ, связанный с этим, на самом деле не дает решения.

Как узлы, так и ссылки, по-видимому, повторяются правильно. Изображение 174551

Моя единственная догадка заключается в том, что мне как-то приходится сопоставлять "start" и "end" source и target, или мне нужно каким-то образом преобразовать data.p.nodes и data.p.relationships. Или, возможно, индексирование работает неправильно.

Я могу работать с сторонним разработчиком, чтобы изменить некоторые свойства и типы json (строка, целое число и т.д.).

Здесь вызывается json файл: http://myjson.com/7ovnb

Теги:
d3.js
svg

1 ответ

1
Лучший ответ
  1. Определите штрих для ссылок, чтобы сделать их видимыми:

    .node-wrapper line {
      stroke: #0D9E1E;
    }
    
  2. Переименуйте все вхождения .start с .source и .end с .target в функции tick().

  3. В вашей функции find() вы должны сравнить с свойством node.id:

    function find(f){
      var i; // do not return an existing value as default
        data.p.nodes.forEach(function(node, index){
            node.x = 200 + Math.random()*200;
            node.y = 150 + Math.random()*200;
            if(node.id == f)
                i = index;
        });
        return i;
    }
    

    Index 0 if - это существующий индекс узла, поэтому было бы лучше не устанавливать его как значение по умолчанию.

  • 0
    Спасибо, я постараюсь реализовать это утром и сообщить, как у меня дела.
  • 0
    Да, это сделал это. Большое спасибо @ccprog

Ещё вопросы

Сообщество Overcoder
Наверх
Меню