In a previous post, we saw how to use the ShapeSheet to resize text based on a shape’s size. A related question we sometimes hear is how to make a shape automatically resize to contain its text. Visio includes some shapes that resize based on their text. Go to File > Shapes > Visio Extras > Callouts and try out the shapes near the top of the stencil. Let’s see how to build this into a shape.
People often want to fit more text into flowchart shapes. We can make the text smaller for shapes that cannot fit all the text, but this sometimes makes diagrams difficult to read. In other cases, it is OK to resize shapes based on the amount of text they contain. Let’s say we have this piece of a process flowchart.
The size of the Document shapes is unimportant, so we can create a formula to control the height of the shape. Select the shape and open its ShapeSheet by choosing Window > Show ShapeSheet. Visio opens a new window that shows the properties that drive the shape’s behavior.
The shape is taller, but the text still doesn’t fit right. In this case, the Document shape is designed to keep the bottom of the text block above the rounded part of the shape, preventing it from being obscured. We can just add a little buffer to the height of the shape.
But if the shape is resized manually by adjusting the green handles shown when the shape is selected, the formula will be lost. We want the shape to always be at least as tall as the text it holds. We can use the SETATREFEXPR formula to “pick up” the height that is set by manipulating the green handles. Then, use MAX to compare that to the height from the formula above and use the larger of the two.
The shape still looks the same, but now if we resize the height manually, the formula is not lost. And if we try to make the shape smaller, Visio only allows it to shrink small enough to contain all the text.
If this formula were applied to all Document shapes, each one would be a different size based on the amount of text it contains. We can add a condition that keeps the shape at least as large as it was originally. With this, shapes may resize larger but never smaller. Another MAX condition ensures that Visio chooses the largest of the original size (0.75 in.), the calculated size and the manually set size.
The SETATREF trio of functions can be a little tricky to learn, but contain a lot of power for building formulas that interact well with manual changes made through Visio’s user interface. More on these in a future post.
When working with shape text through automation, the Text property of a Shape is generally sufficient to get and set the text. However, this simple property ignores the fact that Visio text may have rich formatting applied or that the text is composed of text fields. If you need a more industrial-strength way to retrieve and modify shape text, use the Characters object for the Shape.
Characters is a kind of do-it-all object for manipulating text. It is capable of breaking text down into individual characters or sets of characters. The Characters object can describe text in much the same way that the Visio Shapesheet stores shape text. Consider the following shape with text:
The shape text consists of a single line with a variety of formats applied to the characters. Visio has to keep track of not just the characters but their formatting as well. It does this using text runs. A text run is a set of characters that have something in common. Typically a text run is a set of characters with identical formatting. That is how Visio represents text in the Shapesheet.
Our sample text is described by six text runs. The number in the first column defines how many characters are in the run. Thus “Hello “ is described by the first line. “World” is in the second line. The space after “World” is next. Then “Sample “, then “Text”. Finally Visio (starting in 2003) terminates text with a non-visible character. Note that this final character is not reported when using the Shape.Text property, but it is reported using Shape.Characters.Text. Our sample text varies mostly by the Style property, which defines whether there is any bold, italics or underlining. Also the Color property varies for one text run.
There is also a notion of a paragraph run, which is the collection of all characters with the same paragraph formatting properties. Note that, like a text run, a paragraph run can span across carriage returns because it describes the formatting not the structure. The number in the first column defines the number of characters in the run. In our example all the characters in the shape text use the same paragraph formatting properties, so Visio put a zero in the column. This would similarly apply to the Characters section if there were no variation in character formatting.
The Visio SDK has sample code demonstrating how to set up custom formatting on shape text, but there isn’t an example of reading the text back. Let’s take a look at a function that can analyze Visio shape text and return the specific text runs that describe the formatting boundaries.
using IVisio = Microsoft.Office.Interop.Visio;
public class TextUtilities
public static List<string> getTextRunList(IVisio.Shape vsoShape)
List<string> textRunList = new List<string>();
// Get the Characters object representing the shape text
IVisio.Characters vsoChars = vsoShape.Characters;
int numChars = vsoChars.CharCount;
int runBegin = 0, runEnd = 1;
// Find the beginning point and end point of every text run in the shape
for (int c = 0; c < numChars; c = runEnd)
// Set the begin and end of the Characters object to the current position
vsoChars.Begin = c;
vsoChars.End = c + 1;
// Get the beginning and end of this character run
runBegin = vsoChars.get_RunBegin((short)IVisio.VisRunTypes.visCharPropRow);
runEnd = vsoChars.get_RunEnd((short)IVisio.VisRunTypes.visCharPropRow);
// Set the begin and end of the Characters object to this run
vsoChars.Begin = runBegin;
vsoChars.End = runEnd;
// Record the text in this run
// As the for loop proceeds, c is set to the end of the current run
This C# code uses a .NET 2.0 Generic string list to store each text run found. The Characters object is retrieved from the text, and the total character count is stored. Then the procedure iterates through the characters from beginning to end. However, the For Loop is unusual because it does not increment on a character by character basis. Let’s examine the For Loop more closely.
The purpose of the For Loop is to find text runs and add them to the string list. First a substring within Characters is defined by setting the Begin and End properties of Characters. This substring is initially just the next two characters in the text. Then the boundary of the text run containing those characters is established by calling RunBegin and RunEnd. These methods search for the first and last characters of the text run containing the substring. A new substring is defined by updating the Begin and End properties to match RunBegin and RunEnd. This substring is added to the text run list. Since the procedure has located the end of the current run, the For Loop is incremented to start at this position when looking for the next text run.
Once you have a list of the text run strings, you can match them with the property information retrieved from the Characters section of the Shapesheet. This gives a more complete description of the text contents. There are other uses for RunBegin and RunEnd beyond character formatting. By passing other flags to the methods, you can get the paragraph runs instead or even individual words or text fields.
When programming in Visio it is important to realize that many Visio objects have more than one name. Objects such as Pages, Masters, Cells and others have a local name and a universal name. Why two names? To address the problems that arise when combining the needs of localization (translating strings into multiple languages) with the needs of solution development (having a constant way to refer to things).
The local name is a friendly name that is displayed in the Visio user interface. For Visio’s own content, this is a string translated for the product sku of Visio (i.e. German strings in German Visio). Users have the ability to rename Page and Master and Cell objects, and that changes the local name. Local names allow users to see things in a language that makes sense to them.
The universal name is hidden from the user interface and can only be updated through automation. This keeps a universal name consistent across product versions and user edits. A constant name allows solution developers to refer to objects by an identifier that makes sense to them. This identifier works no matter what is displayed for the local name.
When working with Visio objects, developers should always use universal names to reference their objects. This advice applies to more than names. A number of properties and methods in the Visio API have universal syntax equivalents. If you find a property and notice the same property exists but ending in a ‘U’, use the universal property. A classic example is to use the FormulaU property to get and set formulas instead of Formula.
There is one special case where setting the local name of an object will automatically update the universal name to match. When the name of an object is changed the first time, both the Name and NameU properties are set to the new name. All subsequent changes to Name do not affect the NameU property. The sample code below illustrates this behavior.
Public Sub NameUDemo()
'Create a new master shape
Dim vsoMaster As Visio.Master
Set vsoMaster = ActiveDocument.Masters.Add
'Check the default Name and NameU property
Debug.Print "Initial Name/NameU:", vsoMaster.Name, vsoMaster.NameU
'Set the name of the master for the first time
vsoMaster.Name = "Apple"
'Check the current Name and NameU property
Debug.Print "Current Name/NameU:", vsoMaster.Name, vsoMaster.NameU
'Set the name of the master for the second time
vsoMaster.Name = "Banana"
Initial Name/NameU: Master.0 Master.0
Current Name/NameU: Apple Apple
Current Name/NameU: Banana Apple
There is a lot of cool functionality in Visio, and some may be more accessible than you think. Especially for those of you who are keyboard aficionados, keyboard shortcuts in Visio could save you time better spent in polishing your diagram.
Here are a few of our favorite shortcuts:
1) Getting around your diagram
2) Select, add text, and connect your shapes, as easy as 1-2-3!
3) Layout and layering of shapes
4) Duplicating selected shape
5) Switch page
6) Full screen (F5)
7) Open Visual Basic Editor (Alt + F11)
As Mai-lan’s blog mentioned before, Dan Brown has a keyboard shortcut mouse pad available here.
Also, for a complete list of Visio shortcuts see here.
Here’s a recent question on the newsgroups that has come up several times in the past. It seems that the larger you make a page in Visio, the less you can zoom in to see the details. This is true. There is a maximum zoom limit in Visio, and this maximum depends on the size of your page.
The limitation on zoom is tied to the way Visio uses Windows’ GDI display component to render pages. A Visio page is one big surface that is clipped to fit in the drawing window. This allows capabilities such as smooth panning / scrolling and rapid zoom changes because the rendered image does not need to be constantly reconstructed. In Windows 9x systems this display surface was limited to a maximum size of 32767 x 32767 pixels - basically a 16-bit system limitation.
To calculate the maximum zoom level, Visio uses this basic formula:
Max Zoom = (32767 / (Page size in inches * Screen pixels per inch)) * 100%
Max Zoom = (32767 / (Page size in inches * Screen pixels per inch)) * 100%
Take an example drawing with the largest page dimension equal to 34 inches and a standard monitor pixel density of 96 DPI. This formula evaluates to 1004%. If the page size increases, the maximum zoom decreases proportionally.
More recent versions of Windows support larger ranges in GDI. Starting with the latest service pack of Visio 2003, we have updated our zoom logic to take advantage of this headroom. At a minimum, you can zoom into your drawing at 1000% regardless of page size. The formula above is still used to determine the maximum zoom. Thus the zoom limit is the larger of the formula result or 1000%.
Hopefully this addresses most of the situations where zooming was restricted with large pages.
There have been several recent newsgroup questions relating to dragging shapes around on the page. Sometimes you get to see the geometry you are dragging around. Other times you only see an outline rectangle. A similar issue is that dragging is quite choppy such that you often don't see what you drag. Both issues deal with performance in Visio. Let's look at each one.
Drag image generation
When you drag a shape around, Visio generates a drag image to display. This is basically a bitmap representation of your shape. Seeing the actual geometry of your shape helps with positioning and alignment. If you select a bunch of shapes to drag around, the drag image that Visio must generate is more complex. This takes more time, which then makes Visio feel sluggish.
To avoid this situation, Visio has a cut-off point of 25 shapes. This 25 shape limit includes any sub-shapes of groups in the selection. If you drag around more than 25 shapes at a time, Visio will only show an outline rectangle for the drag image. You can still pause while dragging, and Visio will go ahead and generate the full image.
An interesting side effect of this threshold is that it causes 2-D glue operations to fail as well. (2-D glue means gluing a 2-D shape to another 2-D shape, while 1-D glue is the normal connector to 2-D shape operation.) 2-D glue only works when the drag image is shown. Even pausing to generate the drag image does not work around the problem. Shapes that have outward connection points on them thus need to be kept simple.
For those that would like to eliminate this threshold entirely, there is a registry key. For Visio 2003 set ‘HKCU\Software\Microsoft\Office\11.0\Visio\Application\DragBitmap’ to “2”. For Visio 2007 set ‘HKCU\Software\Microsoft\Office\12.0\Visio\Application\DragBitmap’ to “2”. The downside is that you will encounter degraded performance as you begin to drag more complex shapes around. This may or may not be noticeable on your computer.
Once you begin dragging and the drag image has been generated, a second issue affects whether you can drag it around smoothly. Visio must update the rendered drawing as you drag this image across it. This involves creating a mask out of the drag image and then doing XOR operations against pixels as things move around. Depending on how complicated the drawing page is behind the drag image, this process can take some time. The longer it takes to re-render, the choppier the drag behavior appears to be in Visio. With some really complicated drawings like inserted CAD objects, it may take more than a second for any update to occur.
Dragging performance really depends on the computer's video card, but many users have reported that dragging is actually slower on their new computers versus their older computers. How can performance be worse on a faster video card? It turns out that Visio's masking code is really old. The code makes specific calls to the video card that are no longer in use today. The cards now support much more efficient ways of doing things. In fact, video card manufacturers likely no longer optimize the legacy calls. Since Visio still does things the old-fashioned way, performance goes down on the newer cards.
There is nothing a user can do to address this second problem. The good news is that Visio 2007 has replaced it's old masking code with newer, mainstream calls to the video cards. The results are dramatic. We measured drag performance to be 150 times faster in Visio 2007! This results in very smooth dragging for even the most complex Visio diagrams.
Keep in mind that both of the two drag issues here impact what you see on the screen. One is a hard-coded limit based on shape count. The other is dependent on the performance of the video card (when used with legacy calls). If the first issue is annoying, you can use the registry fix. If the second issue is frustrating, you will need to wait for Visio 2007.
This is the fourth topic in a series discussing the essential features that make up the Visio application.
Essential Feature: Zoom
From business processes to project schedules to organization charts to network topologies, there are many different kinds of information that people and businesses use Visio to visualize. But all these scenarios have one thing in common: The business information presented in these diagrams tends to be complex. In fact, the more detailed and complicated information is, the more likely you need a tool like Visio to help organize it and present it. When drawings become large and contain detailed information, one of the most useful features in Visio is Zoom.
Zoom is a surprisingly under-utilized feature since a full page diagram is not readable on a typical screen. We see many beginners struggle to create diagrams simply because they are working at full page zoom rather than enlarging the area they are focused on. Learning how to use zoom effectively is a significant part of the transition from casual user to Visio expert.
You can change the zoom level by several means. Clicking on the zoom dropdown in the Standard toolbar is the most frequently chosen method. There is a Zoom sub-menu under View. Ctrl+Mouse Wheel also works. But Visio experts use the keyboard shortcuts: Ctrl+Shift+Left Click and Ctrl+Shift+Right Click. The keyboard shortcuts are quick. You can also do Ctrl+Shift+Left Drag to define a particular region of the page to zoom into.
Of course, once you are zoomed in, panning (scrolling the view) becomes important too. The scrollbars obviously work here. Mouse Wheel and Shift+Mouse Wheel work as well. But again the most convenient method may be Ctrl+Shift+Right Drag. Thus the Left mouse button assists with zooming and the Right mouse button assists with panning.
There is one other helpful feature for understanding your current location in relation to the entire diagram. The Pan & Zoom window shows a bird's eye view of the drawing page, and a red rectangle outlines the region currently shown in the drawing window. You can click, drag or resize the rectangle to manipulate the view in the drawing window. There is also a handy slider bar for the zoom level. The window is accessed from the View menu.
You can become quite proficient using Visio simply by using Zoom to enlarge your workspace. The most obvious benefit is that text is readable. Zoom also increases the precision of shape operations making it easy to get exactly what you want. It makes it easier to access shape object handles because they are spread farther apart. These differences are subtle but the result is a better diagramming experience.
We're going to kick off the Visio Insights blog with a series on the essential features that make Visio the popular diagramming application it is today. In each topic, we'll cover the basics from a user's perspective and then dive more deeply into the technical details.
Essential Feature: Drag and Drop
Fifteen years ago a new diagramming product hit the marketplace with a revolutionary way to draw. Rather than construct drawings from geometric primitives such as lines and arcs, Visio offered the ability to drag and drop pre-built shapes. One of the early tag-lines for Visio was Drag, Drop, Done. Making diagrams in Visio is more a matter of assembling than drawing, and this mechanism made diagramming approachable for many people.
So how does drag and drop really work?
The pre-built shapes are called Masters, often referred to as Master shapes. The masters are organized into documents called Stencils. The stencils are displayed on the left side of the drawing workspace inside the Shapes window. To add a shape to the drawing, you drag one of the masters from a stencil to the drawing page.
Behind the scenes Visio does a lot of work to place that shape on the page. A stencil is a separate document from the drawing, so Visio first must copy the master from the stencil to the drawing document. (This operation is generally not visible to the user. If you want to see the masters in the drawing document, go to File > Shapes > Show Document Stencil.) Then Visio creates an instance of the master shape and places it on the drawing page.
If you drag the same master shape out from the stencil again, Visio checks to see if there is already a copy of the master in the drawing document. If the master is already present, Visio skips the copy operation and proceeds to create another shape instance to place on the drawing page. Visio checks a property on the master called the UniqueID to determine if two masters are alike. Whenever you edit a master, the UniqueID changes. Thus it is possible for two masters to have the same name, but Visio will know that the masters are different by their UniqueIDs.
UniqueID lets Visio distinguish between two masters with the same name, but users may have more difficulty telling them apart. To avoid that problem, Visio forces the name of each master within a document to be unique. When you add a different master by the same name to a document, Visio automatically renames the incoming master by appending a decimal point and a number such as Person.1 . There may be a scenario where you want Visio to interpret masters with the same name as being identical, so there is a property on the master that you can set to “Match master by name on drop”.
Why go through all these steps to drop a shape on the page? It ensures that Visio documents are always portable. There are no external references to masters in a Visio document, so you can pass documents around and not worry about missing information. Master shapes are a powerful concept, and we'll have more to say about them in a future post.
Earlier this week we began creating a digital clock shape. In the previous post we used Visio’s shape operations feature to construct a digit shape for our clock. Today we will add a behavior to the digit to make it display any numeral required. Then we will complete the clock shape.
Our digit shape has seven geometry sections to represent the segments that make up the digit. We could make ten copies of our shape and delete the unneeded segments in each to make all ten numerals. However, our digital clock requires a single digit shape that is capable of displaying any numeral. A particular numeral is shown by showing and hiding the correct set of segments.
This special behavior will be defined using formulas we add to the Shapesheet of the digit shape. For those unfamiliar with the Shapesheet, here are the essential things to know to work with a shape:
A single User-defined cell named Digit is created to specify the current numeral to display in the shape. The NoShow cell in each geometry section is used to determine the visibility of the geometry. We enter formulas in each NoShow cell to return True or False depending on the value in User.Digit.
Each NoShow formula is a little different since it must control the visibility of a specific segment in the digit shape. The seven NoShow formulas are listed below. If you are building your own version of the digit shape, your geometry sections may be in a different order. Therefore you need to work out for yourself what formula goes where.
You can now test the digit shape by entering each of the 10 possible numerals in the User.Digit cell to verify that the correct geometry appears in each case. The digit has been transformed into a multi-shape – a single shape that can take on multiple appearances. Now we can use the digit shape to complete the clock.
The digital clock is composed of four digit shapes for the hours and minutes, plus a pair of dots separating the hour and minutes, plus a rectangle to group everything together. Four copies of the digit shape are arranged side by side. Then two small squares are drawn and formatted to match the digit shapes (using Format Painter). You can use the Combine command from the Shape > Operations menu to combine the two squares into one shape for efficiency. Then a rectangle is drawn around everything. The rectangle is moved behind the other shapes using Send to Back and given a thicker border with a slight corner rounding.
Next we need to assemble all the shapes into a group. Rather than selecting everything and grouping it, we will convert the rectangle shape into a group. This is more efficient because it takes advantage of the ability for group shapes to have their own geometry and text. The rectangle is selected and the Convert to Group command is chosen from the Shape > Grouping menu. With the rectangle still selected the other shapes are added to the selection using Shift+Click. The Add to Group command is chosen to make the digits and squares sub-shapes of the rectangle.
The group shape will keep track of the time to be displayed in the clock. It will break out the time into hours and minutes. Three User-defined cells are added to the group’s Shapesheet to track these values. The time is placed in the User.Time cell, which is set to the NOW() function for this example. This function returns the current date and time and will automatically refresh about every minute (or sooner if the user is taking other actions).
Each digit shape uses the hours and minutes information to determine what numeral to display. The User.Digit cell in each digit shape is given a special formula to extract the digit from the group’s hour or minute value. The formulas below are placed into the four User.Digit cells. The Sheet.ID in these formulas should be the Sheet.ID of the group shape. This is easily found by noticing what Sheet.ID is referenced by the formulas in the Shape Transform section of the digit shape.
First Hour Digit: INT(Sheet.14!User.Hour/10)
Second Hour Digit: MODULUS(Sheet.14!User.Hour,10)
First Minute Digit: INT(Sheet.14!User.Minute/10)
Second Minute Digit: MODULUS(Sheet.14!User.Minute,10)
This completes the digital clock! We created complex geometry using shape operations to make construction easy. Then we built a multi-shape with special behavior to selectively display the geometry. Finally the components were wrapped in a group to control the multi-shapes from a single input value. The clock in this example uses a total of six Visio shapes for the display. Using the techniques shown here though, it is possible for you to combine all the digits together with the squares into a single multi-shape – reducing the total shape count to two. We’ll explore this issue of minimizing shape count in a future post.
Visio's SpatialNeighbors property is useful for finding shapes that are nearby other shapes or that overlap other shapes. It can be used to programmatically answer the question "What did I drop my shape on top of?".
Unfortunately, the SpatialNeighbors property can be extremely slow under certain circumstances. In real world scenarios, searching might take anywhere from a second to over a minute. That's unacceptable for developers who need to make frequent calls to the method. Two factors can significantly alter the performance of the method.
First, searching group shapes is much slower than searching non-group shapes. This has to do with the way that SpatialNeighbors defines containment. Shape A is contained within Group Shape B if A is contained within the union of all the sub-shapes of B. Thus a lot of work is done to calculate that union before any relationship determination is made. It may not be possible to eliminate groups, but it is always helpful to performance to minimize the number of sub-shapes as much as possible. Also make sure to avoid nested groups. Opt instead for of a single group shape with many sub-shapes. Reducing the number of groups or shapes within groups can double or triple the performance of SpatialNeighbors.
That's a decent improvement, but the second factor is even more important for performance. With each call to SpatialNeighbors, the developer must specify the Relation types they wish to detect. The four relation types are ContainedIn, Contain, Overlap and Touching. Any combination of types can be searched for. The problem is that Visio checks for each of these relationships individually and must redo all the analysis work described above every time. This leads to astronomic execution times.
The workaround here is to not specify the relation type at all. When passing in 0 for the Relation parameter, Visio makes several internal optimizations because it no longer cares about the particular way in which two shapes are related. For developers who don't care about the relation type, passing in 0 is a couple orders of magnitude faster (100x) than passing in all the types. For those that really do need to find the shapes matching a particular relationship, call SpatialNeighbors passing in 0 to get a collection of candidate shapes. Then iterate through the collection and use the SpatialRelation property to get the relationship. This technique uses the really fast searching code to weed out all the shapes that are completely unrelated. The expensive code to determine actual relationships is then used with a much smaller set of shapes.
In the previous post we examined how the SetAtRef function could be used to keep two Shapesheet cells synchronized. Today we will explore a few advanced capabilities of SetAtRef for manipulating cell values.
Our scenario is a shape with a custom property called Size. We would like this property to control the Width of the shape. Also changes to the Width should update the Size property. A text field displays the current value of the Size property as well.
Notice that the cell values for Width and Prop.Size are not the same. Our previous solution using SetAtRef to synchronize the cells will not work. One unit of Size should correspond with 0.25 inches of Width. What we need is a way to convert between Size and Width as we are synchronizing the cells.
A first attempt might look like this:
We adjust the Width formula to take the Size value and convert it to a width. This works properly whenever the Size changes, but any change to the Width will push the wrong value back to Size. We need to take the incoming Width value and perform a conversion on it before that value is pushed to the Prop.Size cell.
Fortunately, the SetAtRef function supports this capability. You can provide an optional second argument to the function that tells Visio how to transform the incoming value. Our goal is to take the incoming Width value and divide it by the proper conversion factor to calculate the Size. To specify this as an expression in the SetAtRef function, we need a way of referencing the incoming cell value. Visio provides the SetAtRefExpr function for this purpose. SetAtRefExpr starts with no function arguments. Then Visio places the incoming cell value into the function. Like SetAtRef, for recalc SetAtRefExpr evaluates to its function argument: SetAtRefExpr(x) = x.
This almost solves the problem. However, if you look below at the resulting value put in the Prop.Size cell, you can see that Visio is putting the literal expression in the cell rather than the calculated result of the expression. The formula in Prop.Size does evaluate to 4, but we would prefer to have just the final result.
There is another function available to force Visio to evaluate the SetAtRef expression before a value is put in the cell. SetAtRefEval can be used on the entire second argument in SetAtRef or on one or more portions of the expression.
This completely solves our problem. The shape now is able to keep the Width and Size properties synchronized while converting between the two. Our final formula for the Width cell is:
SETATREF(Prop.Size,SETATREFEVAL(SETATREFEXPR(1.25 in)/0.25 in))*0.25 in
Here is a verbose description of this formula. When the Width of the shape changes, do not overwrite the contents of this cell. Place the new Width value into the SetAtRefExpr function argument. Then take the new value and divide it by 0.25 inches. Evaluate that result and place the it in the Prop.Size cell. Then recalculate the Width cell. For recalculation take the current value of Prop.Size and multiply it by 0.25 inches. This is the final value of the Width cell.
As you can see SetAtRef and its related functions allow fairly sophisticated manipulations of cell contents. The result for the user is simply intelligent shape behavior. Next time we’ll look at a few more ways that SetAtRef can be used.
To continue our exploration of best practices for shape development we will look at grouping in this post. Grouping is a convenient way of packaging shapes and is the mechanism for creating many complex shapes. Visio offers a number of capabilities for groups, from special interaction behaviors to shape transform changes. It's not surprising to see groups used extensively in master shapes. However, grouping can easily be taken too far, and you can encounter serious performance issues when that happens. Let's look at the issues in detail.
First, a group in Visio is a shape. Prior to Visio 2000 groups were special objects that were not quite the same as shapes. They were containers for shapes but could not have their own text or geometry. Beginning with Visio 2000 groups became full-fledged shapes. Today a group can have geometry and text just like any other shape. A group can be either 1-D or 2-D. It is important to note that groups are shapes too because this is one of the simplest and best optimations to make in shape design. Visio's overall performance is highly dependent on the total number of shapes being managed. A group containing two sub-shapes is three shapes to Visio. If you are using the group merely as a container, you are wasting one shape. Convert one of the sub-shapes into a group and stick the other sub-shape inside. Now you only have two shapes to provide the same functionality.
Second, there is a penalty for using groups in Visio. Every group defines a new coordinate system for the contents of the group. There is overhead required to compute the transforms for these coordinate systems to display shapes on a page. The deeper the nesting of groups the more coordinate transformation that Visio must do. Thus if you must use groups, it is better to keep the structure as flat as possible. We recommend avoiding making any shapes with more than two levels of nested groups.
The most common problem we see in custom shapes (and in some of the ones in the Visio box) is that groups are used where they are convenient, not just where they are required. This results in too many shapes being used in a master. When you are designing your custom master shape, determine the minimum number of shapes required to do the job. An additional shape is necessary when you need another piece of text separate from the shape text you already have or when you need a portion of the shape to have different line or fill formatting than the rest. These are the two conditions: more text or different formatting. You do not need a new shape for more geometry. Visio supports multiple geometry sections per shape. As long as these sections can use the same formatting, this is much more efficient than creating a group.
Let's look at an example to see the difference between grouping and geometry sections. Imagine a master consisting of 16 squares. It's easy to create this shape by drawing one square in Visio, then duplicating it 15 times. If you group all 16 squares together, you now have a group with 16 sub-shapes. (A colored box is drawn around the group just for illustration purposes.) Some basic performance testing shows that Visio takes 74 milliseconds to create 50 instances of the master on a page. Each instance requires 64.4 kilobytes of memory.
Compare that master to an similar one that uses multiple geometry sections to accomplish the same task. After duplicating the square to make 16 squares total, a Combine shape operation was run to make a single shape with 16 geometry sections. Because there is only one shape, no group is required. Performance testing shows that 50 instances take 31 milliseconds to create, and Visio requires 36.6 kilobytes of memory for each instance. Thus you get better than twice the performance and almost half the memory consumption as the group shape. The differences are more dramatic as you apply local formatting as we saw in a previous post. In this example, there is no reason to use a group because a single shape can accommodate all the necessary geometry. Additional shapes are only required if multiple pieces of text or different sets of formatting are needed.
When you do use groups make sure to keep things flat. Additional nested levels add more shapes and more overhead. Pretend that our example master was created by drawing two squares, then grouping them, then duplicating the group, then grouping that, then duplicating and grouping by two until a single group remained. The original 16 squares have become a 31 shape master.
Over the years we have received many customer drawings where performance, memory and file size are severely impacted because of too much grouping. Often it is too late to tell customers to redesign their masters to economize on shape use. Where customers have made changes, the results can be dramatic. Improvements from 2x to 10x are typical. A common excuse heard from shape designers is that they use nested groups because the masters are assemblies of standard components. The shape designers want to keep the components contained within their own groups to facilitate maintainability. Before commiting to this structure we recommend testing the performance of the shapes to know whether the tradeoff in inefficiency is acceptable.
For those that are interested in real-world examples of complex but efficient group shapes, look at the Data Graphics callouts in the new Visio 2007 Professional product. These shapes follow the strict rules for when an additional shape is required, but they have some impressive graphical looks as well.
In this post, we take a break from Visio 2007 information and explore a peculiar shape design issue. If you have worked with Groups in Visio, you have probably encountered a situation where the shapes inside of a group just don't behave properly during resize. Sometimes you want shapes inside a group to resize with the group. Sometimes you don't. Visio provides a setting to control the resize behavior, but you may be surprised how it works. Enter ResizeMode.
ResizeMode is the name of the Shapesheet cell that controls shape resize within groups. This is presented as Resize Behavior in the Format > Behavior dialog. There are three possible settings for the resize behavior: Scale with group, Reposition only and Use group's setting.
A shape inside a group will have one of these three settings. Really there are just two behaviors (scale & reposition), with the third setting just deferring up to the group for its value. The default setting is Use group, which in turn defaults to Scale. So how does Scale and Reposition affect the resizing of shapes inside a group?
Scale allows the shapes inside the group to stretch as the group stretches. Reposition maintains the original size of the shapes but moves their center as the group stretches. Sounds straightforward enough, so what's the catch?
The catch is that ResizeMode only works when used BEFORE a shape is grouped. When a shape is put into a group, Visio uses ResizeMode to determine what formulas get applied to the shape to make it resize with the group. Changing ResizeMode later on has no effect on the resize behavior. Thus it is quite likely that users change the setting and then get frustrated when nothing happens. It's just not a good design.
Here is the Shapesheet view of what is happening. ResizeMode is a cell in the Shape Transform section. The default is 0 (Use group's setting). Reposition only is 1. Scale with group is 2. Below is the Shapesheet for a shape before it is grouped.
Below is the Shapesheet of a shape with ResizeMode = 1 that is then grouped. Notice that the Width and Height formulas are untouched, but the PinX and PinY depend on the group. This is the Reposition behavior.
Below is the Shapesheet of a shape with ResizeMode = 2 that is then grouped. Notice that Width and Height now depend on the group. This is the Scale behavior.
Changing ResizeMode in the Shapesheet and in the Format > Behavior dialog has no effect on these formulas. The setting only comes into play at the time the shape is added to a group. Visio has some work to do to clean up both the design and the documentation for ResizeMode. Hopefully this article explains what is really happening.
Microsoft has released Service Pack 3 for the Visio 2003 product. You can download the pack here:
(If English is not your install language, you can change to another one on the web page.)
The set of changes is described here:
The majority of the changes in this release are security and reliability related as Visio 2003 gets much of the same hardening that has gone into more recent versions. There are also a number compatibility fixes to help Visio 2003 work with newer products such as IE7, Vista, SQL 2005 and even Visio 2007.
In particular the hyperlink problem with IE7 as described in this previous post has been corrected.
This update also applies to those running Visio for Enterprise Architects in Visual Studio 2005. A number of fixes have been made to the Software / Database functionality that resides in Visio Professional as well as VEA.
And finally no update to Visio 2003 would be complete without addressing a printing problem. Visio 2003 has had more than its fair share of printing issues. SP3 fixes a problem with very long plotter pages.
This is a beefy download at 48MB but definitely recommended.
Things have been quiet here for a bit because the product team is heads down on development. In the meantime a new blog has joined the Visio community that you might be interested in.
John Goldsmith is the author and a frequent newsgroup poster. John hopes to cover common problems discussed on the newsgroups and encourage more people to dive into the Shapesheet and Visio programmability.
If you are authoring a Visio blog and want to let us know about it, please leave a comment with the information.
Our previous post on AutoConnect in Visio 2010 discussed how Visio 2010 makes it simpler and faster for end users to create connected diagrams such as flowcharts. Many developers will be pleased to hear that Visio 2010 also brings greatly simplified utilities for working with connected diagrams programmatically. The Visio 2010 API contains new methods that let developers manipulate and traverse connected diagrams or graphs at a higher level of abstraction than previously, which can result in greater programmer productivity and more concise, readable code.
In this blog post, we will introduce the new Visio 2010 methods used for working with connected diagrams. Then we will see these methods in action by doing a visual walk-through of a program that manipulates a flowchart. (The source code and diagram used below are also available for download here.)
For each of the following API methods, we give a brief description on what the method does, along with an explanation of the method’s arguments. This is not meant to be a complete reference; the forthcoming Visio 2010 SDK will contain much more complete documentation on these methods.
Returns an array of identifiers (IDs) of shapes that are one degree of separation away from the given shape (i.e. separated by a 1-D connector).
Returns an array of identifiers for the shapes that are glued to a shape. For instance, if the given shape is a 2-D shape that has multiple connectors attached to it, this method would return the IDs of those connectors. If the given shape is a connector, this method would return the IDs of the shapes to which its ends are glued.
Creates a new Shape object on the page, places the new shape relative to the specified existing target shape, and adds a connector from the existing shape to the new shape. Returns the newly created shape. This feature parallels the AutoConnect feature in the Visio user interface.
Splits the specified connector with the specified shape. Returns the new, duplicated connector.
Unglues the specified connector end points and offsets them the specified amount from the shapes they were joined to.
Automatically draws multiple connections in the specified directions between the specified shapes. Returns the number of shapes connected.
Here is a screenshot of a Visio drawing we will be manipulating and traversing:
Using a few of the above listed methods, we’ll add to this flowchart and traverse it. Each step along the way, we’ll show you the corresponding line of C# code along with a screenshot of the change it caused.
Note: In the below code snippets, page refers to the active drawing page, and the Visio namespace is an abbreviation of Microsoft.Office.Interop.Visio. The meanings of most other variables should be apparent from the context.
First, let's split the connector that currently connects "Start Event" to "Task" and insert a Sub-Process shape. We can access that connector using the GluedShapes method. Once we’ve accessed the connector, we use SplitConnector to split it.
Array shapesGluedToStartEvent = startEvent.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesOutgoing1D, "", null); // In this example, the above array has 1 element. Let's get that element. int splittableConnectorID = (int)shapesGluedToStartEvent.GetValue(0); Visio.Shape splittableConnector = page.Shapes.get_ItemFromID(splittableConnectorID); page.SplitConnector(splittableConnector, subprocessMaster);
This yields the following result:
Let's say we want to programmatically access the "Task" shape. If we have a reference to "Start Event", we can access "Task" by traversing across "Sub-Process", using ConnectedShapes.
Array shapesConnectedToByStartEvent = startEvent.ConnectedShapes(Visio.VisConnectedShapesFlags.visConnectedShapesOutgoingNodes, ""); // In this example, the above array has 1 element. Let's get that element. int subProcessID = (int)shapesConnectedToByStartEvent.GetValue(0); Visio.Shape subProcess = page.Shapes.get_ItemFromID(subProcessID);
// Repeating the same action as above to get from "Sub-Process" to "Task". Array shapesConnectedToBySubProcess = subProcess.ConnectedShapes(Visio.VisConnectedShapesFlags.visConnectedShapesOutgoingNodes, ""); int taskID = (int)shapesConnectedToBySubProcess.GetValue(0); Visio.Shape task = page.Shapes.get_ItemFromID(taskID);
Now let's use DropConnected to drop an End Event shape onto the page and have "Task" connect to it. We use the default connector, so the last argument can be null.
Visio.Shape endEvent = page.DropConnected(endEventMaster, task, Visio.VisAutoConnectDir.visAutoConnectDirRight, null);
We hope this walk-through was a helpful illustration of Visio 2010’s new API utilities for working with connected diagrams. This article covers only a small part of the enhancements made to Visio’s API for the 2010 release; more information will come in future posts on this blog, and with the release of the Visio 2010 SDK.
We’re interested to hear what developers think of this API functionality, so please use the Send a Smile feedback tool or leave a comment below.
In Visio 2007, we introduced the Themes feature to make it easy to apply a professionally designed look to a diagram. In Visio 2010, the Themes feature gets a whole new user interface that takes advantage of the Office Fluent UI. The theme choices are displayed in a gallery on the Design tab in the ribbon.
An improvement over Visio 2007 is that you can apply both theme colors and effects with one click on a thumbnail in the main Themes gallery, instead of having to visit two separate task panes. Each thumbnail is a pairing of a color scheme from the Colors gallery and an effect scheme from the Effects gallery.
As in Visio 2007, the color schemes include colors for text, fills, lines, connectors, shadows, and backgrounds, as well as a collection of five accent colors. The effect schemes include the font used in text, as well as formatting for the fills, lines, connectors, and shadows.
If none of the theme pairs in the main gallery are to your liking, you can choose from any of the schemes in the Colors or Effects galleries, which are located next to the main gallery.
As in Visio 2007, you can also click “Create New Theme Colors” or “Create New Theme Effects” at the bottom of the gallery to create your own custom theme.
Themes is one of the features that demonstrate the Live Preview capability of the Office Fluent UI. As you move the cursor over each thumbnail in the gallery, the theme’s formatting is previewed on your diagram. This lets you quickly experiment with various looks without forcing you to commit to the change. If you don’t click on anything, the diagram reverts back to whatever was applied before the preview.
Live Preview helps break the repetitive “Undo” cycle of applying formatting to content, deciding against the formatting change, choosing Undo to return to the original formatting, and then starting the cycle all over again.
Live Preview is available for many other galleries and menus in Visio 2010. Another feature that makes good use of it is the Containers feature discussed in an earlier post. When you move the cursor over the various container designs in the Container gallery on the Insert tab, the container style is previewed on the selected shapes so you can see what it would look like if applied.
If you’re running the Visio 2010 Technical Preview, check out the new Themes user interface and Live Preview and let us know what you think via Send a Smile or a comment on the blog.
Harry Miller and Jonathan Foster in Office Content Publishing recently created a new educational video series called “Clarity," whose aim is to encourage people to learn more about how to use Visio. (Note that these videos feature Visio 2007, rather than the newer Visio 2010 Community Tech Preview we have been discussing on the blog recently.) Here are the first two episodes of “Clarity”:
Thanks Harry and Jonathan for the great videos!
Visio has long had the ability to display, import and export CAD drawings stored in the DWG and DXF file formats. If you are unfamiliar with the ways that Visio can work with CAD drawings, please read through this previous post.
In Visio 2003 the CAD feature set was overhauled to improve performance and reliability plus provide a better mapping of Visio shapes to CAD entities on Export. There were changes in the CAD Display Properties and Conversion dialogs as well. Unfortunately there were a number of serious bugs that impacted the functionality of the feature set. A few items have been fixed in Visio 2003 service packs, but many more were addressed in Visio 2007.
This post describes the problems in Visio 2003 that were corrected in Visio 2007. The next post will discuss the remaining issues surrounding Visio's CAD integration.
Insert CAD Drawing
There are two ways to display a CAD drawing in a Visio document. If you go to File > Open, you can point directly at the DWG or DXF file and open it. Visio creates a new blank drawing, chooses a page scale that will fit the CAD drawing to the Visio page and adds the CAD drawing. Another method is to start from an existing diagram and go to Insert > CAD Drawing. Visio shows the CAD Drawing Properties dialog and allows you to specify the scale you want to use. Unfortunately, there are several issues going this route in Visio 2003:
· Visio defaults to a custom scale that fits the CAD object to the page, but this scale does not match the scale of the Visio page. If you choose this default, the CAD object will be scaled incorrectly with respect to everything else in the diagram. When inserting into an existing diagram you should always choose the current page scale. The custom scale default is really only useful when you want to use the CAD drawing as an unscaled image in your diagram.
· Since CAD drawings don't explicitly define what units of measure are used, you must specify the CAD drawing units in the dialog to properly scale the CAD object. This can be confusing, and in Visio 2003 the setting doesn't work. The value is ignored, resulting in improper scaling for CAD objects drawn in Metric coordinates.
· For those who bravely tried to get the scale settings configured properly, there is one more problem: The preview pane did not update as you made changes to the settings. Thus the visual feedback about what you would get was also wrong.
These issues combined to make Insert > CAD Drawing very challenging in Visio 2003. Settings either didn't work or were configured improperly by default. This created unnecessary confusion and frustration for customers. Visio 2007 corrects these problems, although it is still the responsibility of the user to set the CAD drawing units properly to end up with the right scale.
A note of caution for Visio 2007: The CAD Drawing Properties dialog does not remember settings very well. Once you close the dialog and reopen it, you will have to reset the Pre-defined scale to Page Scale again. Also do not manually resize the CAD object using the green shape handles since this just distorts the scale.
Export CAD Drawing
Visio drawings are exported to CAD files using the File > Save As > DWG / DXF command. If there is no existing CAD object in the drawing, Visio converts the Visio shapes to entities correctly. If there is a CAD object in the drawing, Visio 2003 fails to use the proper scale to ensure that the converted Visio shapes match up with the existing CAD object's entities. It also fails to position the converted shapes relative to the existing CAD entities. Additionally any cropping or rotation of the CAD object is ignored in the exported file.
Visio 2007 corrects most of the scaling and positioning issues. There are a few cases with dimensions that still are troublesome. Visio 2007 does not support cropping or CAD object rotation on export.
Many of the fixes in Visio 2007 can be credited to a group of customers that are passionate about Visio and its use with CAD drawings. At the Visio Conference in 2006 the product team showcased the upcoming Visio 2007 version with its emphasis on data connectivity. However, a number of partners and customers voiced concerns about the problems with CAD in Visio 2003. In an ad-hoc meeting, we sat down with all interested parties to understand the issues and hear firsthand how important the feature is for these customers.
Following the conference, the Visio team did an extensive review of the CAD feature set to uncover the bugs that were causing the most customer pain. These issues were corrected in Visio 2007 and released as part of the Visio 2007 betas to have partners and customers verify the fixes. The result is a significantly better experience in Visio 2007 over Visio 2003. We weren't able to address all concerns though. Next time we will look at the current state of CAD integration in Visio.
This situation has come up frequently enough in the newsgroups that the solution should be widely circulated:
When Visio crashes, it will often restart and recover the document you were working on. This is generally quite helpful, but sometimes Visio doesn't know when to stop. Sometimes Visio will continue to recover that document and show it to you every time you launch Visio. This can be frustrating, but there is a solution.
Close Visio. Then look in the folder "%userprofile%\Local Settings\Application Data\Microsoft\Visio" using Windows Explorer. Some of the folders in the path are hidden, but you can usually paste the path found between the quotation marks directly into the address bar and press Enter. Now find the file autorecover.ini and delete it. The recovered documents should stop reappearing when Visio is launched.
A few updates…
We recently reported the availability of Service Pack 2 (SP2) for Visio 2007. We received a few questions about how to use the XMI export feature in UML diagrams. The behavior in SP2 is exactly the same as in previous versions. Integrating it into the UML solution and retiring the separate download should make life easier for everyone, including us! The following VBA example demonstrates the interface:
Application.Addons("UML Background Add-on").Run("/CMD=400 /XMIFILE=""C:\path\file.xmi""")
Application.Addons("UML Background Add-on").Run("/CMD=400 /XMIFILE=""C:\path\file.xmi""")
The XMI export acts on the active document, so be sure to set that if your application session has multiple documents open. If you’re not familiar with VBA, the extra quotation marks in the XMIFILE argument are used to escape the quote character – the value passed in must be wrapped in quotes.
Visio Conference 2008 Videos
Last year, we posted links to videos from the Visio Conference 2008, where we shared a few glimpses into the next version of Visio. The links have changed – replace the visioconference2008 part of the URL with visio2008 to get to the video site. Note that some of the videos are quite large and can take a bit to download.
Our previous post introduced the improvements we made to the ShapeSheet window for shape developers. In this post, we will continue with ShapeSheet development and dig deeper to examine the new ShapeSheet cells and functions available in Visio 2010.
A number of new cells were added to both the PageSheet and the ShapeSheet to support new features in Visio 2010 and to expand the possibilities for shape development. We will examine each one in turn.
New PageSheet cells in Visio 2010:
New ShapeSheet cells in Visio 2010:
Recall that you can view the PageSheet for a page or the ShapeSheet for a shape using the Developer tab.
This cell takes a TRUE or FALSE value and determines whether the Auto Align and Space features attempt to avoid placing shapes on page breaks. This corresponds to the Space Shapes > Avoid Page Breaks setting under the Position button on the Home tab.
This cell corresponds to the Page Auto Size feature, which is found on the Design tab. It takes three values. Values 1 and 2 correspond to Auto Size on and off, respectively.
Zero is “undefined,” which is the default state for a document created in Visio 2007 or prior, since this cell doesn’t exist in those versions. This value allows Visio to determine whether Auto Size is enabled for the user. It makes a best guess by looking at the page size relative to common paper sizes and deciding whether the page size appears to have been customized, or left at a default size. If the page is at a default size, Visio enables Auto Size so users can benefit from it; if customized, Visio assumes that a specific page size was chosen for a reason and disables Auto Size. In any case, the user can change the setting by toggling the Auto Size button on the Design tab.
This cell defines “bands” of Z-order and is used to determine the default global Z-order position for a shape when it is added to the page. Visio uses this to place containers behind the shapes they contain, regardless of what order they are added to the page. Shapes with a higher DisplayLevel value are displayed on top of shapes with a lower value. Each value of DisplayLevel, which ranges from –32767 to +32767, defines a band.
As an example, consider a diagram with three masters, each with the DisplayLevel value shown. Regardless of what order shapes with DisplayLevel 10, 20 or 30 are dropped, the 10s will always be behind the 20s and 30s, and so forth. The blue shape shown below is at the bottom of the Z-order and was dropped before the other two shapes at DisplayLevel 10. DisplayLevel bands do not interfere with the Z-order commands on the Home tab – Bring Forward / Send Backward and Bring to Front / Send to Back. Using Bring to Front or Send to Back will initially only move the shape to the front or back of the Z-order for its band. A subsequent use will move it to the global front or back of the Z-order.
Notice the special –32768 value, which means that the shape has been pulled out of its band. Visio stores the previous band in a formula in the DisplayLevel cell so it can be restored. Note that changing the value of the DisplayLevel cell does not change the shape’s Z-order, but the band will be taken into account the next time Visio needs to manipulate the shape’s Z-order.
This cell allows Actions, or custom right-click menu items, to be nested. Any menu item whose FlyoutChild value is TRUE will appear in a flyout menu of the first row above it whose FlyoutChild is FALSE. This allows one level of nesting.
The Actions section below will show the following custom items on the right-click menu.
If the value of FlyoutChild for B and C is TRUE, then those items appears in a flyout menu under A.
This cell allows a shape developer to control how click and drag inside a given geometry section of a shape works. Typically, this picks up and moves a shape. By setting this cell to TRUE, you can create a non-clickable (or non-selectable) filled geometry area that prevents picking up and moving the shape. The container shapes new to Visio 2010 use this cell to allow click and drag to select shapes in the container rather than move the container.
This cell stores the relationships among containers, lists, callouts and shapes. It uses a series of DEPENDSON functions, one for each different type of relationship the object has. Note that changes to this cell will not trigger actual relationship changes; Visio only uses this as a means to store the relationship information. This cell is not intended to be modified by users or shape developers.
The types of relationships are listed below.
A shape named Process that is a member of a container named Container 1 would have a Relationships cell formula of this form: =SUM(DEPENDSON(4,Container 1!SheetRef())). The container’s Relationship cell would look like: =SUM(DEPENDSON(1,Process!SheetRef())).
If the Process shape were pinned to the left edge of the container, its Relationships cell would be: =SUM(DEPENDSON(7,Container 1!SheetRef()),DEPENDSON(4,Container 1!SheetRef())). The container’s cell would remain as listed.
A shape that is a member of two containers would look like: =SUM(DEPENDSON(7),DEPENDSON(4,Container 1!SheetRef(),Container 2!SheetRef())), and so forth.
We also added ShapeSheet functions that enable new developer scenarios, particularly for integrating with new Visio 2010 features.
A number of functions are designed to enable interaction with the new container and list features.
The following functions return a Sheet reference, or a reference to the shape. (Such functions exist in Visio 2007 and previous versions, such as NAME and ID.) This return value can then be used to call another function. For example, CALLOUTTARGETREF()!HASCATEGORY(“Category”).
The following functions return the number of associated shapes.
The following functions
In the example below, the rectangular process shape belongs to a container. It shows the total number of shapes in the container using a text field with the formula CONTAINERSHEETREF(1)!CONTAINERMEMBERCOUNT().
Another set of functions enable detailed interaction with individual geometry paths among different shapes. Each of these functions requires a specific Geometry section to be specified – e.g., PATHSEGMENT(Sheet.1!Geometry2.Path, 0.4). Points on a path are given as a percentage of the distance along the path.
These functions open up a broad set of interesting shape interactions that we’re sure shape and solution developers will love. We will write a more detailed post focusing on these functions soon.
The last group of functions are various helpers that either support the new functions or fill in gaps. The first four operate on a Sheet reference.
Index enumeration for BOUNDINGBOXDIST:
Index enumeration for BOUNDINGBOXRECT:
We also modified the following functions that existed in Visio 2007 and prior versions. You can continue to use these as you have in the past – e.g., NAME() – or you can use them with a Sheet reference, such as Sheet.4!NAME() or CONTAINERSHEETREF(1)!NAME().
We hope you will find these useful in opening new opportunities for shapes and making your shape development tasks easier. As always, we’re interested in your feedback and suggestions via a comment on the blog or using Send a Smile.
Diagram Validation is a new Visio 2010 feature that provides a way for users to check their diagrams for common errors and for companies to ensure that employees are following certain diagramming standards. The basics of diagram validation and creating custom validation rules have been previously discussed on this blog. In this post, we focus on the details of using the validation API to create validation rules, trigger validation, and manage validation issues.
Visio provides an extensive Diagram Validation API that allows companies to develop custom validation rules based on their own needs. For example, you can build rules to check that a network diagram includes mandatory components, or that a process diagram complies with company policies. The ability to verify the correctness of a diagram and raise issues to end-users is also crucial for solutions that need a certain diagram structure to work. For example, Visio uses validation for Microsoft SharePoint Workflow diagrams to ensure that SharePoint workflows are structured correctly before exporting them. As a developer, you can leverage Diagram Validation to support diagram verification for the diagram types and the issues that are important to you.
The key objects, methods and properties for validation are shown below.
The validation API is based on three main concepts: rule sets, rules and issues. A validation rule, or simply a rule, represents one type of error that can occur in your diagram. Each rule has some underlying business logic which determines when the rule has been broken. An issue is one case in your diagram where the validation rule has been broken. Depending on your diagram, there may be multiple issues associated with the same rule. For example, if the rule requires that all shapes be labeled, then validation will display an issue for each shape without a label. Rule sets are logical grouping of rules, such as the BPMN and flowchart rule sets.
Rules sets, rules and issues each have corresponding API objects, namely ValidationRuleSet, ValidationRule and ValidationIssue. Below we explain the key properties for each of these objects.
Every rule set has a unique NameU property representing the universal name of the rule set. You should also specify a Description for each rule set. Other properties are set by default, and only need to be modified if a different behavior is desired. The key properties of the ValidationRuleSet object are shown below.
Every rule has a unique NameU property representing the universal name of the rule. You should also specify a Category and Description for each rule set, as these properties are used in the UI. The Category should inform the user about the type of issue, and may be used to identify the rule set that triggered the issue. The Description should be explicit enough to explain the issue so that a user can address it.
The blog post on creating custom validation rules describes two approaches for creating custom validation rules: you can store validation logic in a Visio template, or you can express validation logic in code and deploy this logic as part of a Visio solution. If you decide to store validation logic in a Visio template, the FilterExpression, TestExpression and TargetType are the fundamental properties for detecting and reporting issues during validation. If you decide to write validation logic in code, these fields should be left blank. The FilterExpression, TargetType and TestExpression properties are described in more detail in the section titled Defining ValidationRule.FilterExpression and ValidationRule.TestExpression.
The key properties of the ValidationRule object are shown below.
Every issue has an associated Rule which specifies the description and category that is displayed in Issues window. When a user clicks on an issue in the Issues window, Visio will navigate to the page of the issue (if the issue targets a page or shape) and will select the target shape (if the issue targets a shape).The TargetPage, TargetPageID and TargetShape properties are used determine the page to display and the shape to select. The key properties of the ValidationIssue object are shown below.
Validation methods can be divided into different groups. We will start by describing the first group of methods, which allows developers to add validation rule sets and rules to a document. Typically, these methods are executed once to populate a template or diagram with validation rules. In fact, the rules can be pre-populated in a template, and then the template can be deployed to end-users without any solution code.
For each of the following API methods, we give a brief description on what the method does, along with an explanation of the method’s arguments.
Adds a new, empty ValidationRuleSet object to the ValidationRuleSets collection of the document.
Adds a new, empty ValidationRule object to the ValidationRules collection of the document.
The following VBA code adds a rule set and a rule that targets a shape to the active document.
When you set the TargetType, FilterExpression and TestExpression of a rule, Visio will manage issues associated with the rule for you. For very complex validation rules, it will be easier to omit these properties and write the validation logic in solution code. For this approach, the solution should listen for the appropriate RuleSetValidated event and use its own logic to determine the list of issues to add to the document.
We give a brief description of the two key methods that you will use to manage issues, along with an explanation of the method’s arguments.
Creates a new validation issue that is based on the validation rule, and adds it to the document.
Deletes the ValidationIssue object from the document.
The following VBA code adds an issue to an existing rule. It assumes that vsoValidationRule is a valid Visio.ValidationRule object, vsoShape is a valid Visio.Shape object and vsoPage is a valid Visio.Page object.
If you have a custom solution that needs a certain diagram structure to function properly, you can use the Validation.Validate method to validate the diagram and raise issues to end-users. This method validates a particular validation rule set (if specified) and updates the Validation. LastValidatedDate property. It will also trigger the RuleSetValidated event. It is recommended that you omit the rule set parameter, and validate against all active rule sets. This gives end-users a clear and consistent view of the issues currently in their document.
Validates the specified validation rule set.
The following VBA code validates all rule sets in the document and launches the Issues window.
When you validate a diagram by calling the Validation.Validate method or by clicking Check Diagram on the Process tab, Visio will automatically use any validation logic stored in the document to detect errors. This validation logic is expressed in the ValidationRule.TargetType, ValidationRule.FilterExpression and ValidationRule.TestExpression properties. The FilterExpression and TestExpression should be written as Boolean expressions that can be evaluated on every object of type TargetType. During validation of a rule, for every object of type TargetType, Visio uses the FilterExpression to determine whether the object must satisfy the validation rule. If the filter expression evaluates to True, Visio uses the TestExpression to determine whether to generate an issue for the object. If the filter expression evaluates to False, Visio does not apply the validation rule to the object.
The syntax for the FilterExpression and TestExpression properties are the same as that of a ShapeSheet expression (you can get more details here and here if you're unfamiliar with the ShapeSheet). For example, since NOT(IS1D()) is a valid Boolean expression for the ShapeSheet of a shape, "NOT(Is1D())" is a valid FilterExpression or TestExpression for a validation rule with TargetType = Visio.VisRuleTargets.visRuleTargetShape. In addition to the standard ShapeSheet functions, the following validation functions can be used in a FilterExpression or TestExpression.
The validation expression functions ConnectedShapes and GluedShapes correspond to connectivity API functions with the same names. Similarly, the possible values of the Direction input parameter for ConnectedShapes and GluedShapes correspond to the VisConnectedShapesFlags and VisGluedShapesFlags enumerations, respectively.
We hope that this overview of the validation API provides the necessary details to start writing your own validation rules. We’re interested to hear what developers think of this API functionality, so please use the Send a Smile feedback tool or leave a comment below.
Many of you are familiar with the work we did in Visio 2007 to make it easier to surface data that exists in your diagram in a visual form. Data graphics allow you to add refreshable data visualizations to the shapes in your diagram. See our previous posts Microsoft Office Visio 2007 Released and Customizing Data Graphics for more information.
One thing users have asked us for is a way to describe the data graphics used in the diagram – a legend. Visio 2010 adds the ability to insert a legend that documents the data bars, icon sets and color by values in data graphics applied to shapes on the page. You can do this using the Insert Legend button on the Data tab.
Visio creates the legend at the upper right corner of the page. The legend contains a separate section for each data field referenced in the data graphics’ definitions. The descriptions for each legend item are obtained from the data graphics.
The legend is customizable, so you can add, remove and rename sections and shapes to make the legend look just right for your particular diagram. Legends also pick up the theme applied to the page, or they can be manually formatted.
The legend is made up of a number of shapes and uses containers to keep the different parts of the legend organized. The top-most shape is a list, a special type of container that arranges its members in a regular, linear pattern. The members of that list are containers, each of which represents a data field from the data graphics. Inside each container is another list, this one invisible, which keeps the individual legend items neatly arranged.
You can select a legend item and use the arrow keys on your keyboard to reorder them, or you can drag them around the list. You can also drag them out, delete them or drag your own shapes in. The same can be done with the containers that correspond to each data field. If you click the blue insert arrow on the outer list, Visio adds an empty container for your own use. While this will not have the inner list, you are free to add any shapes you wish.
To preserve the customizations you might make to the legend, Visio does not update it as you edit your data graphics or change which data graphics are applied to shapes on the page. Simply insert a new legend once you are done making changes. Delete the existing one or move it out of the way if you need to bring anything over.
Finally, for the developers out there, you can drop a legend using Page.DropLegend in the Visio API and specify custom outer list and field container masters.
We’re happy to be able to close this gap in data visualization and are interested in your feedback via Send a Smile or a comment here on the blog.
We frequently speak with Visio users whose organizations need to manage collections of process diagrams. Many of these users are employing basic methods such as storing these documents on network file shares. However, these methods leave much to be desired. For instance, end users frequently ask us questions like:
Additionally, the administrators and managers who supervise these document repositories often ask us questions like:
To address the above pain points, we have created the Visio Process Repository, a new SharePoint site template that is available out of the box with SharePoint 2010. It leverages SharePoint’s collaboration features -- including check-in and check-out, versioning, and workflow -- and integrates with several of Visio’s new process management features. The result is that in just a few clicks, a SharePoint administrator can create a Visio Process Repository that is pre-configured for easy storage and management of Visio process diagrams.
Here is the home page of an example Process Repository:
As shown in the sidebar above, a Repository site contains a library for documentation, a task list, and a discussion board. But most important is the “Process Diagrams” document library, which is designed to store processes. This document library comes pre-populated with several templates that can be used to create new process diagrams. (However, you can store other diagram types in a Repository; these particular templates are available simply for convenience.)
Let’s say you use the Cross-Functional Flowchart template to create the following diagram in Visio:
Once you’re finished and (optionally) have checked your diagram for errors using the Validation feature, you can save your document back to the Repository through the “Save to SharePoint” billboard in the Backstage:
Then, when you navigate back to your Repository, your process diagram will be listed in the Process Diagrams document library as shown in the image below. Note the two special columns marked by the red rectangles:
Since the Process Repository is built on top of SharePoint 2010, you can also take advantage of other SharePoint features. For instance, you can configure workflows, set up automatic email notifications for when documents change, and view revision history for a given document. Also, with Visio Services users can view the processes in their browser in a single click, even if they do not have Visio installed on their computers. For instance, this is what the above cross-functional flowchart looks like when viewed in a browser:
We hope this quick tour of the Visio Process Repository feature gives you ideas for how you can use a Process Repository (as well as related Visio 2010 features like Validation and Visio Services) in your organization. Please let us know what you think, either by commenting on the blog or via Send a Smile.