Draw a graph with vertices in a line

Mar 23, 2012 at 9:51 AM

Hi,

I need to draw a zoomable graph that has vertices on a line (it is a time line, so each vertex represents a point of time), and edges from these vertices to vertices with information. Is it possible with NodeXL? What classes should I use?
I'm using C# and Windows.Forms. I am new to NodeXL and I have just downloaded the NodeXL class library and run an example with NodeXLControl from help. Maybe you could also advise what sections of NodeXLApi help I should read in my case?

Thanks,

Alya

Mar 23, 2012 at 4:56 PM
Edited Mar 23, 2012 at 4:56 PM

Hello, Alya:

The NodeXLControl is appropriate for drawing a network, which is a collection of vertices connected by edges.  Usually, the vertices are laid out using an intelligent algorithm that places them all over the graph.  There are no built-in facilities for laying out your point-in-time vertices along a line, and then intelligently placing information vertices near the point-in-time vertices.  With enough programming work you could probably get the NodeXLControl to do that, but I can't help but wonder whether there is another control out there that might be more appropriate for your particular application and would require less work on your part.  Something intended specifically for a timeline, perhaps.

-- Tony

Mar 24, 2012 at 12:25 PM

Hi Tony,

Thank you for your answer.

Actually, it is a problem to find the control that suits my needs, though I'm still searching. Could you please advise what parts of source code I should change in order to implement this timeline possibility? Or at least what classes should I refer to in the first place? Actually, I do not need timeline with vertices, it can be just a line with dates and edges to actual vertices. Though I do not know which would be easier to implement, the line without vertices or the line consisting of vertices.

Mar 24, 2012 at 9:14 PM

Alya:

I don’t recommend this, because it reeks of using a screwdriver to drive a nail when finding a hammer might take some time but be far more effective.  With that warning sternly delivered, here are some guidelines.

* First, I don’t think you need to recompile the NodeXL source code.  I believe that just the prebuilt NodeXL Class Libraries, which you have already downloaded, will suffice.

* See the NodeXLApi.chm help file in that download for more details about what I talk about here.

* The essence of your problem is that you need to lay out your vertices in a very specific manner.  NodeXL has an extensible family of “layout” classes whose job it is to set the location of each of the graph’s vertices before the graph is drawn.  There is a CircleLayout class, for example, and a GridLayout class.  There is no TimelineLayout, but you can create your own.

* To create your custom TimelineLayout, derive it from the abstract class Smrf.NodeXL.Layouts.LayoutBase.  You can create your own layout class from scratch, but if you derive from LayoutBase instead, most of the miscellaneous layout details are taken care of for you.

* When deriving from LayoutBase, all you have to implement is the abstract method LayOutGraphCore(), which sets the IVertex.Location property of each of the graph’s vertices.  That’s all it does.  You have to compute the locations yourself, but the rest of NodeXL will take care of drawing the graph for you.

* LayOutGraphCore() is a protected method that is not documented in NodeXLApi.chm.  You’ll want to download the source code so you can read the method’s comments.  Again, you don’t have to actually recompile the source code.

* When computing the location of the vertices, LayOutGraphCore() needs to be able to identify the special vertices that represent dates.  When your application populates your NodeXL group, it should “mark” those vertices using a special key that you define, like this:

IVertex dateVertex = nodeXLControl.Graph.Vertices.Add();
dateVertex.SetValue(“ThisIsADateVertex”, null);

* Then LayOutGraphCore() can check for this key like so:

Boolean isDateVertex = someVertex.ContainsKey(“ThisIsADateVertex”);

If it’s a date vertex, its Location property should be set so that it falls on your timeline.  Otherwise, the Location property should be set to I-don’t-know-what.  That’s up to you.

* To use your custom TimeLineLayout, do this:

PopulateNodeXLControl();
nodeXLControl.Layout = new TimelineLayout();
nodeXLControl.DrawGraph(true);

-- Tony

Apr 2, 2012 at 2:24 PM

Tony,

Thank you very much for your detailed explanation. I took your warning into consideration, however, I still cannot find a suitable option for me.

I have a question concerning zooming. Is it possible to change the graph after zooming to a certain extent? For example, I have a graph displaying some statistic information with months vertices on timeline and number of meetings held in months in informaion vertices. But after zooming to the extent of the month, I want to redraw the graph and see another one with concrete dates and concrete information of each meeting. So, is it possible somehow to trace the zooming scale?

Alya

Apr 3, 2012 at 1:52 AM

Alya:

The NodeXLControl has a GraphZoomChanged event that fires whenever the graph is zoomed.  In the event handler, you can read the NodeXLControl.GraphZoom property to determine the zoom level of the graph.

You can modify the graph's vertices and edges and then call NodeXLControl.DrawGraph(false) to redraw the graph without laying out the vertices again.  However, I have never tried doing that from a GraphZoomChanged event handler and I wouldn't be surprised if it caused problems.  It's kind of a strange thing to do.

An alternative technique you might consider is to have two NodeXLControls stacked on top of each other, with the top one not visible (topNodeXLControl.Visibility = Visibility.Hidden).  When the user zooms into the bottom NodeXLControl, populate the top one with concrete dates and meeting information, then make the top one visible.  When the user zooms out of the top one, make it invisible again.  Just an idea.

-- Tony