public abstract class BarnesHutLayout extends SourceBase implements Layout
This base class creates the space decomposition method and manages the main
loop of the simulation. The simulation is made of NodeParticle
and
EdgeSpring
elements that are created and linked for you in response
to graph events received via the Sink
interface. However you have to
provide an implementation of the abstract NodeParticle
class (by
overriding the abstract method newNodeParticle(String)
).
As almost all the repulsion/attraction forces computation is done in the
NodeParticle
class, this is the most important one.
This algorithm can be configured using several attributes put on the graph :
SourceBase.ElementType
Constructor and Description |
---|
BarnesHutLayout()
New 2D Barnes-Hut simulation.
|
BarnesHutLayout(boolean is3D)
New Barnes-Hut simulation.
|
BarnesHutLayout(boolean is3D,
java.util.Random randomNumberGenerator)
New Barnes-Hut simulation.
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Clears the whole nodes and edges structures
|
void |
compute()
Method to call repeatedly to compute the layout.
|
void |
edgeAdded(java.lang.String graphId,
long time,
java.lang.String edgeId,
java.lang.String fromNodeId,
java.lang.String toNodeId,
boolean directed)
An edge was inserted in graph.
|
void |
edgeAttributeAdded(java.lang.String graphId,
long time,
java.lang.String edgeId,
java.lang.String attribute,
java.lang.Object value)
A edge attribute was added.
|
void |
edgeAttributeChanged(java.lang.String graphId,
long time,
java.lang.String edgeId,
java.lang.String attribute,
java.lang.Object oldValue,
java.lang.Object newValue)
A edge attribute was changed.
|
void |
edgeAttributeRemoved(java.lang.String graphId,
long time,
java.lang.String edgeId,
java.lang.String attribute)
A edge attribute was removed.
|
void |
edgeRemoved(java.lang.String graphId,
long time,
java.lang.String edgeId)
An edge of graph was removed.The nodes the edge connects may already have
been removed from the graph.
|
void |
freezeNode(java.lang.String id,
boolean on)
Freeze or un-freeze a node.
|
double |
getBarnesHutTheta()
The Barnes-Hut theta value used to know if we use a pole or not.
|
Point3 |
getCenterPoint() |
Energies |
getEnergies() |
double |
getForce()
The current layout force.
|
double |
getGravityFactor()
A gravity factor that attracts all nodes to the center of the layout to avoid
flying components.
|
Point3 |
getHiPoint()
Largest point in space of the layout bounding box.
|
long |
getLastStepTime()
Time in nanoseconds used by the last call to step().
|
abstract java.lang.String |
getLayoutAlgorithmName()
Name of the layout algorithm.
|
Point3 |
getLowPoint()
Smallest point in space of the layout bounding box.
|
int |
getNodeMovedCount()
How many nodes moved during the last step?.
|
double |
getQuality()
The current layout algorithm quality.
|
java.util.Random |
getRandom() |
ParticleBox |
getSpatialIndex()
The spatial index as a n-tree.
|
double |
getStabilization()
Estimate of how close to stabilization the layout algorithm is.
|
double |
getStabilizationLimit()
Above which value a correct stabilization is achieved?
|
int |
getSteps()
Number of calls made to step() so far.
|
double |
getViewZone() |
void |
graphAttributeAdded(java.lang.String graphId,
long time,
java.lang.String attribute,
java.lang.Object value)
A graph attribute was added.
|
void |
graphAttributeChanged(java.lang.String graphId,
long time,
java.lang.String attribute,
java.lang.Object oldValue,
java.lang.Object newValue)
A graph attribute was changed.
|
void |
graphAttributeRemoved(java.lang.String graphId,
long time,
java.lang.String attribute)
A graph attribute was removed.
|
void |
graphCleared(java.lang.String graphId,
long time)
The whole graph was cleared.
|
boolean |
is3D() |
void |
moveNode(java.lang.String id,
double x,
double y,
double z)
Move a node by force to a new location.
|
abstract NodeParticle |
newNodeParticle(java.lang.String id)
Factory method to create node particles.
|
void |
nodeAdded(java.lang.String graphId,
long time,
java.lang.String nodeId)
A node was inserted in the given graph.
|
void |
nodeAttributeAdded(java.lang.String graphId,
long time,
java.lang.String nodeId,
java.lang.String attribute,
java.lang.Object value)
A node attribute was added.
|
void |
nodeAttributeChanged(java.lang.String graphId,
long time,
java.lang.String nodeId,
java.lang.String attribute,
java.lang.Object oldValue,
java.lang.Object newValue)
A node attribute was changed.
|
void |
nodeAttributeRemoved(java.lang.String graphId,
long time,
java.lang.String nodeId,
java.lang.String attribute)
A node attribute was removed.
|
void |
nodeRemoved(java.lang.String graphId,
long time,
java.lang.String nodeId)
A node was removed from the graph.
|
void |
particleAdded(java.lang.Object id,
double x,
double y,
double z) |
void |
particleAdded(java.lang.Object id,
double x,
double y,
double z,
java.lang.Object mark) |
void |
particleAttributeChanged(java.lang.Object id,
java.lang.String attribute,
java.lang.Object newValue,
boolean removed) |
void |
particleMarked(java.lang.Object id,
java.lang.Object mark) |
void |
particleMoved(java.lang.Object id,
double x,
double y,
double z) |
void |
particleRemoved(java.lang.Object id) |
double |
randomXInsideBounds() |
double |
randomYInsideBounds() |
double |
randomZInsideBounds() |
void |
setBarnesHutTheta(double theta)
Change the barnes-hut theta parameter allowing to know if we use a pole or
not.
|
void |
setForce(double value)
The general "speed" of the algorithm.
|
void |
setGravityFactor(double value)
Set the gravity factor that attracts all nodes to the center of the layout to
avoid flying components.
|
void |
setQuality(double qualityLevel)
Set the overall quality level, a number between 0 and 1 with 1 the highest
quality available, but often with a slower computation.
|
void |
setSendNodeInfos(boolean on)
If true, node informations messages are sent for every node.
|
void |
setStabilizationLimit(double value)
Change the stabilization limit for this layout algorithm.
|
void |
shake()
Add a random vector whose length is 10% of the size of the graph to all node
positions.
|
void |
stepBegins(java.lang.String graphId,
long time,
double step)
Since dynamic graphs are based on discrete event modifications, the notion of
step is defined to simulate elapsed time between events.
|
void |
stepFinished(int time) |
addAttributeSink, addElementSink, addSink, attributeSinks, clearAttributeSinks, clearElementSinks, clearSinks, elementSinks, removeAttributeSink, removeElementSink, removeSink, sendAttributeChangedEvent, sendAttributeChangedEvent, sendEdgeAdded, sendEdgeAdded, sendEdgeAttributeAdded, sendEdgeAttributeAdded, sendEdgeAttributeChanged, sendEdgeAttributeChanged, sendEdgeAttributeRemoved, sendEdgeAttributeRemoved, sendEdgeRemoved, sendEdgeRemoved, sendGraphAttributeAdded, sendGraphAttributeAdded, sendGraphAttributeChanged, sendGraphAttributeChanged, sendGraphAttributeRemoved, sendGraphAttributeRemoved, sendGraphCleared, sendGraphCleared, sendNodeAdded, sendNodeAdded, sendNodeAttributeAdded, sendNodeAttributeAdded, sendNodeAttributeChanged, sendNodeAttributeChanged, sendNodeAttributeRemoved, sendNodeAttributeRemoved, sendNodeRemoved, sendNodeRemoved, sendStepBegins, sendStepBegins
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
addAttributeSink, addElementSink, addSink, clearAttributeSinks, clearElementSinks, clearSinks, removeAttributeSink, removeElementSink, removeSink
public BarnesHutLayout()
public BarnesHutLayout(boolean is3D)
is3D
- If true the simulation dimensions count is 3 else 2.public BarnesHutLayout(boolean is3D, java.util.Random randomNumberGenerator)
is3D
- If true the simulation dimensions count is 3 else 2.randomNumberGenerator
- The random number generator to use.public Point3 getLowPoint()
Layout
getLowPoint
in interface Layout
public Point3 getHiPoint()
Layout
getHiPoint
in interface Layout
public double randomXInsideBounds()
public double randomYInsideBounds()
public double randomZInsideBounds()
public Point3 getCenterPoint()
public double getGravityFactor()
public void setGravityFactor(double value)
value
- The new gravity factor, usually between 0 and 1.public ParticleBox getSpatialIndex()
public long getLastStepTime()
Layout
getLastStepTime
in interface Layout
public abstract java.lang.String getLayoutAlgorithmName()
Layout
getLayoutAlgorithmName
in interface Layout
public int getNodeMovedCount()
Layout
getNodeMovedCount
in interface Layout
public double getStabilization()
Layout
getStabilization
in interface Layout
public double getStabilizationLimit()
Layout
getStabilizationLimit
in interface Layout
public int getSteps()
Layout
public double getQuality()
Layout
getQuality
in interface Layout
public boolean is3D()
public double getForce()
Layout
public java.util.Random getRandom()
public Energies getEnergies()
public double getBarnesHutTheta()
public double getViewZone()
public void setSendNodeInfos(boolean on)
Layout
setSendNodeInfos
in interface Layout
on
- If true, send node informations to a "layout.info" attribute.public void setBarnesHutTheta(double theta)
theta
- The new value for theta (between 0 and 1).public void setForce(double value)
Layout
public void setStabilizationLimit(double value)
Layout
The stabilization is a number between 0 and 1 that indicates how close to
stabilization (no nodes need to move) the layout is. The value 1 means the
layout is fully stabilized. Naturally this is often only an indication only,
for some algorithms, it is difficult to determine if the layout is correct or
acceptable enough. You can get the actual stabilization limit using
Layout.getStabilizationLimit()
. You can get the actual stabilization using
Layout.getStabilization()
.
Be careful, most layout classes do not use the stabilization limit, this
number is mostly used the process that control the layout, like the
LayoutRunner
for example. The stabilization limit is only an
indication with a default set for each layout algorithm. However this default
can be changed using this method, or by storing on the graph an attribute
"layout.stabilization-limit" (or "layout.stabilisation-limit").
The convention is that the value 0 means that the process controlling the layout will not stop the layout (will therefore not consider the stabilization limit). In other words the layout will compute endlessly.
setStabilizationLimit
in interface Layout
value
- The new stabilization limit, 0 means no need to stabilize. Else a
value larger than zero or equal to 1 is accepted.public void setQuality(double qualityLevel)
Layout
setQuality
in interface Layout
qualityLevel
- The quality level, a number between 0 and 1.public void clear()
Layout
public void compute()
Layout
This method implements the layout algorithm proper. It must be called in a
loop, until the layout stabilizes. You can know if the layout is stable by
using the Layout.getNodeMovedCount()
method that returns the number of node
that have moved during the last call to step().
The listener is called by this method, therefore each call to step() will also trigger layout events, allowing to reproduce the layout process graphically for example. You can insert the listener only when the layout stabilized, and then call step() anew if you do not want to observe the layout process.
public void shake()
Layout
public void moveNode(java.lang.String id, double x, double y, double z)
Layout
public void freezeNode(java.lang.String id, boolean on)
Layout
freezeNode
in interface Layout
id
- The node identifier.on
- If true the node is frozen.public void particleAdded(java.lang.Object id, double x, double y, double z, java.lang.Object mark)
public void particleAdded(java.lang.Object id, double x, double y, double z)
public void particleMarked(java.lang.Object id, java.lang.Object mark)
public void particleMoved(java.lang.Object id, double x, double y, double z)
public void particleRemoved(java.lang.Object id)
public void stepFinished(int time)
public void particleAttributeChanged(java.lang.Object id, java.lang.String attribute, java.lang.Object newValue, boolean removed)
public void edgeAdded(java.lang.String graphId, long time, java.lang.String edgeId, java.lang.String fromNodeId, java.lang.String toNodeId, boolean directed)
ElementSink
edgeAdded
in interface ElementSink
graphId
- Identifier of the graph where the edge was added.edgeId
- Identifier of the added edge.fromNodeId
- Identifier of the first node of the edge.toNodeId
- Identifier of the second node of the edge.directed
- If true, the edge is directed.public void nodeAdded(java.lang.String graphId, long time, java.lang.String nodeId)
ElementSink
nodeAdded
in interface ElementSink
graphId
- Identifier of the graph where the node was added.nodeId
- Identifier of the added node.public void edgeRemoved(java.lang.String graphId, long time, java.lang.String edgeId)
ElementSink
edgeRemoved
in interface ElementSink
graphId
- The graph where the edge will be removed.edgeId
- The edge that will be removed.public void nodeRemoved(java.lang.String graphId, long time, java.lang.String nodeId)
ElementSink
nodeRemoved
in interface ElementSink
graphId
- Identifier of the graph where the node will be removed.nodeId
- Identifier of the removed node.public void graphCleared(java.lang.String graphId, long time)
ElementSink
graphCleared
in interface ElementSink
graphId
- The graph cleared.public void stepBegins(java.lang.String graphId, long time, double step)
ElementSink
Since dynamic graphs are based on discrete event modifications, the notion of step is defined to simulate elapsed time between events. So a step is a event that occurs in the graph, it does not modify it but it gives a kind of timestamp that allow the tracking of the progress of the graph over the time.
This kind of event is useful for dynamic algorithms that listen to the dynamic graph and need to measure the time in the graph's evolution.
stepBegins
in interface ElementSink
graphId
- Identifier of the graph where the step starts.time
- A numerical value that may give a timestamp to track the evolution
of the graph over the time.public void graphAttributeAdded(java.lang.String graphId, long time, java.lang.String attribute, java.lang.Object value)
AttributeSink
graphAttributeAdded
in interface AttributeSink
graphId
- Identifier of the graph where the attribute changed.attribute
- The attribute name.value
- The attribute new value.public void graphAttributeChanged(java.lang.String graphId, long time, java.lang.String attribute, java.lang.Object oldValue, java.lang.Object newValue)
AttributeSink
graphAttributeChanged
in interface AttributeSink
graphId
- Identifier of the graph where the attribute changed.attribute
- The attribute name.oldValue
- The attribute old value.newValue
- The attribute new value.public void graphAttributeRemoved(java.lang.String graphId, long time, java.lang.String attribute)
AttributeSink
graphAttributeRemoved
in interface AttributeSink
graphId
- Identifier of the graph where the attribute was removed.attribute
- The removed attribute name.public void nodeAttributeAdded(java.lang.String graphId, long time, java.lang.String nodeId, java.lang.String attribute, java.lang.Object value)
AttributeSink
nodeAttributeAdded
in interface AttributeSink
graphId
- Identifier of the graph where the change occurred.nodeId
- Identifier of the node whose attribute changed.attribute
- The attribute name.value
- The attribute new value.public void nodeAttributeChanged(java.lang.String graphId, long time, java.lang.String nodeId, java.lang.String attribute, java.lang.Object oldValue, java.lang.Object newValue)
AttributeSink
nodeAttributeChanged
in interface AttributeSink
graphId
- Identifier of the graph where the change occurred.nodeId
- Identifier of the node whose attribute changed.attribute
- The attribute name.oldValue
- The attribute old value.newValue
- The attribute new value.public void nodeAttributeRemoved(java.lang.String graphId, long time, java.lang.String nodeId, java.lang.String attribute)
AttributeSink
nodeAttributeRemoved
in interface AttributeSink
graphId
- Identifier of the graph where the attribute was removed.nodeId
- Identifier of the node whose attribute was removed.attribute
- The removed attribute name.public void edgeAttributeAdded(java.lang.String graphId, long time, java.lang.String edgeId, java.lang.String attribute, java.lang.Object value)
AttributeSink
edgeAttributeAdded
in interface AttributeSink
graphId
- Identifier of the graph where the change occurred.edgeId
- Identifier of the edge whose attribute changed.attribute
- The attribute name.value
- The attribute new value.public void edgeAttributeChanged(java.lang.String graphId, long time, java.lang.String edgeId, java.lang.String attribute, java.lang.Object oldValue, java.lang.Object newValue)
AttributeSink
edgeAttributeChanged
in interface AttributeSink
graphId
- Identifier of the graph where the change occurred.edgeId
- Identifier of the edge whose attribute changed.attribute
- The attribute name.oldValue
- The attribute old value.newValue
- The attribute new value.public void edgeAttributeRemoved(java.lang.String graphId, long time, java.lang.String edgeId, java.lang.String attribute)
AttributeSink
edgeAttributeRemoved
in interface AttributeSink
graphId
- Identifier of the graph where the attribute was removed.edgeId
- Identifier of the edge whose attribute was removed.attribute
- The removed attribute name.public abstract NodeParticle newNodeParticle(java.lang.String id)
id
- The identifier of the new node/particle.