Programming with .NetMap components

Coordinator
Jul 19, 2008 at 2:53 PM
Developers can embed (Excel) .NetMap components into their own applications.  Building a .NetMap application?  Discuss it here!
Aug 12, 2008 at 9:25 AM
Is it possible to embed a .NetMap component within a WPF application?
Coordinator
Aug 12, 2008 at 4:09 PM
In general, you can embed Windows Forms controls in WPF applications via the WindowsFormsHost control.  I haven't tried this with NetMapControl, which is .NetMap's Windows Forms control.  If anyone tries it, please let us know how it works by posting here.

-- Tony
Aug 13, 2008 at 11:48 AM
I tried it and it works. Thank you very much.
Aug 26, 2008 at 7:38 PM
Hi all,

I've played a bit with the .NetMap libs today in a winform app and I must say I really like it.
Thing is, i want to set a different color for one particular vertex and just to keep things simple, i've used the sample code from the help file:
             using System;
             using System.Windows.Forms;
             using Microsoft.NetMap.Visualization;
             using Microsoft.NetMap.Core;
             
             namespace WindowsFormsApplication1
             {
             public partial class Form1 : Form
             {
                 public Form1()
                 {
                     InitializeComponent();
                 
                     oNetMapControl.BeginUpdate();
                 
                     // Get the graph's vertex collection.
                 
                     IVertexCollection oVertices = oNetMapControl.Graph.Vertices;
                 
                     // Add three vertices.
                 
                     IVertex oVertexA = oVertices.Add();
                     IVertex oVertexB = oVertices.Add();
                     IVertex oVertexC = oVertices.Add();
                    
                     // Change vertex color..
                     oVertexA.SetValue(ReservedMetadataKeys.PerColor, Color.Purple);
                 
                     // Get the graph's edge collection.
                 
                     IEdgeCollection oEdges = oNetMapControl.Graph.Edges;
                 
                     // Connect the vertices with edges.
                 
                     oEdges.Add(oVertexA, oVertexB);
                     oEdges.Add(oVertexB, oVertexC);
                     oEdges.Add(oVertexC, oVertexA);
                 
                     oNetMapControl.EndUpdate();
                 }
             }
                 
             }
As you can see in the code I want to change the color of oVertexA to purple, but when i run this sample, it will just show me 3 black vertices:(. I also tried to create the vertex first and then add it, but that won't work either..:
            Vertex oVertexA = new Vertex();
            oVertexA.SetValue(ReservedMetadataKeys.PerColor, Color.Purple);
            oVertices.Add(oVertexA);

Any ideas?

Thanks in advance.

David


        
    
Coordinator
Aug 26, 2008 at 9:07 PM

David:

You have to change the NetMapControl.VertexDrawer to a PerVertexDrawer to get the control to recognize per-vertex attributes, including color, shape, and radius.  I'll update the documentation, which I realize doesn't make this obvious.

Below my signature is updated sample code.

-- Tony

using System;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.NetMap.Visualization;
using Microsoft.NetMap.Core;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            oNetMapControl.BeginUpdate();

            // Replace the default vertex drawer with one that will vary the
            // color, radius, and shape of vertices based on metadata values
            // stored in the vertices.  (Note that there are also
            // PerVertexWithLabel and PerVertexWithImage drawers that do the
            // same thing and more.)

            oNetMapControl.VertexDrawer = new PerVertexDrawer();

            // Get the graph's vertex collection.

            IVertexCollection oVertices = oNetMapControl.Graph.Vertices;

            // Add three vertices.

            IVertex oVertexA = oVertices.Add();
            IVertex oVertexB = oVertices.Add();
            IVertex oVertexC = oVertices.Add();

            // Customize their appearance.

            oVertexA.SetValue(ReservedMetadataKeys.PerColor, Color.Blue);
            oVertexA.SetValue(ReservedMetadataKeys.PerVertexRadius, 15F);

            oVertexB.SetValue(ReservedMetadataKeys.PerColor, Color.Orange);
            oVertexB.SetValue(ReservedMetadataKeys.PerVertexRadius, 20F);
            oVertexB.SetValue(ReservedMetadataKeys.PerVertexShape,
                VertexDrawer.VertexShape.Sphere);

            // Get the graph's edge collection.

            IEdgeCollection oEdges = oNetMapControl.Graph.Edges;

            // Connect the vertices with edges.

            oEdges.Add(oVertexA, oVertexB);
            oEdges.Add(oVertexB, oVertexC);
            oEdges.Add(oVertexC, oVertexA);

            oNetMapControl.EndUpdate();

        }
    }
}

Coordinator
Aug 27, 2008 at 12:05 AM

Here is a slightly modified version of the above code.  It's the version I'm putting into the documentation.

-- Tony

