SVG d3 элементы заикаются / трепещут / трясутся. Никаких преобразований внутри - PullRequest
1 голос
/ 25 мая 2020

Я новичок Angular и JavaScript.

Вот json, который я использую для создания графического svg. Я также использую колу. js специально для графиков.

{
   "nodes":[
      {
         "name":"Video-SoundRecorder"
      },
      {
         "name":"ObjectDetector"
      },
      {
         "name":"SoundClassifier"
      },
      {
         "name":"DetectIntruder"
      },
      {
         "name":"NotifyHouseOwner"
      },
      {
         "name":"NotifyPolice"
      }
   ],
   "links":[
      {
         "name":"Link1",
         "source":0,
         "target":1
      },
      {
         "name":"Link2",
         "source":0,
         "target":2
      },
      {
         "name":"Link3",
         "source":1,
         "target":3
      },
      {
         "name":"Link4",
         "source":2,
         "target":3
      },
      {
         "name":"Link5",
         "source":3,
         "target":4
      },
      {
         "name":"Link6",
         "source":3,
         "target":5
      }
   ],
   "groups":[
      {
         "name":"Split1",
         "leaves":[
            0,
            1,
            2
         ],
         "colorId":0,
         "priority":0
      },
      {
         "name":"Split2",
         "leaves":[
            3,
            4,
            5
         ],
         "colorId":1,
         "priority":1
      },
      {
         "name":"Merge1",
         "leaves":[
            1,
            2,
            3
         ],
         "groups":[

         ],
         "colorId":2,
         "priority":2
      }
   ]
}

Вот видео, показывающее поведение:

Видео

Там почти ничего на странице. colaGraph - пустой div. А вот код d3:

    const color = d3.scaleOrdinal(d3.schemeCategory10);
    const svg = d3.select('#colaGraph')
      .append('svg')
      .attr('viewBox', '0 0 1620 740')
      .attr('preserveAspectRatio', 'xMidYMid meet')
      .classed('svg-content-responsive', true);

    const width = svg.node().getBoundingClientRect().width;
    const height = svg.node().getBoundingClientRect().height;

    const cola = webcola.d3adaptor(d3)
      .linkDistance(170)
      .avoidOverlaps(true)
      .handleDisconnected(true)
      .flowLayout('x', 300)
      .size([width, height]);

    const group = svg.selectAll('.group')
          .data(graph.groups)
          .enter()
          .append('rect')
          .attr('rx', 8).attr('ry', 8)
          .attr('class', 'group')
          .attr('label', 'test')
          .style('fill', function(d: any) {
            return d.fill;
          })
          .sort((d: any) => -d.priority)
          .order()
          .on('click', function(d) {
            console.log('group');
          });

    const link = svg.selectAll('.link')
          .data(graph.links)
          .enter()
          .append('line')
          .attr('class', 'link')
          .attr('marker-end', 'url(#end)')
          .on('click', function(d) {
            console.log('link');
          });

    const node = svg.selectAll('.node')
          .data(graph.nodes)
          .enter()
          .append('rect')
          .attr('class', 'node')
          .attr('width', function(d: any) {
            return d.width;
          })
          .attr('height', function(d: any) {
            return d.height;
          })
          .attr('rx', 5).attr('ry', 5)
          .style('fill', function(d: any) {
            return d.fill;
          })
          .style('cursor', 'pointer')
          .on('mouseup', function(d: any) {
            d.fixed = 0;
            cola.alpha(1); // fire it off again to satify gridify
          })
          .on('click', function(d) {
            console.log('node');
          });

    node.append('title')
          .text(function(d: any) {
            return d.name;
          });

    const linkLabel = svg.selectAll('.linkLabel')
          .data(graph.links)
          .enter().append('text')
          .attr('class', 'linkLabel')
          .text(function(d: any) {
            return d.name;
          });

    const label = svg.selectAll('.label')
          .data(graph.nodes)
          .enter().append('text')
          .attr('class', 'label')
          .style('cursor', 'pointer')
          .text(function(d: any) {
            return d.name;
          });

    const clusterLabel = svg.selectAll('.clusterLabel')
          .data(graph.groups)
          .enter().append('text')
          .attr('class', 'clusterLabel')
          .text(function(d: any) {
            return d.name;
          });

        // Start the graph, coordinates
    cola
          .nodes(graph.nodes)
          .links(graph.links)
          .groups(graph.groups)
          .on('tick', function() {

            link.attr('x1', (d: any) => getXArrowCoordinate(d.target.x, d.target.y, d.source.x, d.source.y, d.source.width))
              .attr('y1', (d: any) => getYArrowCoordinate(d.target.x, d.target.y, d.source.x, d.source.y, d.source.height))
              .attr('x2', (d: any) => getXArrowCoordinate(d.source.x, d.source.y, d.target.x, d.target.y, d.target.width))
              .attr('y2', (d: any) => getYArrowCoordinate(d.source.x, d.source.y, d.target.x, d.target.y, d.target.height));

            node.attr('x', function(d: any) {
              return d.x - d.width / 2;
            })
              .attr('y', function(d: any) {
                return d.y - d.height / 2;
              });

            group.attr('x', function(d: any) {
              return d.bounds.x;
            })
              .attr('y', function(d: any) {
                return d.bounds.y;
              })
              .attr('width', function(d: any) {
                return d.bounds.width();
              })
              .attr('height', function(d: any) {
                return d.bounds.height();
              });

            label.attr('x', function(d: any) {
              return d.x;
            })
              .attr('y', function(d: any) {
                const h = this.getBBox().height;
                return d.y + h / 4;
              });

            clusterLabel
              .attr('x', function(d: any) {
                return d.bounds.x + 50;
              })
              .attr('y', function(d: any) {
                return d.bounds.y;
              });

            linkLabel
              .attr('x', function(d: any) {
                return (d.source.x + d.target.x) / 2;
              })
              .attr('y', function(d: any) {
                return (d.source.y + d.target.y) / 2 - 10;
              });
          })
          .start(2, 2, 2);


...