use of org.cytoscape.view.layout.LayoutNode in project cytoscape-impl by cytoscape.
the class ForceDirectedLayoutTask method layoutPartition.
public void layoutPartition(LayoutPartition part) {
LayoutPoint initialLocation = null;
// System.out.println("layoutPartion: "+part.getEdgeList().size()+" edges");
// Calculate our edge weights
part.calculateEdgeWeights();
// System.out.println("layoutPartion: "+part.getEdgeList().size()+" edges after calculateEdgeWeights");
// m_fsim.setIntegrator(integrator.getNewIntegrator());
// m_fsim.clear();
m_fsim = new ForceSimulator();
m_fsim.addForce(new NBodyForce());
m_fsim.addForce(new SpringForce());
m_fsim.addForce(new DragForce());
forceItems.clear();
List<LayoutNode> nodeList = part.getNodeList();
List<LayoutEdge> edgeList = part.getEdgeList();
if (context.isDeterministic) {
Collections.sort(nodeList);
Collections.sort(edgeList);
}
// initialize nodes
for (LayoutNode ln : nodeList) {
ForceItem fitem = forceItems.get(ln);
if (fitem == null) {
fitem = new ForceItem();
forceItems.put(ln, fitem);
}
fitem.mass = getMassValue(ln);
fitem.location[0] = 0f;
fitem.location[1] = 0f;
m_fsim.addItem(fitem);
}
// initialize edges
for (LayoutEdge e : edgeList) {
LayoutNode n1 = e.getSource();
ForceItem f1 = forceItems.get(n1);
LayoutNode n2 = e.getTarget();
ForceItem f2 = forceItems.get(n2);
if (f1 == null || f2 == null)
continue;
m_fsim.addSpring(f1, f2, getSpringCoefficient(e), getSpringLength(e));
}
// setTaskStatus(5); // This is a rough approximation, but probably good enough
if (taskMonitor != null) {
taskMonitor.setStatusMessage("Initializing partition " + part.getPartitionNumber());
}
// Figure out our starting point
initialLocation = part.getAverageLocation();
// perform layout
long timestep = 1000L;
for (int i = 0; i < context.numIterations && !cancelled; i++) {
timestep *= (1.0 - i / (double) context.numIterations);
long step = timestep + 50;
m_fsim.runSimulator(step);
setTaskStatus((int) (((double) i / (double) context.numIterations) * 90. + 5));
}
// update positions
// reset the nodes so we get the new average location
part.resetNodes();
for (LayoutNode ln : part.getNodeList()) {
if (!ln.isLocked()) {
ForceItem fitem = forceItems.get(ln);
ln.setX(fitem.location[0]);
ln.setY(fitem.location[1]);
part.moveNodeToLocation(ln);
}
}
}
use of org.cytoscape.view.layout.LayoutNode in project cytoscape-impl by cytoscape.
the class BioLayoutKKAlgorithmTask method calculatePartials.
private PartialDerivatives calculatePartials(PartialDerivatives partials, List partialsList, double[] potentialEnergy, boolean reversed) {
partials.reset();
LayoutNode node = partials.node;
// How does this ever get to be > 0?
// Get the node size from the nodeView?
double nodeRadius = node.getWidth() / 2;
double nodeX = node.getX();
double nodeY = node.getY();
PartialDerivatives otherPartials = null;
LayoutNode otherNode;
double otherNodeRadius;
PartialDerivatives furthestPartials = null;
Iterator iterator;
if (partialsList == null)
iterator = partition.nodeIterator();
else
iterator = partialsList.iterator();
double deltaX;
double deltaY;
double otherNodeX;
double otherNodeY;
double euclideanDistance;
double euclideanDistanceCubed;
double distanceFromRest;
double distanceFromTouching;
double incrementalChange;
double[] xTable = { .01, .01, -.01, -.01 };
double[] yTable = { .01, -.01, .01, -.01 };
int offsetTable = 0;
int nodeIndex = node.getIndex();
while (iterator.hasNext()) {
if (partialsList == null) {
otherNode = (LayoutNode) iterator.next();
} else {
otherPartials = (PartialDerivatives) iterator.next();
otherNode = otherPartials.node;
}
if (node == otherNode)
continue;
// How does this every get to be > 0?
// Get the node size from the nodeView?
otherNodeRadius = otherNode.getWidth() / 2;
otherNodeX = otherNode.getX();
otherNodeY = otherNode.getY();
deltaX = nodeX - otherNodeX;
deltaY = nodeY - otherNodeY;
euclideanDistance = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
if (((float) euclideanDistance) < 0.0001) {
otherNodeX = otherNodeX + xTable[offsetTable];
otherNodeY = otherNodeY + yTable[offsetTable++];
if (offsetTable > 3)
offsetTable = 0;
otherNode.setX(otherNodeX);
otherNode.setY(otherNodeY);
euclideanDistance = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY));
}
/*
System.out.println("nodeX = "+nodeX);
System.out.println("nodeY = "+nodeY);
System.out.println("otherNodeX = "+otherNode.getX());
System.out.println("otherNodeY = "+otherNode.getY());
*/
int otherNodeIndex = otherNode.getIndex();
double radius = nodeRadius + otherNodeRadius;
euclideanDistanceCubed = euclideanDistance * euclideanDistance * euclideanDistance;
distanceFromTouching = euclideanDistance - (nodeRadius + otherNodeRadius);
distanceFromRest = (euclideanDistance - m_nodeDistanceSpringRestLengths[nodeIndex][otherNodeIndex]);
// calculationProfile.start();
if (!reversed) {
partials.x += calculateSpringPartial(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistance, deltaX, radius);
partials.y += calculateSpringPartial(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistance, deltaY, radius);
partials.xx += calculateSpringPartial3(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaY * deltaY, radius);
partials.yy += calculateSpringPartial3(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaX * deltaX, radius);
partials.xy += calculateSpringPartialCross(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaX * deltaY, radius);
potentialEnergy[0] += calculatePE(m_layoutPass, distanceFromRest, distanceFromTouching, nodeIndex, otherNodeIndex);
}
if (otherPartials != null) {
if (!reversed) {
otherPartials.x += calculateSpringPartial(m_layoutPass, distanceFromTouching, otherNodeIndex, nodeIndex, euclideanDistance, -deltaX, radius);
otherPartials.y += calculateSpringPartial(m_layoutPass, distanceFromTouching, otherNodeIndex, nodeIndex, euclideanDistance, -deltaY, radius);
otherPartials.xx += calculateSpringPartial3(m_layoutPass, distanceFromTouching, otherNodeIndex, nodeIndex, euclideanDistanceCubed, deltaY * deltaY, radius);
otherPartials.yy += calculateSpringPartial3(m_layoutPass, distanceFromTouching, otherNodeIndex, nodeIndex, euclideanDistanceCubed, deltaX * deltaX, radius);
otherPartials.xy += calculateSpringPartialCross(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaX * deltaY, radius);
potentialEnergy[0] += calculatePE(m_layoutPass, distanceFromRest, distanceFromTouching, nodeIndex, otherNodeIndex);
} else {
otherPartials.x -= calculateSpringPartial(m_layoutPass, distanceFromTouching, otherNodeIndex, nodeIndex, euclideanDistance, -deltaX, radius);
otherPartials.y -= calculateSpringPartial(m_layoutPass, distanceFromTouching, otherNodeIndex, nodeIndex, euclideanDistance, -deltaY, radius);
otherPartials.xx -= calculateSpringPartial3(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaY * deltaY, radius);
otherPartials.yy -= calculateSpringPartial3(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaX * deltaX, radius);
otherPartials.xy -= calculateSpringPartialCross(m_layoutPass, distanceFromTouching, nodeIndex, otherNodeIndex, euclideanDistanceCubed, deltaX * deltaY, radius);
potentialEnergy[0] -= calculatePE(m_layoutPass, distanceFromRest, distanceFromTouching, nodeIndex, otherNodeIndex);
}
// Update the euclidean distance
otherPartials.euclideanDistance = Math.sqrt((otherPartials.x * otherPartials.x) + (otherPartials.y * otherPartials.y));
if ((furthestPartials == null) || (otherPartials.euclideanDistance > furthestPartials.euclideanDistance))
furthestPartials = otherPartials;
}
// calculationProfile.checkpoint();
}
if (!reversed)
partials.euclideanDistance = Math.sqrt((partials.x * partials.x) + (partials.y * partials.y));
if ((furthestPartials == null) || (partials.euclideanDistance > furthestPartials.euclideanDistance))
furthestPartials = partials;
return furthestPartials;
}
use of org.cytoscape.view.layout.LayoutNode in project cytoscape-impl by cytoscape.
the class BioLayoutKKAlgorithmTask method layoutPartition.
/**
* Perform a layout
*/
public void layoutPartition(LayoutPartition partition) {
LayoutPoint initialLocation = null;
this.partition = partition;
// Initialize all of our values. This will create
// our internal objects and initialize them
// local_initialize();
m_nodeCount = partition.nodeCount();
// Set defaults -- this is done here insted of in the constructor
// to allow users to change m_numLayoutPasses
m_nodeDistanceSpringScalars = new double[m_numLayoutPasses];
for (int i = 0; i < m_numLayoutPasses; i++) m_nodeDistanceSpringScalars[i] = 1.0;
m_anticollisionSpringScalars = new double[m_numLayoutPasses];
m_anticollisionSpringScalars[0] = 0.0;
for (int i = 1; i < m_numLayoutPasses; i++) m_anticollisionSpringScalars[i] = 1.0;
// System.out.println("BioLayoutKK Algorithm. Laying out " + m_nodeCount + " nodes and "
// + partition.edgeCount() + " edges: ");
/*
for (Iterator diter = partition.nodeIterator(); diter.hasNext(); ) {
System.out.println("\t"+(LayoutNode)diter.next());
}
for (Iterator diter = partition.edgeIterator(); diter.hasNext(); ) {
System.out.println("\t"+(LayoutEdge)diter.next());
}
*/
// Calculate a distance threshold
double euclideanDistanceThreshold = (m_nodeCount + partition.edgeCount()) / 10;
int numIterations = (int) ((m_nodeCount * m_averageIterationsPerNode) / m_numLayoutPasses);
List<PartialDerivatives> partialsList = new ArrayList<PartialDerivatives>();
double[] potentialEnergy = new double[1];
if (potentialEnergy[0] != 0.0)
throw new RuntimeException();
PartialDerivatives partials;
PartialDerivatives furthestNodePartials = null;
m_nodeDistanceSpringRestLengths = new double[m_nodeCount][m_nodeCount];
m_nodeDistanceSpringStrengths = new double[m_nodeCount][m_nodeCount];
// Figure out our starting point
initialLocation = partition.getAverageLocation();
// outside of our bounds
if (context.randomize)
partition.randomizeLocations();
// Calculate our edge weights
partition.calculateEdgeWeights();
// Compute our distances
if (cancelled)
return;
taskMonitor.setProgress(0.02);
taskMonitor.setStatusMessage("Calculating node distances");
int[][] nodeDistances = calculateNodeDistances();
if (cancelled)
return;
taskMonitor.setProgress(0.04);
taskMonitor.setStatusMessage("Calculating spring constants");
calculateSpringData(nodeDistances);
final double percentCompletedBeforePasses = 5.0d;
final double percentCompletedAfterPass1 = 60.0d;
final double percentCompletedAfterFinalPass = 95.0d;
double currentProgress = percentCompletedBeforePasses;
// Compute our optimal lengths
for (m_layoutPass = 0; m_layoutPass < m_numLayoutPasses; m_layoutPass++) {
final double percentProgressPerIter;
Profile passTimer = new Profile();
passTimer.start();
if (m_layoutPass == 0) {
percentProgressPerIter = (percentCompletedAfterPass1 - percentCompletedBeforePasses) / (double) (m_nodeCount + numIterations);
} else {
percentProgressPerIter = (percentCompletedAfterFinalPass - percentCompletedAfterPass1) / (double) ((m_nodeCount + numIterations) * (m_numLayoutPasses - 1));
}
// Initialize this layout pass.
potentialEnergy[0] = 0.0;
partialsList.clear();
furthestNodePartials = null;
taskMonitor.setStatusMessage("Calculating partial derivatives -- pass " + (m_layoutPass + 1) + " of " + m_numLayoutPasses);
// Calculate all node distances. Keep track of the furthest.
for (LayoutNode v : partition.getNodeList()) {
if (cancelled)
return;
taskMonitor.setProgress(currentProgress / 100.0);
if (v.isLocked())
continue;
partials = new PartialDerivatives(v);
calculatePartials(partials, null, potentialEnergy, false);
// System.out.println(partials.printPartial()+" potentialEnergy = "+potentialEnergy[0]);
partialsList.add(partials);
if ((furthestNodePartials == null) || (partials.euclideanDistance > furthestNodePartials.euclideanDistance)) {
furthestNodePartials = partials;
}
currentProgress += percentProgressPerIter;
}
// partialProfile.done("Partial time for pass "+(m_layoutPass+1)+" is ");
taskMonitor.setStatusMessage("Executing spring logic -- pass " + (m_layoutPass + 1) + " of " + m_numLayoutPasses);
// springProfile.start();
for (int iterations_i = 0; (iterations_i < numIterations) && (furthestNodePartials.euclideanDistance >= euclideanDistanceThreshold); iterations_i++) {
if (cancelled)
return;
taskMonitor.setProgress(currentProgress / 100.0);
furthestNodePartials = moveNode(furthestNodePartials, partialsList, potentialEnergy);
// System.out.println(furthestNodePartials.printPartial()+" (furthest) potentialEnergy = "+potentialEnergy[0]);
currentProgress += percentProgressPerIter;
}
// springProfile.done("Spring time for pass "+(m_layoutPass+1)+" is ");
}
taskMonitor.setProgress(percentCompletedAfterFinalPass / 100.0);
taskMonitor.setStatusMessage("Updating display");
// Actually move the pieces around
// Note that we reset our min/max values before we start this
// so we can get an accurate min/max for paritioning
partition.resetNodes();
for (LayoutNode v : partition.getNodeList()) {
partition.moveNodeToLocation(v);
}
// Not quite done, yet. If we're only laying out selected nodes, we need
// to migrate the selected nodes back to their starting position
double xDelta = 0.0;
double yDelta = 0.0;
final LayoutPoint finalLocation = partition.getAverageLocation();
xDelta = finalLocation.getX() - initialLocation.getX();
yDelta = finalLocation.getY() - initialLocation.getY();
partition.resetNodes();
for (LayoutNode v : partition.getNodeList()) {
if (!v.isLocked()) {
v.decrement(xDelta, yDelta);
partition.moveNodeToLocation(v);
}
}
}
use of org.cytoscape.view.layout.LayoutNode in project cytoscape-impl by cytoscape.
the class AttributeCircleLayoutTask method layoutPartition.
/**
* DOCUMENT ME!
*
* @param partition DOCUMENT ME!
*/
public void layoutPartition(LayoutPartition partition) {
// just add the unlocked nodes
List<LayoutNode> nodes = new ArrayList<LayoutNode>();
for (LayoutNode ln : partition.getNodeList()) {
if (!ln.isLocked()) {
nodes.add(ln);
}
}
int count = nodes.size();
int r = (int) Math.sqrt(count);
r *= context.spacing;
if (layoutAttribute != null && count > 0) {
final CyColumn column = nodes.get(0).getRow().getTable().getColumn(layoutAttribute);
Class<?> klass = (column == null) ? null : column.getType();
if (klass != null && Comparable.class.isAssignableFrom(klass)) {
// FIXME: I assume this would be better, but get type errors if I try:
// Class<Comparable<?>> kasted = (Class<Comparable<?>>) klass;
// Collections.sort(nodes, new AttributeComparator<Comparable<?>>(kasted));
Collections.sort(nodes, new AttributeComparator(klass));
} else {
/* FIXME Error. */
}
}
// Compute angle step
double phi = (2 * Math.PI) / count;
// We want to figure out our mins & maxes anew
partition.resetNodes();
for (int i = 0; i < count; i++) {
LayoutNode node = (LayoutNode) nodes.get(i);
double x = r + (r * Math.sin(i * phi));
double y = r + (r * Math.cos(i * phi));
node.setX(x);
node.setY(y);
partition.moveNodeToLocation(node);
}
}
use of org.cytoscape.view.layout.LayoutNode in project cytoscape-impl by cytoscape.
the class CircularLayoutAlgorithmTask method layoutPartition.
@Override
public void layoutPartition(LayoutPartition partition) {
if (cancelled)
return;
final int numNodes = partition.nodeCount();
if (numNodes == 1) {
// We were asked to do a circular layout of a single node -- done!
return;
}
nodeViews = new HashMap<Integer, View<CyNode>>(numNodes);
Map<CyNode, Integer> nodeIdexMap = new HashMap<CyNode, Integer>();
int nodeIndex = 0;
Iterator<LayoutNode> nodeIter = partition.getNodeList().iterator();
while (nodeIter.hasNext() && !cancelled) {
// final View<CyNode> nv = nodeIter.next().getNodeView();
LayoutNode ln = nodeIter.next();
if (ln.isLocked())
continue;
final View<CyNode> nv = ln.getNodeView();
nodeViews.put(nodeIndex, nv);
nodeIdexMap.put(nv.getModel(), nodeIndex);
nodeIndex++;
}
if (cancelled)
return;
/* create edge list from edges between selected nodes */
final List<Edge> edges = new LinkedList<Edge>();
final Iterator<LayoutEdge> edgeIter = partition.edgeIterator();
while (edgeIter.hasNext() && !cancelled) {
final LayoutEdge ev = edgeIter.next();
final Integer edgeFrom = nodeIdexMap.get(ev.getEdge().getSource());
final Integer edgeTo = nodeIdexMap.get(ev.getEdge().getTarget());
if ((edgeFrom == null) || (edgeTo == null))
continue;
edges.add(new Edge(edgeFrom, edgeTo));
edges.add(new Edge(edgeTo, edgeFrom));
}
nodeIdexMap.clear();
nodeIdexMap = null;
if (cancelled)
return;
/* find horizontal and vertical coordinates of each node */
final Edge[] edge = new Edge[edges.size()];
edges.toArray(edge);
final Graph graph = new Graph(numNodes, edge);
if (cancelled)
return;
// all false
posSet = new boolean[nodeViews.size()];
// all false
depthPosSet = new boolean[nodeViews.size()];
bc = graph.biconnectedComponents();
int maxSize = -1;
int maxIndex = -1;
for (int i = 0; i < bc.length; i++) if (bc[i].length > maxSize) {
maxSize = bc[i].length;
maxIndex = i;
}
if (maxIndex == -1)
return;
if (cancelled)
return;
drawnBiComps = new boolean[bc.length];
node2BiComp = new HashMap<Integer, Integer>();
for (int i = 0; i < bc.length; i++) if (bc[i].length > 3) {
for (int j = 0; j < bc[i].length; j++) {
node2BiComp.put(bc[i][j], i);
}
}
final double radius = (48 * maxSize) / (2 * Math.PI);
final double deltaAngle = (2 * Math.PI) / maxSize;
double angle = 0;
int startX = (int) radius;
int startY = (int) radius;
edgesFrom = graph.GetEdgesFrom();
// sorting nodes on inner circle
bc[maxIndex] = SortInnerCircle(bc[maxIndex]);
// setting nodes on inner circle
for (int i = 0; i < bc[maxIndex].length; i++) {
setOffset(nodeViews.get(bc[maxIndex][i]), startX + (Math.cos(angle) * radius), startY - (Math.sin(angle) * radius));
posSet[bc[maxIndex][i]] = true;
angle += deltaAngle;
}
drawnBiComps[maxIndex] = true;
nodeHeights = new HashMap<Integer, Integer>();
SetOuterCircle(maxIndex, radius, startX, startY, -1);
if (cancelled)
return;
nodeIter = partition.nodeIterator();
while (nodeIter.hasNext() && !cancelled) {
final LayoutNode ln = nodeIter.next();
final View<CyNode> nv = ln.getNodeView();
ln.setX(nv.getVisualProperty(BasicVisualLexicon.NODE_X_LOCATION));
ln.setY(nv.getVisualProperty(BasicVisualLexicon.NODE_Y_LOCATION));
partition.moveNodeToLocation(ln);
}
}
Aggregations