2012-11-15 23 views
1
繪製邊緣

我是新來JUNG 我有一個代表與到關鍵節點,或者是顏色爲紅色頂點和其他頂點藍色 邊緣從起始節點的網絡拓撲結構的FRLayout結束節點是藍色的 我想要展示到最終節點的路徑的動畫。 如何使用指定的時間間隔將動畫從start_node繪製到end_node?你能提供或參考一個例子嗎?如何動畫與JUNG

回答

2

您可以將關鍵幀附加到您的邊緣數據。然後,每次你畫(使用變壓器)時,您可以使用關鍵幀來調整邊緣的梯度:

RenderContext<V, E> context = vv.getRenderContext(); 
context.setEdgeDrawPaintTransformer(new KeyframeGradientTransformer()); 

public class KeyframeGradientTransformer() implements Transformer<E, Paint> { 
     @Override 
     public Paint transform(Edge edge) { 
      // TODO: Here you would determine the gradient information 
      // based on the edge.getKeyframe(). 
      Paint gradient = new GradientPaint(...); 
      return gradient; 
     } 
} 

編輯:

我寫了一個簡單的例子:

enter image description here

這從一個頂點到另一個頂點(沿着一條邊)進行動畫處理。如果你想通過多個頂點進行動畫處理,那需要更多的邏輯。但是,這看起來很酷,應該給你一個開始。如果您(或任何其他人)需要更多評論,請讓我知道,我可以嘗試使其更清楚。

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.LinearGradientPaint; 
import java.awt.Paint; 
import java.awt.Stroke; 
import java.awt.geom.Point2D; 
import java.util.Timer; 
import java.util.TimerTask; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

import org.apache.commons.collections15.Factory; 
import org.apache.commons.collections15.Transformer; 

import edu.uci.ics.jung.algorithms.generators.random.EppsteinPowerLawGenerator; 
import edu.uci.ics.jung.algorithms.layout.Layout; 
import edu.uci.ics.jung.algorithms.layout.SpringLayout; 
import edu.uci.ics.jung.graph.Graph; 
import edu.uci.ics.jung.graph.SparseMultigraph; 
import edu.uci.ics.jung.graph.util.Pair; 
import edu.uci.ics.jung.visualization.VisualizationViewer; 

public class Test { 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setPreferredSize(new Dimension(1024, 768)); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       JPanel content = new JPanel(); 

       // Set up the graph and the display. 
       int numV = 70; 
       int numE = 50; 
       EppsteinPowerLawGenerator<String, String> gen = new EppsteinPowerLawGenerator<String, String>(
         new GraphFactory(), new CountFactory(), 
         new CountFactory(), numV, numE, 10); 
       Graph<String, String> graph = gen.create(); 
       Layout<String, String> layout = new SpringLayout<String, String>(
         graph); 
       VisualizationViewer<String, String> vv = new VisualizationViewer<String, String>(
         layout); 
       vv.getRenderContext().setEdgeStrokeTransformer(
         new Transformer<String, Stroke>() { 

          @Override 
          public Stroke transform(String edge) { 
           return new BasicStroke(1.5f); 
          } 
         }); 

       content.add(vv); 

       frame.setContentPane(content); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       // Animate the edges! 
       AnimationTimerTask at = new AnimationTimerTask(vv); 
       Timer timer = new Timer(); 
       timer.scheduleAtFixedRate(at, 10, 30); 
      } 

     }); 
    } 

    static class AnimationTimerTask extends TimerTask { 

     private final double width = 0.1; // Size of the colored line. 
     private final double stepsize = 0.01; 
     private double keyframe = 0 + width; // Between 0.0 and 1.0 
     private VisualizationViewer<String, String> vv = null; 

     public AnimationTimerTask(VisualizationViewer<String, String> vv) { 
      this.vv = vv; 
     } 

     @Override 
     public void run() { 
      vv.getRenderContext().setEdgeDrawPaintTransformer(
        new Transformer<String, Paint>() { 

         @Override 
         public Paint transform(String edge) { 
          // Find both points of the edge. 
          Pair<String> vs = vv.getGraphLayout().getGraph() 
            .getEndpoints(edge); 
          Point2D p1 = vv.getGraphLayout().transform(
            vs.getFirst()); 
          Point2D p2 = vv.getGraphLayout().transform(
            vs.getSecond()); 

          // This code won't handle self-edges. 
          if (p1.equals(p2)) { 
           return Color.red; 
          } 

          Color[] colors = { Color.gray, Color.red, 
            Color.gray }; 
          float start = (float) Math.max(0.0, keyframe 
            - width); 
          float end = (float) Math.min(1.0, keyframe + width); 
          float[] fractions = { start, (float) keyframe, end }; 
          return new LinearGradientPaint(p1, p2, fractions, 
            colors); 
         } 

        }); 
      vv.repaint(); 
      keyframe += stepsize; 
      keyframe %= 1.0; 
     } 
    } 

    static class GraphFactory implements Factory<Graph<String, String>> { 

     @Override 
     public Graph<String, String> create() { 
      return new SparseMultigraph<String, String>(); 
     } 
    } 

    static class CountFactory implements Factory<String> { 

     private int count = 0; 

     @Override 
     public String create() { 
      return String.valueOf(count++); 
     } 
    } 
} 

此外,我在此之前已經採取了一些熱量:這需要JUNG庫。如果您沒有它,則無法運行SSCCEE。

+0

你能否給出關於關鍵幀的更多細節 – Nabegh

+1

@Nabegh看看編輯 - 希望它是有道理的。 (我不確定這是多高效,但它似乎適用於<500個頂點和邊緣。) – sdasdadas

+0

這非常有幫助。謝謝。我相信爲了改變邊緣中風,我需要使用相同的邏輯來實現setEdgeStrokeTransformer? – Nabegh