2016-11-15 4 views
0

私はこの例を使用します:https://codepen.io/AndrewGHC/pen/mPXjKrD3 Forceの開始位置を追加するにはどうすればよいですか?

ページを更新すると、別の場所に要素が表示されます。 1つの円は正しいかもしれず、次の時間は左です。どのようにこれを避けることができますか?私は開始位置を設定する必要があると思う。

// Request data, generate bg with Trianglify & set up loading function. 
 

 
function slowPrint(tgt, i, msg, spd) { 
 
    if (i < msg.length) { 
 
    $(tgt).append(msg[i]); 
 
    i++; 
 
    var writeTimer = setTimeout(function() { 
 
     slowPrint(tgt, i, msg, spd) 
 
    }, spd); 
 
    } 
 
} 
 

 
function writeThis(tgt, msg, spd) { 
 
    if ($(tgt).html() === msg) { 
 
    return; 
 
    } 
 
    $(tgt).html(''); 
 
    slowPrint(tgt, 0, msg, spd); 
 
} 
 

 
writeThis('#info', 'Loading . . .', 100); 
 

 
var url = "https://raw.githubusercontent.com/AndrewGHC/kevin-bacon-number/master/kevinBacon.json"; 
 

 
d3.json(url, drawGraph); 
 

 
// Credit to Trianglify @ https://github.com/qrohlf/trianglify 
 

 
var pattern = Trianglify({ 
 
    height: $(document).height(), 
 
    width: $(document).width(), 
 
    cell_size: 40 
 
}); 
 

 
document.body.style.backgroundImage = "url(" + pattern.png() + ")"; 
 

 
// Create the drawGraph callback 
 

 
function drawGraph(err, data) { 
 
    if (err) throw err; 
 

 
    var width = $('#graph').width(), 
 
    height = $('#graph').height(); 
 

 
    // Prepare the data for the force graph, beinning by creating an array of movies (strings) 
 

 
    var movies = []; 
 
    (function() { 
 
    data.actors.forEach(function(actor) { 
 
     actor.movies.forEach(function(movie) { 
 
     if (movies.indexOf(movie) === -1) { 
 
      movies.push(movie); 
 
     } 
 
     }); 
 
    }); 
 
    }()) 
 

 
    // Create the links array for the force graph, mapping actors to movies. This will draw a line between the two. 
 

 
    var links = []; 
 
    (function() { 
 
    data.actors.forEach(function(actor, actorIndex) { 
 
     actor.movies.forEach(function(movie, movieIndex) { 
 
     links.push({ 
 
      "source": actorIndex, 
 
      "target": data.actors.length + movies.indexOf(movie) 
 
     }); 
 
     }); 
 
    }); 
 
    }()) 
 

 
    // Now prepare the nodes array, concatenating data.actors and the movies array. The order here is important, and movie indices must be converted into objects. 
 

 
    var nodes = data.actors; 
 
    movies.forEach(function(movie) { 
 
    nodes.push({ 
 
     "movie": movie 
 
    }); 
 
    }); 
 

 
    // Create the SVG canvas & force layout 
 

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

 
    var force = d3.layout.force() 
 
    .size([width, height]) 
 
    .nodes(nodes) 
 
    .links(links) 
 
    .linkDistance(50) 
 
    .charge(function(d) { 
 
     if (d.name === "Kevin Bacon") { 
 
     return -1000; 
 
     } else if (d.name) { 
 
     return -(d.weight) * 50; 
 
     } 
 
     return -((d.weight * 50) * 5); 
 
    }) 
 
    .gravity(0.1) 
 
    .start(); 
 

 
    // Helper function to remove whitespace, later used for assigning IDs 
 

 
    function rmWs(string) { 
 
    if (typeof string !== 'string') { 
 
     return false; 
 
    } 
 
    string = string.split(' ').join(''); 
 
    return string; 
 
    } 
 

 
    // Create the links 
 

 
    var link = canvas.selectAll('.link') 
 
    .data(links) 
 
    .enter().append('line') 
 
    .attr('class', 'link'); 
 

 
    // Create a colour scale for movie nodes. Find the min and max no. of links for the range of the colour domain. 
 

 
    var arrMax = []; 
 
    links.forEach(function(link) { 
 
    arrMax.push(link.target.weight); 
 
    }); 
 

 
    var colour = d3.scale.linear() 
 
    .domain([1, d3.max(arrMax)]) 
 
    .range(["white", "black"]) 
 
    .interpolate(d3.interpolateHcl); 
 

 
    // Set up the pop up on mouse hover 
 

 

 

 
    // Call circles on SVG chart, with colours along a white - black gradient generated based on the max weight & variable sizing. Then place text on these movie elements. 
 

 
    var circleRadius = 17; 
 

 
    var circles = canvas.selectAll('.movies') 
 
    .data(nodes) 
 
    .enter() 
 
    .append('circle') 
 
    .attr('r', function(d, i) { 
 
     if (d.name) { 
 
     return circleRadius; 
 
     } 
 
     return circleRadius + (d.weight * 2); 
 
    }) 
 
    .attr('stroke', '#777') 
 
    .attr('stroke-width', '2px') 
 
    .attr('fill', function(d, i) { 
 
     return colour(d.weight) || 'black'; 
 
    }) 
 
    .call(force.drag) 
 

 
    var text = canvas.selectAll('.moviesText') 
 
    .data(nodes) 
 
    .enter() 
 
    .append('text') 
 
    .attr('text-anchor', 'middle') 
 
    .text(function(d) { 
 
     return d.movie; 
 
    }); 
 

 
    // Set up clip path for each forthcoming image node to clip rectangular images to circles. Then call images on the canvas. 
 

 
    var clip = canvas.selectAll('clipPath') 
 
    .data(nodes) 
 
    .enter() 
 
    .append('clipPath') 
 
    .attr('id', function(d) { 
 
     return rmWs(d.name) || rmWs(d.movie) 
 
    }) 
 
    .append('circle') 
 
    .attr('r', circleRadius); 
 

 
    var imgWidth = 50, 
 
    imgHeight = 50; 
 

 
    var node = canvas.selectAll('.node') 
 
    .data(nodes) 
 
    .enter() 
 
    .append('image') 
 
    .attr('xlink:href', function(d) { 
 
     return d.thumbnail; 
 
    }) 
 
    .attr("class", "image") 
 
    .attr("width", imgWidth) 
 
    .attr("height", imgHeight) 
 
    .attr("clip-path", function(d) { 
 
     return "url(#" + (rmWs(d.name) || rmWs(d.movie)) + ")" 
 
    }) 
 
    .call(force.drag); 
 

 
    // Handle operations on each tick. 
 

 
    force.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("x", function(d) { 
 
     return d.x - (imgWidth/2); 
 
     }) 
 
     .attr("y", function(d) { 
 
     return d.y - (imgHeight/2); 
 
     }); 
 

 
    clip.attr('cx', function(d) { 
 
     return d.x; 
 
     }) 
 
     .attr('cy', function(d) { 
 
     return d.y; 
 
     }) 
 

 
    circles.attr('cx', function(d) { 
 
     return d.x; 
 
     }) 
 
     .attr('cy', function(d) { 
 
     return d.y; 
 
     }) 
 

 
    text.attr('x', function(d) { 
 
     return d.x; 
 
     }) 
 
     .attr('y', function(d) { 
 
     return d.y - 30; 
 
     }) 
 
    }); 
 

 
    // When all initial calculations are done, print title to replace 'Loading . . .' 
 

 
    force.on('end', function() { 
 
    writeThis('#info', 'D3 Force Graph - Distance from Kevin Bacon', 100); 
 
    }) 
 
}
@import url(https://fonts.googleapis.com/css?family=Questrial' rel='stylesheet' type='text/css); 
 
#header { 
 
    text-align: center; 
 
    font-family: 'Jockey One', sans-serif; 
 
} 
 
#graph { 
 
    margin: 15px auto; 
 
    background: white; 
 
    height: 750px; 
 
    width: 750px; 
 
    -webkit-box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.75); 
 
    -moz-box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.75); 
 
    box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.75); 
 
} 
 
.link { 
 
    stroke: #777; 
 
    stroke-width: 2px; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.1/d3.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="header"> 
 
    <h2 id="info"></h2> 
 
</div> 
 
<div id="graph"></div>

+0

https://stackoverflow.com/questions/17286138/how-can-i-show-a-graph-using-d3-force-layout-with-initial-positions-set-and-no-m –

+0

を参照してください。こんにちは、私はそれを使用http://stackoverflow.com/questions/13463053/calm-down-initial-tick-of-a-force-layout。できます!ありがとう。 – user3896538

答えて

0

私は正確にあなたの問題を理解していなかったが、あなたは同じになります各サークルにはいくつかの場所は、あなたがコードを起動するたびに固定したいように見えます。 1つのアプローチは、属性(一部のJSONオブジェクトは多分?)としてデータの値を指定するか、CSSまたはjavascriptで操作します。どうやら彼らはxとyの値を無作為に得ています。

関連する問題