简体   繁体   English

图形的可视化

[英]Visualization of graph

I have simple program that simulates distributed environment. 我有简单的程序来模拟分布式环境。 I want to visualize processor behaviour by using GraphStream library. 我想通过使用GraphStream库可视化处理器行为。 Each processor is a thread, they do some computations, but not all the time, only when I set the switch variable 每个处理器都是一个线程,只有当我设置了switch变量时,它们会进行一些计算,但不是所有的时间

while(running){
  if(switch)
    computate();
}

I have written a class which take processorList and prepare graph visualization. 我编写了一个带有processorList并准备图形可视化的类。 There is a function for this 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 is that i see colors on edges only for blink of eye and then color disapear. 我的问题是,我只看到边缘的颜色眨眼,然后颜色消失。 It looks like it adds attribute "ui.color" and removes it in same loop round, but how is it possible? 看起来它添加属性"ui.color"并在同一循环中删除它,但它怎么可能? @update I have edited my code, now i can see edges for time specified in thread.sleep() after first loop, well i dont get why after clearing all attributes i can actually see them. @update我已经编辑了我的代码,现在我可以在第一次循环后看到thread.sleep()指定的时间边缘,好吧我不明白为什么在清除所有属性后我实际上可以看到它们。 here is how i'm calling my function 这是我如何称呼我的功能

    while(true)
            {   i++;
//if any processor is not runing
                boolean aux = false;
                while(!aux) {
                    for (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 is set to less then 100 ms it starts to blinks again. 当调整功能内的Thread.sleep()设置为小于100毫秒时,它会再次开始闪烁。

Because it may be a little unclear what i'm doing i have created smaller example 因为我可能有点不清楚我在做什么,我创造了一个较小的例子

This is equivalent of my 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 is a 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 is main class 这是主要的课程

public class TestGs {

        public static void main(String[] args) {
            Node lastNode;
            TestDraw t;
            Vector<SomeObjectWithNode> a = 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 i = 1; i < 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 i run example we can see graph has colours only for the blink of eye instead of displaying it for time in Thread.sleep() 当我运行示例时,我们可以看到图形只有眨眼的颜色,而不是在Thread.sleep()中显示它的时间

The main problem is e.clearAttributes(); 主要问题是e.clearAttributes(); in method adjust() . 在方法adjust() You remove ALL attributes not only "ui.color". 您不仅删除所有属性“ui.color”。 You can use e.setAttribute("ui.color", randomColor); 你可以使用e.setAttribute("ui.color", randomColor); instead e.addAttribute("ui.color", randomColor); 而是e.addAttribute("ui.color", randomColor); and remove block with e.clearAttributes() at all (see original example number 2). 并删除带有e.clearAttributes()块(参见原始示例 2)。

I've modified your code accordingly my comments and shared it on gist.github . 我相应地修改了你的代码我的评论并在gist.github上分享了它。 Now it changes color every 2 secs. 现在它每2秒换一次颜色。

PS: now about cause of blining. PS:现在关于blining的原因。 I've had short investigation of GraphStream source code (a lot of java code, sorry). 我对GraphStream源代码进行了简短的调查(很多java代码,对不起)。 AbstractElement.java (only interesting methods): AbstractElement.java(只有有趣的方法):

    public void clearAttributes() {
            if (attributes != null) {
                for (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 the value is null,
            event = AttributeChangeEvent.CHANGE; // but the attribute exists.

        oldValue = attributes.put(attribute, value);
        attributeChanged(event, attribute, oldValue, value);
    }
...

As you can see setAttribute and addAttribute is really similar. 如您所见,setAttribute和addAttribute非常相似。 Now attributeChanged() implementation in GraphicElement.java: 现在在GraphicElement.java中实现attributeChanged():

@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( this );
                    mygraph.graphChanged = true;
                } else if (attribute.equals("ui.label")) {
                    label = StyleConstants.convertLabel(newValue);
                    mygraph.graphChanged = true;
                } else if (attribute.equals("ui.style")) {
                    // Cascade the new style in the 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 for %S '%s' :", getSelectorType(), getId()), e);
                        }
                        mygraph.graphChanged = true;
                    } else {
                        logger.warning("Unknown value for 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
                                                                // at
                                                                // this 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: As you can see when you clear attributes, dynamic style will be added/removed by methods popElementAsDynamic/pushElementAsDynamic . 注意:正如您在清除属性时所看到的,将通过popElementAsDynamic/pushElementAsDynamic方法添加/删除动态样式。 And implementations these methods in StyleGroup.java: 并在StyleGroup.java中实现这些方法:

     /**
     * Indicate the element has dynamic values and thus cannot be drawn in bulk
     * operations. Called by the GraphicElement.
     * 
     * @param element
     *            The element.
     */
    protected void pushElementAsDynamic(Element element) {
        if (dynamicOnes == null)
            dynamicOnes = new HashSet<Element>();

        dynamicOnes.add(element);
    }

    /**
     * Indicate the element has no more dynamic values and can be drawn in bulk
     * operations. Called by the GraphicElement.
     * 
     * @param element
     *            The element.
     */
    protected void popElementAsDynamic(Element element) {
        dynamicOnes.remove(element);

        if (dynamicOnes.isEmpty())
            dynamicOnes = null;
    }

Well when we add/setAttribute we only add new elements in existed hashmap. 好吧,当我们添加/ setAttribute时,我们只在现有的hashmap中添加新元素。 When we use clearAttributes we create new instances HashMap for dynamicOnes . 当我们使用clearAttributes时,我们为dynamicOnes创建新的实例HashMap。 Probably in that case we have synchronization issue and that is cause of blinking. 可能在这种情况下我们有同步问题,这是导致闪烁的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM