NShape Basic Tutorial

Basic Tutorial: Creating Diagrams

<< Click to Display Table of Contents >>

Navigation:  Basic Tutorial >

NShape Basic Tutorial

Basic Tutorial: Creating Diagrams

Previous pageReturn to chapter overviewNext page

In this step you will learn how to create a diagram from your program and display it.

Now that your application has some basic functionality, let us come back to the original goal: Visualizing Web statistics. The goal is to read some statistics file that contains information about web pages and referrals and translate this information into a diagram.

For the sake of simplicity, a very simple text file format is defined for the input data. We do not choose XML, because we want to read large files fast and that is still simpler with a text file than with XML. Therefore the text file shall look like this:

www.dataweb.de/de/NShape.html;www.dataweb.de/de/index.html;724
www.google.de;www.dataweb.de/de/index.html;1248
www.dataweb.de/de/NShape.html;www.dataweb.de/en/TurboDB.html;13

Each line indicates the number of referrals from the first URL to the second one. The application will read the file line by line, create a shape for each URL it does not yet now and insert the shape into a dictionary, with the URL as the key. For the first step, we will arrange the shapes in a rectangular pattern. Later in this tutorial you will see how we can use the layouter to create a nicer presentation.

On a slightly higher level, here is how you are going to do it.

How to create the diagram for the web statistics data:

1.Open the statistics file and create a StreamReader for it.
2.Create a diagram, just call diagram = new Diagram("My Diagram").
3.Read the file line by line and do the following for each line:
1.Extract the first URL (the referrer) and look the URL up in the map.
2.If it is not yet there, create a shape, add it to the diagram and insert it into the map.
3.Do the same for the second URL.
4.Ignore the frequency for now.
4.Insert the diagram and its shapes into the repository and display it.

The repository has two sets of methods for inserting and deleting objects:
The Insert / Delete methods will only insert / delete the object itself but no child or contained objects.
The InsertAll / DeleteAll methods will insert / delete the object including its children or contained objects.

For performance reasons, the repository does no consistency checks by default.

For developing applications that insert objects into the repository, we recommend adding and linking the project "NShape" to your application's solution and defining the conditional define REPOSITORY_CHECK

Creating a shape is a bit different from creating a diagram, because shape libraries can be loaded dynamically. The project has a list of available shape types in its ShapeTypes property. You can select a shape type by its name and then call the shape type's CreateInstance method to create the actual shape.

After you have created the diagram you must add it to the repository, so that modifications can be tracked and the diagram can be saved. And finally, you display it.

This simple application can only display one diagram. Therefore, you should either delete all diagrams in the repository before adding a new one or you can modify the code that loads and displays the diagram. Otherwise you won't see the new diagram "D1".

How to display the created diagram:

1.Add namespaces Dataweb.NShape and Dataweb.NShape.Advanced.
2.Add menu item File > Load Statistics.
3.Create a handler for this menu item and insert the code below.
4.Run the application and execute the menu command File > Load Statistics. The display shows an ellipse for each web page in the data file.
This diagram has been created from statistical data through code.

This diagram has been created from statistical data through code.

Here is the code:

private void fileLoadStatisticsToolStripMenuItem_Click(object sender, EventArgs e) {
 // Delete all diagrams (including all their shapes)
 List<Diagram> diagrams = new List<Diagram>(project1.Repository.GetDiagrams());
 for (int i = diagrams.Count - 1; i >= 0; --i)
         project1.Repository.DeleteAll(diagrams[i]);
 // Prepare local variables needed for processing the web statistics file
 Dictionary<string, RectangleBase> shapeDict = new Dictionary<string, RectangleBase>(1000);
 int x = 10;
 int y = 500;
 string statisticsFilePath = @"..\..\Demo Programs\Tutorials\Basic\Sample Data\Small.txt";
 // Create a new diagram for visualizing the web statistics
 Diagram diagram = new Diagram("D1");
 // Read the web statistics file line by line and create shapes for visualization
 using (TextReader reader = new StreamReader(statisticsFilePath)) {
         string line = reader.ReadLine();
         while (line != null) {
                 int idx1 = line.IndexOf(';');
                 int idx2 = line.IndexOf(';', idx1 + 1);
                 RectangleBase shape;
                 string url = line.Substring(0, idx1);
                 if (!shapeDict.TryGetValue(url, out shape)) {
                         // If no shape was created for the web page yet, create one.
                         // For simplicity, we call the CreateInstance method of the shape type instead of 
                         // creating a shape from a template (which is recommended for most cases, see chapter 8)
                         shape = (RectangleBase)project1.ShapeTypes["Ellipse"].CreateInstance();
                         // Set size of the shape
                         shape.Width = 100;
                         shape.Height = 60;
                         // Set position of the shape (diagram coordinates)
                         shape.X = x + 50;
                         shape.Y = y + 50;
                         // Set text of the shape
                         shape.SetCaptionText(0, Path.GetFileNameWithoutExtension(url));
                         // Add shape to the diagram
                         diagram.Shapes.Add(shape);
                         // Add shape to the local dictionary
                         shapeDict.Add(url, shape);
                         // Advance position (for the next shape)
                         x += 120;
                         if (x > 1200) {
                                 x = 10;
                                 y += 70;
                         }
                 }
                 url = line.Substring(idx1 + 1, idx2 - idx1 - 1);
                 if (!shapeDict.TryGetValue(url, out shape)) {
                         // If no shape was created for the web page yet, create one.
                         // For simplicity, we call the CreateInstance method of the shape type instead of 
                         // creating a shape from a template (which is recommended for most cases, see chapter 8)
                         shape = (RectangleBase)project1.ShapeTypes["Ellipse"].CreateInstance();
                         // Set size of the shape
                         shape.Width = 100;
                         shape.Height = 60;
                         // Set position of the shape (diagram coordinates)
                         shape.X = x + 50;
                         shape.Y = y + 50;
                         // Set text of the shape
                         shape.SetCaptionText(0, Path.GetFileNameWithoutExtension(url));
                         // Add shape to the diagram
                         diagram.Shapes.Add(shape);
                         // Add shape to the local dictionary
                         shapeDict.Add(url, shape);
                         // Advance position (for the next shape)
                         x += 120;
                         if (x > 1200) {
                                 x = 10;
                                 y += 70;
                         }
                 }
                 // Read next text line
                 line = reader.ReadLine();
         }
         reader.Close();
 }
 // Insert created diagram into the repository (otherwise it won't be saved to file)
 cachedRepository1.InsertAll(diagram);
 // Display created diagram
 display1.Diagram = diagram;
}

Tutorial Navigation