I need to change attributes of nodes and edges over time. The time is split into timeperiods, every timeperiod looks the same: Check every node and edge for possible changes and edit attribute if necessary. Specifically there are numeric attributes and the size of a node and the width of an edge are based on the attributes value. Initially the graph displays correctly. The nodes and edges have the supposed size. But changing the attribute values dynamically over time does not change the elements sizes. How can I make sure, attribute changes also change the graphs visualisation?
As far as I understand the Graphstream Docs and tutorials there are sources, sinks and sipes (a pipe is both a source and a sink). Sources create events, sinks consumes them. I use the GridGenerator which is a source. I can add the graph as a sink and let the generator create the graph. I think, I have to add a sink to the graph then, because changing attributes of elements of the graph makes it a source. But what do I use as sink? graph.display()
returns a Viewer but I can't add it as sink, it says it's not compatible with the arguments for graph.addSink(sink)
. Even though the Graphstream Docs says that a Viewer is a sink and that the Viewer gets added automatically as a sink. Why do I don't see changes in the UI then? I don't get it.
After generating the graph the nodes and edges get there attributes
public static void configureElements(Graph world) {
for (Node node : world.getEachNode()) {
double random = Math.random() * 100;
if (random < 20) {
// remove obstacles
world.removeNode(node)
} else if (random < 30) {
// node have rohstoffe
node.addAttribute("ui.class", "rohstoff");
node.addAttribute("ui.label", node.getId());
node.addAttribute("isRohstoff");
int capacity = (int) (Math.random() * maxCapacity);
node.addAttribute("capacity", capacity);ity);
// nodes size is based on capacity of rohstoffe
node.setAttribute("ui.size", node.getNumber("capacity") + 10);
} else if (random < 32) {
// node is a lager
node.addAttribute("ui.class", "lager");
node.addAttribute("ui.label", node.getId());
node.addAttribute("isLager");
node.addAttribute("lagerstand", 0);
// nodes size is based on capacity of the lager
node.setAttribute("ui.size", node.getNumber("lagerstand") + 10);
} else {
// normal node
node.addAttribute("isNode");
}
}
for (Edge edge : world.getEachEdge()) {
// add pheromones to edge
edge.addAttribute("pheromones", 0);
// edges size is based on number of pheromones
edge.setAttribute("ui.size", edge.getNumber("pheromones"));
}
}
Here I change the node attribute dynamically over time
public void dropRohstoff(Node node) {
int oldRohstoff = (int) node.getNumber("rohstoff");
int newRohstoff = oldRohstoff++;
node.setAttribute("rohstoff", newRohstoff);
world.nodeAttributeChanged(world.getId(), (long) world.getStep(), node.getId(),"rohstoff", oldRohstoff, newRohstoff);
}
public void pickRohstoff(Node node) {
int oldCapacity = (int) node.getNumber("capacity");
int newCapicity = oldCapacity++;
node.setAttribute("capacity", newCapicity);
world.nodeAttributeChanged(world.getId(), (long) world.getStep(), node.getId(), "capacity", oldCapacity, newCapicity);
}
Here the edge attributes
public void evaporateAll() {
for (Edge edge : world.getEachEdge()) {
Double oldEvaporateRate = edge.getNumber("pheromones");
Double newEvaporateRate = oldEvaporateRate * (1.0 - evaporateRate);
edge.setAttribute("pheromones", newEvaporateRate);
world.edgeAttributeChanged(world.getId(), (long) world.getStep(), edge.getId(), "pheromones", oldEvaporateRate, newEvaporateRate);
}
}
Does anybody know how do I have to add the sink? Or am I missing something else?