在带有强制模块的D3 v4中,初始化图形后如何更新模拟参数?
更确切地说,当用户点击其中一个节点时,我正在尝试更改力导向图的 <?php session_start();
try {
//$con= new PDO('mysql:host=localhost;dbname=wydania_tonery', "sa", "sql");
$zmien_kodowanie = $dbo->query("SET names 'utf8'");
$sesja = $_SESSION['username'];
$query = "SELECT
mdl_user.firstname AS 'Imie',
mdl_user.lastname AS 'Nazwisko',
mdl_user.department AS 'Akronim',
reg.data AS 'Region',
sta.data AS 'Stanowisko',
mdl_user.aim AS 'Stan',
NULLIF('Uwagi', 0) AS 'Uwagi'
FROM
mdl_user
LEFT JOIN
mdl_user_info_data AS reg ON reg.userid=mdl_user.id AND reg.fieldid='2'
LEFT JOIN
mdl_user_info_data AS sta ON sta.userid=mdl_user.id AND sta.fieldid='4'
WHERE
mdl_user.email LIKE 'kierownik.%' AND mdl_user.deleted='0' AND mdl_user_info_data.fieldid = ".$_SESSION['username']." /*AND mdl_user.department='BBT'*/
ORDER BY
mdl_user.department ASC";
//first pass just gets the column name
echo "<table> \n";
$result = $dbo->query($query);
//return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
print " <tr> \n";
foreach ($row as $field => $value){
print " <th>$field</th> \n";
} // end foreach
print " </tr> \n";
//second query gets the data
$data = $dbo->query($query);
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach($data as $row){
print " <tr> \n";
foreach ($row as $name=>$value){
print " <td>$value</td> \n";
} // end field loop
print " </tr> \n";
} // end record loop
print "</table> \n";
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
} // end try
?>
和.forceLink
。
.forceManyBody
到目前为止,我已经能够通过在connectedNodes函数下复制模拟来更新它:
var node = svg
.append("g")
.attr("class", "gnodes")
.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("class", "node")
.on('dblclick', connectedNodes); //calls for change in simulation parameters
虽然这有效,但它非常多余。有没有一种方法可以使用新参数刷新模拟?我尝试了以下但它不起作用
function connectedNodes() {
//new parameters
linkDistance = 5;
fCharge = -10;
//replicates the initial simulation code
simulation = d3.forceSimulation()
.force("link", d3.forceLink()
.id(function(d) {return d.id;})
.distance(linkDistance)
)
.force("collide", d3.forceCollide()
.radius(function(d){return d.r + 10})
.strength(1)
)
.force("charge", d3.forceManyBody()
.strength(fCharge)
)
.force("center", d3.forceCenter(width / 2, height / 2));
simulation.nodes(graph.nodes).on("tick", ticked);
simulation.force("link").links(graph.links);
答案 0 :(得分:5)
您需要引用要更新的力量。这可以使用以下两种方式之一完成:
正如Cool Blue comment所指出的那样,您可以通过调用simulation.force()
仅仅传递其注册的部队名称来轻松获得对部队的引用在第一位。据说,如果我们创建了我们的模拟,同时传递了一个匿名的就地力量,如下所示:
var simulation = d3.forceSimulation()
.force("link", d3.forceLink() // "link" is the name to register the force
.id(function(d) { return d.id; })
.distance(linkDistance)
);
稍后可以在需要时通过其名称获取力:
var forceLink = simulation.force("link"); // Get the force by its name
就个人而言,我喜欢这种方法,并且只要有可能,我会更喜欢第二种方法,因为我不喜欢有很多引用/变量。
创建时保持对力的引用。
var forceLink = d3.forceLink() // Keep a reference to the force
.id(function(d) { return d.id; })
.distance(linkDistance);
var simulation = d3.forceSimulation()
.force("link", forceLink ) // Pass the reference when creating the simulation
无论您选择哪种方式,您都可以通过执行类似
的操作来更新您的力量linkDistance += 10;
forceLink.distance(linkDistance);
一旦计算下一个滴答,这将考虑新值。如果模拟已经停止,或者您只是想再次加热,可以致电
simulation.alpha(1).restart();
我已设置example,当您将鼠标悬停在SVG上时会显示这些实时更新。这将更新linkDistance
并重新启动力布局。