我一直在尝试减少我正在处理的d3项目中的动画量。
到目前为止,我尝试使用各种内置函数来抑制动画的力量。例如alpha(.1) gravity(1) charge(-1000)
虽然其中一些功能似乎没有产生巨大的差异。
最终结果: 我想尝试消除动画开始时的巨大反弹。这可能吗?
这是我的完整js功能:
// return data for relationships between database tables
returnTableRelationshipData = function(){
data = {
"nodes":[
{
"platform":"Source DB",
"description":"RELATIONSHIPS BETWEEN BUSINESS REFERENCES",
"ingested":"No",
"tableId":"RELAC_REFER",
"level1":"DAEG",
"level2":"url",
"nodeId":0
},
{
"platform":"Source DB",
// see jsfiddle for full data
]
};
//find the node index
function find(f){
var i = -1
data.nodes.forEach(function(node, index){
if(node.nodeId == f)
i = index;
});
return i;
}
//set the source and target index
data.links.forEach(function(d){
d.source = find(d.source);
d.target = find(d.target);
})
// 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 = 600,
h = 500;
var force = d3.layout.force()
.nodes(data.nodes)
.links(data.links)
.alpha(.1)
.gravity(1)
//.distance(150)
.charge(-1000)
.size([w, h])
.start();
var svg = d3.select(".graphContainer").append("svg: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.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;
});
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; });
/*circle.on("mousedown", function(d) { d.fixed = true; });*/
force.on("tick", tick);
function tick() {
path.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;
});
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) {
//nodes.fixed = true; // fix all nodes after single drag
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
tick();
force.resume();
}
// sort the links by source, then target
function sortLinks(){
if(data.links != null){
data.links.sort(function(a,b){
if(a.source > b.source){
return 1;
}else if(a.source < b.source){
return -1;
}else{
if(a.target > b.target){
return 1;
}if(a.target < b.target){
return -1;
}else{
return 0;
}
}
});
}
}
//any links with duplicate source and target get an incremented 'linknum'
function setLinkIndexAndNum(){
for(var i = 0; i < data.links.length; i++){
if(i != 0 &&
data.links[i].source == data.links[i-1].source &&
data.links[i].target == data.links[i-1].target){
data.links[i].linkindex = data.links[i-1].linkindex + 1;
}else{
data.links[i].linkindex = 1;
}// save the total number of links between two nodes
if(mLinkNum[data.links[i].target + "," + data.links[i].source] !== undefined){
mLinkNum[data.links[i].target + "," + data.links[i].source] = data.links[i].linkindex;
}else{
mLinkNum[data.links[i].source + "," + data.links[i].target] = data.links[i].linkindex;
}
}
}
function checkDataNotEmpty(){
data.links.forEach(function(link, index, list) {
if (typeof link.source === 'undefined') {
console.log('undefined link', data.nodes[link.source]);
}
if (typeof link.target === 'undefined') {
console.log('undefined source', data.nodes[link.target]);
}
});
}
}
returnTableRelationshipData();
链接到jsfiddle
我尝试将原始代码与SO问题here合并,并链接了jsbin here
我设法将未分类的库发布到pastebin,然后将其链接到jsfiddle,以供参考,这里是完整的js库:Unminified d3 Library v3
看起来好像动画功能从第5807行开始
var d3_ease_default = function() {
return d3_identity;
};
我已经尝试评论了很多这些功能,动画似乎没有变化。
我意识到这不是最好的问题,但如果有人有这方面的经验,我会非常感激。
此外,我很高兴使用固定节点,但我认为它们只能在强制动画完成后修复。
答案 0 :(得分:3)
这种巨大反弹的原因之一是所有节点都在同一位置开始模拟。
尝试传播它们:
data.nodes.forEach(function(node){
node.x = 200 + Math.random()*200;
node.y = 150 + Math.random()*200;
}
此处,幻数200
和150
只是w/2
和h/2
减去100
。
这是更新的小提琴:https://jsfiddle.net/nd8e5m9s/
答案 1 :(得分:1)
你强制dgendlay在dragend上强制到某个坐标点并让它反弹,为什么不删除
function dragend(d, i) {
//nodes.fixed = true; // fix all nodes after single drag
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
tick();
//force.resume();
}