使用d3力模拟时出错

时间:2017-11-14 17:31:33

标签: javascript d3.js svg force-layout

我在使用d3力模拟时遇到错误。在某个点之后(当添加3个主节点时),模拟会出现故障,颤抖和无限排斥。以下是视频(https://youtu.be/XJvQ4v6XPOMd3 error的链接,以及用于模拟的我(有些混乱)代码。每个链接都有一个'source'和'target'节点对象,其值为。

///////////

d3.select('#canvas').selectAll('svg').remove();

    var width = 960,
        height = 700

    var svg = d3.select("#canvas").append("svg")
        .attr("width", width)
        .attr("height", height);

    var linkDistance = this.props.settings.linkDistance || 200;
    var circleSize = this.props.settings.circleSize || 17;
    var artistNum = this.props.settings.artistNumber || 7;
    var roles = this.props.settings.roles || ['rapper', 'producer'];
    var label = this.props.settings.label || 'text';

    var nodes = d3.forceSimulation(this.state.allMovies)
    .force("charge", d3.forceManyBody().strength(-30))
    .force("link", d3.forceLink(this.state.blinks)
      .distance((d) => {
        return d.value > 0 ? linkDistance/(d.value*1.5) : linkDistance*1.5;
      })
      // .strength((d) => {
      //   return d.value > 0 ? d.value*2 : 1;
      // })
      )
    .force("center", d3.forceCenter(400, 300))
    // .force("gravity", d3.forceManyBody().strength(-50))

    // .force("distance", d3.forceManyBody(100))

    // .force('collision', d3.forceCollide().radius(function(d) {
    //   return 30
    // }))
    .force("size", d3.forceManyBody([width, height]));

    var link = svg.selectAll(".link").data(this.state.blinks).enter()
        .append("line")
        .attr("class", (d) => `link ${d.source.title.split(' ').join('')} ${d.target.title.split(' ').join('')}`)
        .attr("stroke-width", (d) => d.value*3);

          $('.link').toggle();

    link.on("click", (d) => {
        console.log('selected link', d);

        // var songsArr = this.state.songsLibrary.filter(song => {
        //   return d.songList.includes(song.id)
        // })
        //
        // this.setState({
        //   display: 'link',
        //   selectedLink: d,
        //   songs: songsArr
        // })
      });

var node = svg.selectAll(".node").data(this.state.allMovies).enter()
    .append("g").attr("class", "node")
    .call(d3.drag()
            .on('start', dragstarted)
            .on('drag', dragged)
            .on('end', dragended)
    );

function dragstarted() {
  if (!d3.event.active) nodes.alphaTarget(0.3).restart();
  d3.event.subject.fx = d3.event.subject.x;
  d3.event.subject.fy = d3.event.subject.y;
}

function dragged() {
  d3.event.subject.fx = d3.event.x;
  d3.event.subject.fy = d3.event.y;
}

function dragended() {
  if (!d3.event.active) nodes.alphaTarget(0);
  d3.event.subject.fx = null;
  d3.event.subject.fy = null;
}

// append("svg:image")
// .attr('x', -9)
// .attr('y', -12)
// .attr('width', 20)
// .attr('height', 24)
// .attr("xlink:href", "resources/images/check.png")



if (label === 'image') {

  node.append("circle")
      .attr("r", (d) => d.type === 'primary' ? circleSize*3 : circleSize*2)
      .attr("fill", function(d) { return d.type === 'primary' ? '#241587' : '#3f88a3' })
      .attr("class", (d) => `${d.title.split(' ').join('')} node`);

  node.append("svg:image")
      .attr('x', -circleSize*1.5)
      .attr('y', -circleSize*1.5)
      .attr('width', circleSize*3)
      .attr('height', circleSize*3)
      .attr("border-radius", '50%')
      .attr("xlink:href", (d) => `${d.poster}`)

} else {

  node.append("circle")
      .attr("r", (d) => d.type === 'primary' ? circleSize*2.5 : circleSize*1.3)
      .attr("fill", function(d) { return d.type === 'primary' ? '#241587' : '#3f88a3' })
      .attr("class", (d) => `${d.title.split(' ').join('')} node`);

  node.append("text")
      .attr("dx", -15).attr("dy", ".70em")
      .text(function(d) { return d.title })
      .style("font-size", "12px")
      .style("fill", (d) => d.type === 'primary' ? "#e8eaed" : "#262728")
      .attr("class", (d) => `${d.title.split(' ').join('')}`)
}

    node.on('click', d => {
      console.log('SELECTED', d)
      let movie = d.title;
      var relatedLinks = this.state.blinks.filter(link => {
        return link.source.name === movie || link.target.name === movie;
      })

      $('.link').css('display', 'none')
      $(`.${movie.split(' ').join('')}.link`).toggle();

      this.sendRequestForMovies(d.title, 'secondary');

      this.setState({
        links: relatedLinks
      }, () => {
        console.log('movie in state', this.state.selectedMovie)
      })
    });

      nodes.on("tick", function() {
        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; });

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

0 个答案:

没有答案