Hi Stackoverflow Community!Динамически изменяет размер div, когда он используется как узел в d3-силовом графике
Итак, моя проблема заключается в следующем:
У меня есть d3 сила-ориентированный граф. Узлы этого графа являются div. Теперь я хочу, чтобы иметь возможность изменять размер этого divs с помощью мыши. Для этой цели я использую jqueryui resizable().
К сожалению, это делает изменения ui (когда я достигаю краев узла, я получаю mousesymbol для изменения размера), но я не могу изменять их размер. Я считаю, что это потому, что d3-forcegraph накладывает функцию jqueryui. Я попытался остановить график, чтобы получить доступ к функциям изменения размера, но это, похоже, не сработает.
Есть ли у кого-нибудь идеи, как я могу сделать эти divs изменяемыми по размеру? Я создал скрипку, чтобы показать, что я имею в виду: https://jsfiddle.net/5jgrf5h8/
//constants for the network visualisation
var height = window.innerHeight-20; //fullsize svg
var width = window.innerWidth-20;
var nodes = [
{"id": "RootNode", "group": 0},
{"id": "Node1",
"ip_adresses": [
{"ip_adress": "aa.bbb.114.80/28"}
],
"group": 1},
{"id": "Node2",
"ip_adresses": [
{"ip_adress": "aa.bbb.117.96/28"}
],
"group": 1},
{"id": "Node3",
"ip_adresses": [
{"ip_adress": "eeee:ffff:400:3001::7"},
{"ip_adress": "eeee:ffff:400:3001::8"},
{"ip_adress": "eeee:ffff:400:3001::9"},
{"ip_adress": "eeee:ffff:400:3001::10"},
{"ip_adress": "eeee:ffff:400:3001::11"},
{"ip_adress": "eeee:ffff:400:3001::12"},
{"ip_adress": "eeee:ffff:400:3001::13"},
{"ip_adress": "eeee:ffff:400:3001::14"},
{"ip_adress": "eeee:ffff:400:3001::15"},
{"ip_adress": "eeee:ffff:400:3001::16"},
{"ip_adress": "eeee:ffff:400:3001::17"}
],
"group": 1},
{"id": "Node4",
"ip_adresses": [
{"ip_adress": "cc.dd38.151"},
{"ip_adress": "cc.dd38.152"}
],
"group": 1},
{"id": "Node5",
"ip_adresses": [
{"ip_adress": "aa.bbb.114.36"},
{"ip_adress": "aa.bbb.114.37"}
],
"group": 1}
];
var links = [
{"source": "RootNode", "target": "Node1", "value": 140},
{"source": "RootNode", "target": "Node2", "value": 140},
{"source": "RootNode", "target": "Node3", "value": 140},
{"source": "RootNode", "target": "Node4", "value": 140},
{"source": "RootNode", "target": "Node5", "value": 140}
];
var color = d3.scaleOrdinal(d3.schemeCategory10);
//creating and configuring the d3 force-directed graph simulation
var simulation = d3.forceSimulation()
.force("charge", d3.forceManyBody().strength(-2000))
.force("center", d3.forceCenter(width/2, height/2))
.force("link", d3.forceLink()
.distance(function(d){return d.value;})
.strength(1.3).id(function(d){return d.id;}));
//create a svg in the body of index.html
var svg = d3.select("body").append("svg")
.classed("simulation", 1)
.attr("width", width)
.attr("height", height);
//setting the links
var glink = svg.append("g")
.attr("class", "links")
.selectAll("links")
.data(links).enter();
var link = glink.append("polyline")
.attr("stroke-width", 2);
//setting the nodes. they will be div elements
var node = d3.select("body")
.append("div")
.attr("class", "nodes")
.selectAll(".node")
.data(nodes)
.enter().append("div")
.attr("class", "node")
.attr("id", function(d){return d.id;})
.style("background", function(d) { return color(d.group); });
node.each(function (d, i){
if(d.group === 1)
{
console.log(d.id, i, d3.select(this).attr("id"));
d3.select(this).append("select")
.attr("size", 2)
.selectAll('option')
.data(nodes[i].ip_adresses)
.enter()
.append("option")
.text(function(d){return d.ip_adress;});
}
else
{
d3.select(this).text(function (d){return d.id;});
}
});
//start the simulation
node.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
//assigning data to the simulation and set tick
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
function ticked() {
link.attr("points", function(d) {
var sourceX = d.source.x;
var sourceY = d.source.y;
var targetX = d.target.x;
var targetY = d.target.y;
return sourceX + "," + sourceY + " " +
(sourceX + targetX)/2 + "," + (sourceY + targetY)/2 + " " +
targetX + ", " + targetY;
});
node.style('left', function(d ,i) {
return d.x-$("[id='"+d.id+"']").outerWidth()/2+"px";
})
.style('top', function(d) {
return d.y-$("[id='"+d.id+"']").outerHeight()/2+"px";
});
}
d3.select("body").selectAll("option").on("dblclick", function(){
alert(this.text);
});
//this would be nice but it is not working in the d3 graph
$(".node").resizable();
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
d.fixed = true;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
Привет Кирилл! Теперь изменение размера действительно работает, поскольку оно задумано спасибо за вашу помощь здесь! Однако из-за удаления событий перетаскивания он имеет недостаток, что узлы больше не могут перемещаться. Есть ли способ поддерживать перетаскивание узлов? –
ну, извините, я думаю, что у вас не может быть лучшего из обоих миров :). Может быть, кнопка или что-то добавить перетащить прослушиватели, а затем отменить ее при изменении размера. – Cyril
Okay :) Итак, теперь я нашел способ удалить прослушиватель drag-list для одного узла, используя эту строку d3.select ('# Node1'). On ('. Drag', null); , Это отключает перетаскивание для Node1 и делает его изменяемым по размеру. К сожалению, я не могу принести элемент-перехватчик обратно на элемент. Я попытался использовать ** var dragCallback = d3.select ('# Node1'). Свойство ('__ onmousedown.drag') ['_']; **, а затем has3.select ('# Node1'). on ('mousedown.drag', dragCallback); но я уже получаю сообщение: Uncaught TypeError: Невозможно прочитать свойство «_» неопределенного. –