示例#1
0
        static void Main(string[] args)
        {
            // Create a random network
            SimpleNetwork net = SimpleNetwork.ReadFromEdgeList("demo.edges");

            // We use a custom coloring
            NetworkColorizer colors = new NetworkColorizer();
            colors.DefaultBackgroundColor = Color.Black;
            colors.DefaultEdgeColor = Color.WhiteSmoke;
            colors.DefaultVertexColor = Color.SteelBlue;

            // Let's use curved edges instead of the default straight ones
            Renderer.CurvedEdges = true;

            // Fire up the visualizer window
            Renderer.Start(net, new NETVisualizer.Layouts.FruchtermanReingold.FRLayout(10), colors);

            // Trigger the layout
            Renderer.Layout.DoLayoutAsync();

            // The rendering and layouting is done asynchronously in parallel,
            // so you can modify the network while the visualization and the layout continues
            Console.Write("Press ANY KEY to add another edge");
            Console.ReadKey();
            net.AddEdge("a", "b");
            net.AddEdge("b", "c");

            // Trigger the layout again. Only changed nodes will be relayouted ...
            Renderer.Layout.DoLayoutAsync();

            Console.WriteLine("Waiting for rendering window to be closed ...");
        }
        private static void DrawVertex(XGraphics g, string v, LayoutProvider layout, NetworkColorizer colorizer)
        {
            OpenTK.Vector3 p = layout.GetPositionOfNode(v);

            double size = Renderer.ComputeNodeSize(v);

            if (!double.IsNaN(p.X) &&
                !double.IsNaN(p.Y) &&
                !double.IsNaN(p.Z))
            {
                g.DrawEllipse(new SolidBrush(colorizer[v]), p.X - size / 2d - x_offset, p.Y - size / 2d - y_offset, size, size);
            }
        }
 private static void Draw(XGraphics g, IRenderableNet n, LayoutProvider layout, NetworkColorizer colorizer)
 {
     lock (n)
     {
         if (g == null)
             return;
         g.SmoothingMode = PdfSharp.Drawing.XSmoothingMode.HighQuality;
         g.Clear(Color.White);
         foreach (var e in n.GetEdgeArray())
             if (string.Compare(e.Item1, e.Item2) >= 0)
                 DrawEdge(g, e, layout, colorizer);
         foreach (string v in n.GetVertexArray())
             DrawVertex(g, v, layout, colorizer);
     }
 }
示例#4
0
        /// <summary>
        /// Creates a new instance of a Networkvisualizer which renders the specified network in real-time
        /// </summary>
        /// <param name="network">The network to render</param>
        /// <param name="layout">The layout algorithm to use</param>
        /// <param name="colorizer">The colorizer to apply. Default colors will be used if this is set to null (which is the default)</param>
        /// <param name="width">The width of the rendering window. 800 pixels by default</param>
        /// <param name="height">The height of the rendering window. 600 pixels by default</param>
        public static void Start(IRenderableNet network, LayoutProvider layout, NetworkColorizer colorizer = null, int width = 800, int height = 600)
        {
            // The actual rendering needs to be done in a separate thread placed in the single thread appartment state
            _mainThread = new Thread(new ThreadStart(new Action(delegate() {
                Instance = new Renderer(network, layout, colorizer, width, height);
                _initialized.Set();
                Instance.Run(80f);
            })));

            // Set single thread appartment
            _mainThread.SetApartmentState(ApartmentState.STA);
            _mainThread.Name = "STA Thread for NETVisualizer";

            // Fire up the thread and wait until initialization has been completed
            _mainThread.Start();
            _initialized.WaitOne();
        }
        public static void CreatePDF(string path, IRenderableNet n, LayoutProvider layout, NetworkColorizer colorizer = null)
        {
            PdfSharp.Pdf.PdfDocument doc = new PdfDocument();
            doc.Info.Title = "Network";
            doc.Info.Subject = "Created by NETVisualizer";

            PdfPage page = doc.AddPage();
            x_offset = Renderer.Origin.X;
            y_offset = Renderer.Origin.Y;
            page.Width = Renderer.Bottomright.X - Renderer.Origin.X;
            page.Height = Renderer.Bottomright.Y - Renderer.Origin.Y;

            if (colorizer != null)
                // Draw the network to the xgraphics object
                Draw(XGraphics.FromPdfPage(page), n, layout, colorizer);
            else
                Draw(XGraphics.FromPdfPage(page), n, layout, new NetworkColorizer());

            // Save the s_document...
            doc.Save(path);
        }
示例#6
0
        /// <summary>
        /// Basic constructor that initializes all events, default values and fields
        /// </summary>
        /// <param name="network"></param>
        /// <param name="layout"></param>
        /// <param name="colorizer"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        internal Renderer(IRenderableNet network, LayoutProvider layout, NetworkColorizer colorizer, int width, int height)
            : base(width, height, OpenTK.Graphics.GraphicsMode.Default, "NETVisualizer")
        {
            // Register key and mouse events
            Keyboard.KeyDown   += new EventHandler <KeyboardKeyEventArgs>(Keyboard_KeyDown);
            Mouse.ButtonDown   += new EventHandler <MouseButtonEventArgs>(Mouse_ButtonDown);
            Mouse.ButtonUp     += new EventHandler <MouseButtonEventArgs>(Mouse_ButtonUp);
            Mouse.Move         += new EventHandler <MouseMoveEventArgs>(Mouse_Move);
            Mouse.WheelChanged += new EventHandler <MouseWheelEventArgs>(Mouse_WheelChanged);

            // Set default node size
            ComputeNodeSize = new Func <string, float>(v => {
                return(2f);
            });

            MarkerSize = 2f;

            // Set default edge thickness
            ComputeEdgeThickness = new Func <Tuple <string, string>, float>(e => {
                return(0.05f);
            });

            EdgeCurvatureGamma    = (float)Math.PI / 3f;
            EdgeCurvatureSegments = 15;

            // Set network and initialize layout algorithm
            _network = network;
            _layout  = layout;
            _layout.Init(Width, Height, network);

            // Initialize colorizer
            if (colorizer == null)
            {
                _colorizer = new NetworkColorizer();
            }
            else
            {
                _colorizer = colorizer;
            }
        }
示例#7
0
        /// <summary>
        /// Creates a new instance of a Networkvisualizer which renders the specified network in real-time
        /// </summary>
        /// <param name="network">The network to render</param>
        /// <param name="layout">The layout algorithm to use</param>
        /// <param name="colorizer">The colorizer to apply. Default colors will be used if this is set to null (which is the default)</param>
        /// <param name="width">The width of the rendering window. 800 pixels by default</param>
        /// <param name="height">The height of the rendering window. 600 pixels by default</param>
        public static void Start(IRenderableNet network, LayoutProvider layout, NetworkColorizer colorizer = null, int width=800, int height=600)
        {
            // The actual rendering needs to be done in a separate thread placed in the single thread appartment state
            _mainThread = new Thread(new ThreadStart(new Action(delegate() {
                    Instance =  new Renderer(network, layout, colorizer, width, height);
                    _initialized.Set();
                    Instance.Run(80f);
            })));

            // Set single thread appartment
            _mainThread.SetApartmentState(ApartmentState.STA);
            _mainThread.Name = "STA Thread for NETVisualizer";

            // Fire up the thread and wait until initialization has been completed
            _mainThread.Start();
            _initialized.WaitOne();
        }
示例#8
0
        /// <summary>
        /// Basic constructor that initializes all events, default values and fields
        /// </summary>
        /// <param name="network"></param>
        /// <param name="layout"></param>
        /// <param name="colorizer"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        internal Renderer(IRenderableNet network, LayoutProvider layout, NetworkColorizer colorizer, int width, int height)
            : base(width, height, OpenTK.Graphics.GraphicsMode.Default, "NETVisualizer")
        {
            // Register key and mouse events
            Keyboard.KeyDown += new EventHandler<KeyboardKeyEventArgs>(Keyboard_KeyDown);
            Mouse.ButtonDown += new EventHandler<MouseButtonEventArgs>(Mouse_ButtonDown);
            Mouse.ButtonUp += new EventHandler<MouseButtonEventArgs>(Mouse_ButtonUp);
            Mouse.Move += new EventHandler<MouseMoveEventArgs>(Mouse_Move);
            Mouse.WheelChanged += new EventHandler<MouseWheelEventArgs>(Mouse_WheelChanged);

            // Set default node size
            ComputeNodeSize = new Func<string, float>(v => {
                return 2f;
            });

            MarkerSize = 2f;

            // Set default edge thickness
            ComputeEdgeThickness = new Func<Tuple<string,string>, float>( e => {
                return 0.05f;
            });

            EdgeCurvatureGamma = (float)Math.PI / 3f;
            EdgeCurvatureSegments = 15;

            // Set network and initialize layout algorithm
            _network = network;
            _layout = layout;
            _layout.Init(Width, Height, network);

            // Initialize colorizer
            if (colorizer == null)
                _colorizer = new NetworkColorizer();
            else
                _colorizer = colorizer;
        }
        private static void DrawEdge(XGraphics g, Tuple<string, string> e, LayoutProvider layout, NetworkColorizer colorizer)
        {
            string v = e.Item1;
            string w = e.Item2;
            float width = Renderer.ComputeEdgeThickness(e);
            XColor color = colorizer[e];

            List<Vector2> points = new List<Vector2>();

            // Draw curved edge
            if (Renderer.CurvedEdges)
            {
                // The two end points of the arc
                Vector2 pos_v = new Vector2(Renderer.Layout.GetPositionOfNode(v).X,Renderer.Layout.GetPositionOfNode(v).Y);
                Vector2 pos_w = new Vector2(Renderer.Layout.GetPositionOfNode(w).X, Renderer.Layout.GetPositionOfNode(w).Y);

                if (pos_v == pos_w)
                    return;

                // The vector vw representing one point of an equilateral triangle (v,w,x) with x being the center of the circle
                Vector2 vw = Vector2.Subtract(pos_w, pos_v);

                // In an equilateral triangle, the two angles adjacent to vw are alpha
                float alpha = ((float)Math.PI - Renderer.EdgeCurvatureGamma) / 2f;

                // Compute the radius based on the sine rule ...
                float radius = Math.Abs((float)(vw.Length * Math.Sin(alpha) / Math.Sin(Renderer.EdgeCurvatureGamma)));

                // Compute center point
                Vector2 center = vw;
                center.Normalize();
                float rotated_x = (float)(center.X * Math.Cos(alpha) - center.Y * Math.Sin(alpha));
                float rotated_y = (float)(center.X * Math.Sin(alpha) + center.Y * Math.Cos(alpha));
                center.X = rotated_x;
                center.Y = rotated_y;
                Vector2 pos_center = Vector2.Add(pos_v, Vector2.Multiply(center, radius));

                // The vector xv that will be rotatd in every step ...
                Vector2 xv = Vector2.Subtract(pos_v, pos_center);

                // The point on the circle to use for the next line segment
                Vector2 circle_point = xv;

                // Initiate the drawing ...

                // Gradually rotate the vector circle_point to get the points on the circle to connect to a curved edge
                if (Renderer.orientation(pos_center, pos_v, pos_w) > 0)
                    for (int i = 0; i <= Renderer.EdgeCurvatureSegments; i++)
                    {
                        points.Add(Vector2.Add(pos_center, circle_point));
                        float new_x = (float)(circle_point.X * Math.Cos(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) - circle_point.Y * Math.Sin(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        float new_y = (float)(circle_point.X * Math.Sin(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) + circle_point.Y * Math.Cos(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        circle_point = new Vector2(new_x, new_y);
                    }
                else
                    for (int i = 0; i <= Renderer.EdgeCurvatureSegments; i++)
                    {
                        points.Add(Vector2.Add(pos_center, circle_point));
                        float new_x = (float)(circle_point.X * Math.Cos(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) - circle_point.Y * Math.Sin(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        float new_y = (float)(circle_point.X * Math.Sin(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) + circle_point.Y * Math.Cos(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        circle_point = new Vector2(new_x, new_y);
                    }
            }
            // Draw straight edge as a simple line between the vertices
            else
            {
                points.Add(new Vector2(Renderer.Layout.GetPositionOfNode(v).X, Renderer.Layout.GetPositionOfNode(v).Y));
                points.Add(new Vector2(Renderer.Layout.GetPositionOfNode(w).X, Renderer.Layout.GetPositionOfNode(w).Y));
            }

            for (int i = 1; i < points.Count; i++)
                g.DrawLine(new XPen(color, width), points[i - 1].X-x_offset, points[i - 1].Y-y_offset, points[i].X-x_offset, points[i].Y-y_offset);
        }
示例#10
0
        private static void DrawVertex(XGraphics g, string v, LayoutProvider layout, NetworkColorizer colorizer)
        {
            OpenTK.Vector3 p = layout.GetPositionOfNode(v);

            double size = Renderer.ComputeNodeSize(v);

            if (!double.IsNaN(p.X) &&
               !double.IsNaN(p.Y) &&
               !double.IsNaN(p.Z))
                g.DrawEllipse(new SolidBrush(colorizer[v]), p.X - size / 2d - x_offset, p.Y - size / 2d - y_offset, size, size);
        }
 private static void Draw(XGraphics g, IRenderableNet n, LayoutProvider layout, NetworkColorizer colorizer)
 {
     lock (n)
     {
         if (g == null)
         {
             return;
         }
         g.SmoothingMode = PdfSharp.Drawing.XSmoothingMode.HighQuality;
         g.Clear(Color.White);
         foreach (var e in n.GetEdgeArray())
         {
             if (string.Compare(e.Item1, e.Item2) >= 0)
             {
                 DrawEdge(g, e, layout, colorizer);
             }
         }
         foreach (string v in n.GetVertexArray())
         {
             DrawVertex(g, v, layout, colorizer);
         }
     }
 }
        public static void CreatePDF(string path, IRenderableNet n, LayoutProvider layout, NetworkColorizer colorizer = null)
        {
            PdfSharp.Pdf.PdfDocument doc = new PdfDocument();
            doc.Info.Title   = "Network";
            doc.Info.Subject = "Created by NETVisualizer";

            PdfPage page = doc.AddPage();

            x_offset    = Renderer.Origin.X;
            y_offset    = Renderer.Origin.Y;
            page.Width  = Renderer.Bottomright.X - Renderer.Origin.X;
            page.Height = Renderer.Bottomright.Y - Renderer.Origin.Y;


            if (colorizer != null)
            {
                // Draw the network to the xgraphics object
                Draw(XGraphics.FromPdfPage(page), n, layout, colorizer);
            }
            else
            {
                Draw(XGraphics.FromPdfPage(page), n, layout, new NetworkColorizer());
            }

            // Save the s_document...
            doc.Save(path);
        }
        private static void DrawEdge(XGraphics g, Tuple <string, string> e, LayoutProvider layout, NetworkColorizer colorizer)
        {
            string v     = e.Item1;
            string w     = e.Item2;
            float  width = Renderer.ComputeEdgeThickness(e);
            XColor color = colorizer[e];

            List <Vector2> points = new List <Vector2>();

            // Draw curved edge
            if (Renderer.CurvedEdges)
            {
                // The two end points of the arc
                Vector2 pos_v = new Vector2(Renderer.Layout.GetPositionOfNode(v).X, Renderer.Layout.GetPositionOfNode(v).Y);
                Vector2 pos_w = new Vector2(Renderer.Layout.GetPositionOfNode(w).X, Renderer.Layout.GetPositionOfNode(w).Y);

                if (pos_v == pos_w)
                {
                    return;
                }

                // The vector vw representing one point of an equilateral triangle (v,w,x) with x being the center of the circle
                Vector2 vw = Vector2.Subtract(pos_w, pos_v);

                // In an equilateral triangle, the two angles adjacent to vw are alpha
                float alpha = ((float)Math.PI - Renderer.EdgeCurvatureGamma) / 2f;

                // Compute the radius based on the sine rule ...
                float radius = Math.Abs((float)(vw.Length * Math.Sin(alpha) / Math.Sin(Renderer.EdgeCurvatureGamma)));

                // Compute center point
                Vector2 center = vw;
                center.Normalize();
                float rotated_x = (float)(center.X * Math.Cos(alpha) - center.Y * Math.Sin(alpha));
                float rotated_y = (float)(center.X * Math.Sin(alpha) + center.Y * Math.Cos(alpha));
                center.X = rotated_x;
                center.Y = rotated_y;
                Vector2 pos_center = Vector2.Add(pos_v, Vector2.Multiply(center, radius));

                // The vector xv that will be rotatd in every step ...
                Vector2 xv = Vector2.Subtract(pos_v, pos_center);

                // The point on the circle to use for the next line segment
                Vector2 circle_point = xv;

                // Initiate the drawing ...

                // Gradually rotate the vector circle_point to get the points on the circle to connect to a curved edge
                if (Renderer.orientation(pos_center, pos_v, pos_w) > 0)
                {
                    for (int i = 0; i <= Renderer.EdgeCurvatureSegments; i++)
                    {
                        points.Add(Vector2.Add(pos_center, circle_point));
                        float new_x = (float)(circle_point.X * Math.Cos(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) - circle_point.Y * Math.Sin(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        float new_y = (float)(circle_point.X * Math.Sin(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) + circle_point.Y * Math.Cos(Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        circle_point = new Vector2(new_x, new_y);
                    }
                }
                else
                {
                    for (int i = 0; i <= Renderer.EdgeCurvatureSegments; i++)
                    {
                        points.Add(Vector2.Add(pos_center, circle_point));
                        float new_x = (float)(circle_point.X * Math.Cos(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) - circle_point.Y * Math.Sin(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        float new_y = (float)(circle_point.X * Math.Sin(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments) + circle_point.Y * Math.Cos(-Renderer.EdgeCurvatureGamma / Renderer.EdgeCurvatureSegments));
                        circle_point = new Vector2(new_x, new_y);
                    }
                }
            }
            // Draw straight edge as a simple line between the vertices
            else
            {
                points.Add(new Vector2(Renderer.Layout.GetPositionOfNode(v).X, Renderer.Layout.GetPositionOfNode(v).Y));
                points.Add(new Vector2(Renderer.Layout.GetPositionOfNode(w).X, Renderer.Layout.GetPositionOfNode(w).Y));
            }

            for (int i = 1; i < points.Count; i++)
            {
                g.DrawLine(new XPen(color, width), points[i - 1].X - x_offset, points[i - 1].Y - y_offset, points[i].X - x_offset, points[i].Y - y_offset);
            }
        }