use of org.gephi.graph.api.Node in project gephi by gephi.
the class ScaleLayout method goAlgo.
@Override
public void goAlgo() {
graph = graphModel.getGraphVisible();
graph.readLock();
try {
double xMean = 0, yMean = 0;
for (Node n : graph.getNodes()) {
xMean += n.x();
yMean += n.y();
}
xMean /= graph.getNodeCount();
yMean /= graph.getNodeCount();
for (Node n : graph.getNodes()) {
double dx = (n.x() - xMean) * getScale();
double dy = (n.y() - yMean) * getScale();
n.setX((float) (xMean + dx));
n.setY((float) (yMean + dy));
}
setConverged(true);
} finally {
graph.readUnlockAll();
}
}
use of org.gephi.graph.api.Node in project gephi by gephi.
the class AddBehaviour method buildTree.
public static QuadTree buildTree(Graph graph, int maxLevel) {
float minX = Float.POSITIVE_INFINITY;
float maxX = Float.NEGATIVE_INFINITY;
float minY = Float.POSITIVE_INFINITY;
float maxY = Float.NEGATIVE_INFINITY;
for (Node node : graph.getNodes()) {
minX = Math.min(minX, node.x());
maxX = Math.max(maxX, node.x());
minY = Math.min(minY, node.y());
maxY = Math.max(maxY, node.y());
}
float size = Math.max(maxY - minY, maxX - minX);
QuadTree tree = new QuadTree(minX, minY, size, maxLevel);
for (Node node : graph.getNodes()) {
tree.addNode(node);
}
return tree;
}
use of org.gephi.graph.api.Node in project gephi by gephi.
the class YifanHuLayout method initAlgo.
@Override
public void initAlgo() {
if (graphModel == null) {
return;
}
graph = graphModel.getGraphVisible();
graph.readLock();
try {
energy = Float.POSITIVE_INFINITY;
for (Node n : graph.getNodes()) {
n.setLayoutData(new ForceVector());
}
progress = 0;
setConverged(false);
setStep(initialStep);
} finally {
graph.readUnlockAll();
}
}
use of org.gephi.graph.api.Node in project gephi by gephi.
the class Region method buildSubRegions.
public synchronized void buildSubRegions() {
if (nodes.size() > 1) {
ArrayList<Node> leftNodes = new ArrayList<>();
ArrayList<Node> rightNodes = new ArrayList<>();
for (Node n : nodes) {
ArrayList<Node> nodesColumn = (n.x() < massCenterX) ? (leftNodes) : (rightNodes);
nodesColumn.add(n);
}
ArrayList<Node> topleftNodes = new ArrayList<>();
ArrayList<Node> bottomleftNodes = new ArrayList<>();
for (Node n : leftNodes) {
ArrayList<Node> nodesLine = (n.y() < massCenterY) ? (topleftNodes) : (bottomleftNodes);
nodesLine.add(n);
}
ArrayList<Node> bottomrightNodes = new ArrayList<>();
ArrayList<Node> toprightNodes = new ArrayList<>();
for (Node n : rightNodes) {
ArrayList<Node> nodesLine = (n.y() < massCenterY) ? (toprightNodes) : (bottomrightNodes);
nodesLine.add(n);
}
if (topleftNodes.size() > 0) {
if (topleftNodes.size() < nodes.size()) {
Region subregion = new Region(topleftNodes);
subregions.add(subregion);
} else {
for (Node n : topleftNodes) {
ArrayList<Node> oneNodeList = new ArrayList<>();
oneNodeList.add(n);
Region subregion = new Region(oneNodeList);
subregions.add(subregion);
}
}
}
if (bottomleftNodes.size() > 0) {
if (bottomleftNodes.size() < nodes.size()) {
Region subregion = new Region(bottomleftNodes);
subregions.add(subregion);
} else {
for (Node n : bottomleftNodes) {
ArrayList<Node> oneNodeList = new ArrayList<>();
oneNodeList.add(n);
Region subregion = new Region(oneNodeList);
subregions.add(subregion);
}
}
}
if (bottomrightNodes.size() > 0) {
if (bottomrightNodes.size() < nodes.size()) {
Region subregion = new Region(bottomrightNodes);
subregions.add(subregion);
} else {
for (Node n : bottomrightNodes) {
ArrayList<Node> oneNodeList = new ArrayList<>();
oneNodeList.add(n);
Region subregion = new Region(oneNodeList);
subregions.add(subregion);
}
}
}
if (toprightNodes.size() > 0) {
if (toprightNodes.size() < nodes.size()) {
Region subregion = new Region(toprightNodes);
subregions.add(subregion);
} else {
for (Node n : toprightNodes) {
ArrayList<Node> oneNodeList = new ArrayList<>();
oneNodeList.add(n);
Region subregion = new Region(oneNodeList);
subregions.add(subregion);
}
}
}
for (Region subregion : subregions) {
subregion.buildSubRegions();
}
}
}
use of org.gephi.graph.api.Node in project gephi by gephi.
the class FruchtermanReingold method goAlgo.
@Override
public void goAlgo() {
this.graph = graphModel.getGraphVisible();
graph.readLock();
try {
Node[] nodes = graph.getNodes().toArray();
Edge[] edges = graph.getEdges().toArray();
for (Node n : nodes) {
if (n.getLayoutData() == null || !(n.getLayoutData() instanceof ForceVectorNodeLayoutData)) {
n.setLayoutData(new ForceVectorNodeLayoutData());
}
ForceVectorNodeLayoutData layoutData = n.getLayoutData();
layoutData.dx = 0;
layoutData.dy = 0;
}
// Déplacement limite : on peut le calibrer...
float maxDisplace = (float) (Math.sqrt(AREA_MULTIPLICATOR * area) / 10f);
// La variable k, l'idée principale du layout.
float k = (float) Math.sqrt((AREA_MULTIPLICATOR * area) / (1f + nodes.length));
for (Node N1 : nodes) {
for (Node N2 : nodes) {
// On fait toutes les paires de noeuds
if (N1 != N2) {
// distance en x entre les deux noeuds
float xDist = N1.x() - N2.x();
float yDist = N1.y() - N2.y();
// distance tout court
float dist = (float) Math.sqrt(xDist * xDist + yDist * yDist);
if (dist > 0) {
// Force de répulsion
float repulsiveF = k * k / dist;
ForceVectorNodeLayoutData layoutData = N1.getLayoutData();
// on l'applique...
layoutData.dx += xDist / dist * repulsiveF;
layoutData.dy += yDist / dist * repulsiveF;
}
}
}
}
for (Edge E : edges) {
// Idem, pour tous les noeuds on applique la force d'attraction
Node Nf = E.getSource();
Node Nt = E.getTarget();
float xDist = Nf.x() - Nt.x();
float yDist = Nf.y() - Nt.y();
float dist = (float) Math.sqrt(xDist * xDist + yDist * yDist);
float attractiveF = dist * dist / k;
if (dist > 0) {
ForceVectorNodeLayoutData sourceLayoutData = Nf.getLayoutData();
ForceVectorNodeLayoutData targetLayoutData = Nt.getLayoutData();
sourceLayoutData.dx -= xDist / dist * attractiveF;
sourceLayoutData.dy -= yDist / dist * attractiveF;
targetLayoutData.dx += xDist / dist * attractiveF;
targetLayoutData.dy += yDist / dist * attractiveF;
}
}
// gravity
for (Node n : nodes) {
ForceVectorNodeLayoutData layoutData = n.getLayoutData();
float d = (float) Math.sqrt(n.x() * n.x() + n.y() * n.y());
float gf = 0.01f * k * (float) gravity * d;
layoutData.dx -= gf * n.x() / d;
layoutData.dy -= gf * n.y() / d;
}
// speed
for (Node n : nodes) {
ForceVectorNodeLayoutData layoutData = n.getLayoutData();
layoutData.dx *= speed / SPEED_DIVISOR;
layoutData.dy *= speed / SPEED_DIVISOR;
}
for (Node n : nodes) {
// Maintenant on applique le déplacement calculé sur les noeuds.
// nb : le déplacement à chaque passe "instantanné" correspond à la force : c'est une sorte d'accélération.
ForceVectorNodeLayoutData layoutData = n.getLayoutData();
float xDist = layoutData.dx;
float yDist = layoutData.dy;
float dist = (float) Math.sqrt(layoutData.dx * layoutData.dx + layoutData.dy * layoutData.dy);
if (dist > 0 && !n.isFixed()) {
float limitedDist = Math.min(maxDisplace * ((float) speed / SPEED_DIVISOR), dist);
n.setX(n.x() + xDist / dist * limitedDist);
n.setY(n.y() + yDist / dist * limitedDist);
}
}
} finally {
graph.readUnlockAll();
}
}
Aggregations