Legends and Titles

Sometimes in addition to the nodes and links that are the subject of a diagram, one also wants to display a "legend" or "key" describing the different kinds of nodes or links. Perhaps one also wants there to be "title" for the diagram in large letters.

Outside of Diagram

First, you must consider whether titles or legends should be part of the diagram or not. You can create whatever you want outside of the diagram.

Note that anything in outside the diagram will not automatically scroll and zoom along with the diagram's contents shown in the viewport. But elements could be positioned in front of or behind the diagram's element.

Unmodeled Parts

Second, you should consider whether the title or legend should be held in your data model. Do you need to save and load that data in your database?

If you do not want to these objects to be included in your application's data model, you can just create them as simple Parts and Diagram.Add them to your diagram at explicitly defined Part.Locations.


  SetupForLegends();  // this creates a diagram just like the first example

  diagram.Add(
    new Part { Location = new Point(0, -40) }
      .Add(new TextBlock("A Title") { Font = new Font("Segoe UI", 24, FontWeight.Bold, FontUnit.Point), Stroke = "green" })
  );

If you do not assign a location or position for your Parts, and if your Diagram.Layout (if any) does not assign any Part.Location, then there might not be a real location for those parts and they might not appear anywhere in the diagram.

All of the predefined Layouts that make use of Networks, including TreeLayout, do not operate on simple Parts but only on Nodes and Links. If you had added a Node to the diagram it would have been positioned as part of this diagram's normal tree layout, even though you explicitly set its location. Alternatively it could still be a Node if you set its Part.IsLayoutPositioned property to false.

The title is selectable and movable and copyable and deletable in the diagram above. You may want to set properties such as Part.Selectable to false.

For an example showing a legend, see the Family Tree sample.

Modeled Parts

If on the other hand you do want to store your titles or legends in your model, you can do so using the normal mechanisms. Typically you will use node categories and template maps.

If you do not want your users to manipulate those objects, you will want to set Part.Selectable to false. You may want to set Part.LayerName to "Grid", so that it is always in the background behind everything else. (All Parts in the "Grid" Layer are automatically not selectable, because Layer.AllowSelect is false for that Layer.)

Static Parts

Third, consider whether you want the title or legend to move or scale as the user scrolls or zooms the diagram. If you want to keep such a decoration at the same position in the viewport, it might be easiest to do so by implementing it as a UI element that is superimposed with the diagram's element.

However if you really want to implement it using a GoDiagram Part, you can do so by implementing a "ViewportBoundsChanged" DiagramEvent listener that continually resets the position and scale to values that make them appear not to move as the user scrolls or zooms.


  SetupForLegends();  // this creates a diagram just like the first example

  diagram.Add(
    new Part {
        LayerName = "Grid"  // this Layer is behind everything and is not interactive
      }
      .Set(new {
        _ViewPosition = new Point(0, 0)  // some position in the viewport, not in document coordinates
      })
      .Add(new TextBlock("A Title") { Font = new Font("Segoe UI", 24, FontWeight.Bold, FontUnit.Point), Stroke = "green" })
  );

  diagram.ViewportBoundsChanged += (s, e) => {
    e.Diagram.Commit(dia => {
      // only iterates through simple Parts in the diagram, not Nodes or Links
      foreach (var part in dia.Parts) {
        // and only on those that have the "_viewPosition" property set to a Point
        if (part["_ViewPosition"] != null) {
          part.Position = dia.TransformViewToDoc((Point)part["_ViewPosition"]);
          part.Scale = 1 / dia.Scale;  // counteract any zooming
        }
      }
    }, null);  // set SkipsUndoManager to true, to avoid recording these changes
  };

Note that as the user pans or scrolls or zooms the diagram, the title remains at the same viewport position at apparently the same effective size. This example makes use of the "Grid" Layer (see Intro to Layers), which is convenient for making sure the title (or legend) stays in the background and does not participate in selection or mouse events or the UndoManager.