java - Visualization of graph -
i have simple program simulates distributed environment. want visualize processor behaviour using graphstream library. each processor thread, computations, not time, when set switch
variable
while(running){ if(switch) computate(); }
i have written class take processorlist , prepare graph visualization. there function task
public void adjustbfsgraph2(){ for(edge e: this.g.getedgeset()) { e.clearattributes(); } try { thread.sleep(2000); } catch (interruptedexception e) { e.printstacktrace(); } for(processor p : processorlist) { p.getnode().setattribute("ui.label", "pid" +" " + p.getpid() +" "+"dist: " + p.getfieldvalue("bfs") + " " + "parent" + " " + p.getfieldvalue("parent")); if(!p.getfieldvalue("parent").equals("-1")) { edge e = p.getnode().getedgebetween(p.getfieldvalue("parent")); if(e != null) { e.setattribute("ui.color", p.getcolor()); e.setattribute("ui.label", "added" + p.getpid()); } } } }
my problem see colors on edges blink of eye , color disapear. looks adds attribute "ui.color"
, removes in same loop round, how possible? @update have edited code, can see edges time specified in thread.sleep()
after first loop, dont why after clearing attributes can see them. here how i'm calling function
while(true) { i++; //if processor not runing boolean aux = false; while(!aux) { (processor proc : s.processorlist) { aux = aux || proc.isenabled(); } aux = !aux; } s.gp.adjustbfsgraph(); thread.sleep(5000); for(processor proc: s.processorlist) { proc.enable(); } }
when thread.sleep()
inside adjust function set less 100 ms starts blinks again.
because may little unclear i'm doing have created smaller example
this equivalent of processor class
public class someobjectwithnode { public node n; public color c; public someobjectwithnode(node n) { random rand = new random(); float r = rand.nextfloat(); float g = rand.nextfloat(); float b = rand.nextfloat(); color randomcolor = new color(r, g, b); c = randomcolor; this.n = n; } }
here class witch change graph styling/ drawing it
public class testdraw { vector<someobjectwithnode> n; graph g; public testdraw(vector<someobjectwithnode> k, graph g) { this.g= g; this.n = k; } public void adjust() { random rand = new random(); for(edge e: g.getedgeset()) { e.clearattributes(); } for(someobjectwithnode k: n) { k.n.addattribute("ui.color", k.c); for(edge e: k.n.getedgeset()) { float r = rand.nextfloat(); float g = rand.nextfloat(); float b = rand.nextfloat(); color randomcolor = new color(r, g, b); e.addattribute("ui.color", randomcolor); } } } }
and here main class
public class testgs { public static void main(string[] args) { node lastnode; testdraw t; vector<someobjectwithnode> = new vector<someobjectwithnode>(); system.setproperty("gs.ui.renderer", "org.graphstream.ui.j2dviewer.j2dgraphrenderer"); graph g = new singlegraph("test1"); g.display(); g.addattribute("ui.stylesheet", "node { fill-mode: dyn-plain; size: 10px;} edge { fill-mode: dyn-plain; size: 2px;}"); a.add(new someobjectwithnode(g.addnode(integer.tostring(0)))); lastnode = g.getnode("0"); for(int = 1; < 10; i++) { a.add(new someobjectwithnode(g.addnode(integer.tostring(i)))); g.addedge(integer.tostring(i-1).concat(integer.tostring(i)), a.get(i).n, lastnode); lastnode = a.get(i).n; } t = new testdraw(a,g); while(true) { t.adjust(); try { thread.sleep(3000); } catch (interruptedexception e) { // todo auto-generated catch block e.printstacktrace(); } } } }
when run example can see graph has colours blink of eye instead of displaying time in thread.sleep()
the main problem e.clearattributes();
in method adjust()
. remove attributes not "ui.color". can use e.setattribute("ui.color", randomcolor);
instead e.addattribute("ui.color", randomcolor);
, remove block e.clearattributes()
@ (see original example number 2).
i've modified code accordingly comments , shared on gist.github. changes color every 2 secs.
ps: cause of blining. i've had short investigation of graphstream source code (a lot of java code, sorry). abstractelement.java (only interesting methods):
public void clearattributes() { if (attributes != null) { (map.entry<string, object> entry : attributes.entryset()) attributechanged(attributechangeevent.remove, entry.getkey(), entry.getvalue(), null); attributes.clear(); } } ... public void setattribute(string attribute, object... values) { addattribute(attribute, values); } ... public void addattribute(string attribute, object... values) { if (attributes == null) attributes = new hashmap<string, object>(1); object oldvalue; object value; if (values.length == 0) value = true; else if (values.length == 1) value = values[0]; else value = values; attributechangeevent event = attributechangeevent.add; if (attributes.containskey(attribute)) // in case value null, event = attributechangeevent.change; // attribute exists. oldvalue = attributes.put(attribute, value); attributechanged(event, attribute, oldvalue, value); } ...
as can see setattribute , addattribute similar. attributechanged() implementation in graphicelement.java:
@override protected void attributechanged(attributechangeevent event, string attribute, object oldvalue, object newvalue) { if (event == attributechangeevent.add || event == attributechangeevent.change) { if (attribute.charat(0) == 'u' && attribute.charat(1) == 'i') { if (attribute.equals("ui.class")) { mygraph.stylegroups.checkelementstylegroup(this); // mygraph.stylegroups.removeelement( tis ); // mygraph.stylegroups.addelement( ); mygraph.graphchanged = true; } else if (attribute.equals("ui.label")) { label = styleconstants.convertlabel(newvalue); mygraph.graphchanged = true; } else if (attribute.equals("ui.style")) { // cascade new style in style sheet. if (newvalue instanceof string) { try { mygraph.stylesheet.parsestylefromstring( new selector(getselectortype(), getid(), null), (string) newvalue); } catch (exception e) { logger.log(level.warning, string.format("error while parsing style %s '%s' :", getselectortype(), getid()), e); } mygraph.graphchanged = true; } else { logger.warning("unknown value style [" + newvalue + "]."); } } else if (attribute.equals("ui.hide")) { hidden = true; mygraph.graphchanged = true; } else if (attribute.equals("ui.clicked")) { style.pusheventfor(this, "clicked"); mygraph.graphchanged = true; } else if (attribute.equals("ui.selected")) { style.pusheventfor(this, "selected"); mygraph.graphchanged = true; } else if (attribute.equals("ui.color")) { style.pushelementasdynamic(this); mygraph.graphchanged = true; } else if (attribute.equals("ui.size")) { style.pushelementasdynamic(this); mygraph.graphchanged = true; } else if (attribute.equals("ui.icon")) { mygraph.graphchanged = true; } // else if( attribute.equals( "ui.state" ) ) // { // if( newvalue == null ) // state = null; // else if( newvalue instanceof string ) // state = (string) newvalue; // } } else if (attribute.equals("label")) { label = styleconstants.convertlabel(newvalue); mygraph.graphchanged = true; } } else // remove { if (attribute.charat(0) == 'u' && attribute.charat(1) == 'i') { if (attribute.equals("ui.class")) { object o = attributes.remove("ui.class"); // not yet removed // @ // point ! mygraph.stylegroups.checkelementstylegroup(this); attributes.put("ui.class", o); mygraph.graphchanged = true; } else if (attribute.equals("ui.label")) { label = ""; mygraph.graphchanged = true; } else if (attribute.equals("ui.hide")) { hidden = false; mygraph.graphchanged = true; } else if (attribute.equals("ui.clicked")) { style.popeventfor(this, "clicked"); mygraph.graphchanged = true; } else if (attribute.equals("ui.selected")) { style.popeventfor(this, "selected"); mygraph.graphchanged = true; } else if (attribute.equals("ui.color")) { style.popelementasdynamic(this); mygraph.graphchanged = true; } else if (attribute.equals("ui.size")) { style.popelementasdynamic(this); mygraph.graphchanged = true; } } else if (attribute.equals("label")) { label = ""; mygraph.graphchanged = true; } } }
note: can see when clear attributes, dynamic style added/removed methods popelementasdynamic/pushelementasdynamic
. , implementations these methods in stylegroup.java:
/** * indicate element has dynamic values , cannot drawn in bulk * operations. called graphicelement. * * @param element * element. */ protected void pushelementasdynamic(element element) { if (dynamicones == null) dynamicones = new hashset<element>(); dynamicones.add(element); } /** * indicate element has no more dynamic values , can drawn in bulk * operations. called graphicelement. * * @param element * element. */ protected void popelementasdynamic(element element) { dynamicones.remove(element); if (dynamicones.isempty()) dynamicones = null; }
well when add/setattribute add new elements in existed hashmap. when use clearattributes create new instances hashmap dynamicones
. in case have synchronization issue , cause of blinking.
Comments
Post a Comment