using System;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.NetMap.Visualization;
using Microsoft.NetMap.Core;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        netMapControl1.BeginUpdate();

        // The default vertex drawer draws all vertices with the same
        // color, radius, and shape.  Replace it with one that will vary
        // the appearance of each vertex based on metadata values stored in
        // the vertices.  (Note that there are also PerVertexWithLabel and
        // PerVertexWithImage drawers that do the same thing and more.)

        netMapControl1.VertexDrawer = new PerVertexDrawer();

        // Replace the default edge drawer with one that will vary the
        // color and width of each edge based on metadata values
        // stored in the edges.  (Note that there are also
        // PerEdgeWithLabel and PerEdgeWithImage drawers that do the
        // same thing and more.)

        netMapControl1.EdgeDrawer = new PerEdgeDrawer();

        // Get the graph's vertex collection.

        IVertexCollection oVertices = netMapControl1.Graph.Vertices;

        // Add three vertices.

        IVertex oVertexA = oVertices.Add();
        IVertex oVertexB = oVertices.Add();
        IVertex oVertexC = oVertices.Add();

        // Customize their appearance.

        oVertexA.SetValue(ReservedMetadataKeys.PerColor, Color.Blue);
        oVertexA.SetValue(ReservedMetadataKeys.PerVertexRadius, 15F);

        oVertexB.SetValue(ReservedMetadataKeys.PerColor, Color.Orange);
        oVertexB.SetValue(ReservedMetadataKeys.PerVertexRadius, 20F);
        oVertexB.SetValue(ReservedMetadataKeys.PerVertexShape,
            VertexDrawer.VertexShape.Sphere);

        // Get the graph's edge collection.

        IEdgeCollection oEdges = netMapControl1.Graph.Edges;

        // Connect the vertices with directed edges.

        IEdge oEdge1 = oEdges.Add(oVertexA, oVertexB, true);
        IEdge oEdge2 = oEdges.Add(oVertexB, oVertexC, true);
        IEdge oEdge3 = oEdges.Add(oVertexC, oVertexA, true);

        // Customize their appearance.

        oEdge1.SetValue(ReservedMetadataKeys.PerColor, Color.Chartreuse);
        oEdge1.SetValue(ReservedMetadataKeys.PerEdgeWidth, 3);

        oEdge2.SetValue(ReservedMetadataKeys.PerEdgeWidth, 5);

        oEdge3.SetValue(ReservedMetadataKeys.PerColor, Color.ForestGreen);

        netMapControl1.EndUpdate();
    }
}
}

Aug 27, 2008 at 6:18 AM
Wow!
Thanks for the quick response:)
It works now with the PerVertexDrawer.

Thanks again, and keep up the good work. Really like these projects @ MS Research :)

David.
Aug 31, 2008 at 4:11 PM
Hello All,

I am trying to select a vertex programatically. I tried the code listed below but it doesn't work. Any ideas?

using System;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.NetMap.Visualization;
using Microsoft.NetMap.Core;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        netMapControl1.BeginUpdate();

        netMapControl1.VertexDrawer = new PerVertexDrawer();

        netMapControl1.EdgeDrawer = new PerEdgeDrawer();

        // Get the graph's vertex collection.

        IVertexCollection oVertices = netMapControl1.Graph.Vertices;

        // Add three vertices.

        IVertex oVertexA = oVertices.Add();
        IVertex oVertexB = oVertices.Add();
        IVertex oVertexC = oVertices.Add();

        netMapControl1.SetVertexSelected(oVertexA, true, false);

        netMapControl1.EndUpdate();
    }
}
}

Thanks a million.

Coordinator
Aug 31, 2008 at 6:12 PM
That's a bug in the NetMapControl.  It mistakenly skips all selection-related calls if the graph hasn't been drawn yet, and until EndUpdate() is called, the graph isn't drawn.  And you can't move the SetVertexSelected() call to the line after EndUpdate(), because then the graph drawer will be busy and you'll get a thread-related exception.

I've fixed the bug in my local build and the fix will be in the next posted release.  Until then, here is a terribly ugly but simple timer-assisted workaround.

-- Tony


using System;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.NetMap.Visualization;
using Microsoft.NetMap.Core;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            netMapControl1.BeginUpdate();

            netMapControl1.VertexDrawer = new PerVertexDrawer();

            netMapControl1.EdgeDrawer = new PerEdgeDrawer();

            // Get the graph's vertex collection.

            IVertexCollection oVertices = netMapControl1.Graph.Vertices;

            // Add three vertices.

            IVertex oVertexA = oVertices.Add();
            IVertex oVertexB = oVertices.Add();
            IVertex oVertexC = oVertices.Add();

            {
            // Ugly, TEMPORARY HACK until fix for NetMapControl selection bug
            // is posted.

            Timer oTimer = new Timer();
            oTimer.Interval = 200;

            oTimer.Tick += delegate {
                netMapControl1.SetVertexSelected(oVertexA, true, false);
                };

            oTimer.Start();
            }

            netMapControl1.EndUpdate();
        }
    }
}

 

Sep 1, 2008 at 7:17 AM
Great, it worked now. Thank you very much.
Sep 15, 2008 at 7:50 AM
Hi all,

Is there any way to show labels when using the SugiyamaVertexDrawer?

I'm now using the Sugiyama layout on my graph, but since I've applied the new layout, the labes won't show up in the graph:(

Thanks in advance.

David
Coordinator
Sep 15, 2008 at 4:10 PM

David:

The Sugiyama layout doesn't currently support all of the drawing features available with the other layouts, including labels.  We do have a work item to update the layout, but it hasn't been scheduled yet.  (We also have work items to improve the Fruchterman-Reingold layout, and possibly introduce new layout algorithms.)

-- Tony

Sep 16, 2008 at 9:35 AM
Tony,

Too bad this isn't possible out of the box. I found a workaround though:
First apply the Sugiyama layout, then lock all vertices by setting the LockVertexLocation to true and then reassign the PerVertexWithLabel drawer to the netmap control.
This does the trick :).

Thanks anyway.

David