" /> Visio Guy » Making Shapes More Efficient: Using Fewer Shapes & Groups
Home » Development, ShapeSheet

Making Shapes More Efficient: Using Fewer Shapes & Groups

Submitted by on March 28, 2008 – 6:31 am | | 28117 views 4 Comments

Read Full ArticleYou may have read our recent post on Cisco IP Telephone Shapes, and perhaps downloaded the shapes. While give-aways and freebies are nice, we at Visio Guy like to go further. We like look behind-the-scenes and talk about Visio development-related issues in order to give our readers a deeper understanding.

Before we released the Cisco IP Telephone shapes, we performed a number of tweaks to make them more efficient and better behaved. This article discusses a few of those operations–the whys and hows of making your shapes more efficient, and some tricks for ensuring proper resize behavior!

The Cisco Button Shapes

The shapes we’re talking about provide a nice way of documenting customizations to the Cisco IP Telephone software. This very nicely-drawn set of shapes were submitted by a Visio Guy reader, and look like this:

Cisco IP Telephone Shapes - Shape Sample

click to view larger image

A Developer’s Check-list

Not being content to leave well-enough alone, we examined the shapes, and ran them through a common release checklist to get them ready for distribution to our readers. This check-list aimed to acheive the following:

  1. Eliminate unnecessary grouping (ie: nested groups)
  2. Combine shapes with like-formatting into single (sub) shapes
  3. Ensure proper resize behavior

Items 1 and 2 had to do with the file-size efficiency, and item 3 had to do with maintaining graphical integrity when the shapes are resized. Today we’ll discuss items 1 and 2. Tomorrow we’ll cover item 3.

File Size

These shapes are well-built and precisely drawn, but when considering file-size, there exists a conflict between what’s good for the developer and what’s good for the end-user. This conflict is between ease-of-modification and shape-efficiency.

By using lots of groups and keeping shapes separate, it is easier for the designer to update and modify the shapes. But more groups and more shapes means more ShapeSheets, which means larger file sizes.

Two methods are used to reduce file size: getting rid of groups, and combining like-formatted shapes.

Flattening Group Structure

Getting rid of groups is a simple matter. Just select a shape and open the group-editing window and ungroup everything voraciously! More precisely, you can follow these steps:

  1. Open the group window via Edit > Open Group.
    Note: if the shape is an instance of a master, then the menu item will show Open Master-name.
  2. Select all shapes, (shortcut: Ctrl + A)
  3. Ungroup a bunch of times by repeatedly pressing Ctrl + Shift + U.
    While this isn’t really precise, but you can ungroup six or eight times really quickly with the keyboard shortcut. Hopefully you won’t have more levels of grouping than that!

You can detect shapes that have nested groups in a number of ways. One way is to look at the Drawing Explorer window, which you can shoe via the menu items: View > Drawing Explorer Window. If a shape has sub-shape-nodes that can be expanded, then the shape has extra levels of nesting that might not be necessary. Here’s an example of a shape with several levels of group-nesting:

Making Shapes More Efficient - Nested Groups

After ungrouping all of the sub-shapes, Sheet.96 from above looks like this:

Making Shapes More Efficient - Flat Groups

Now that is much simpler. You can see why we call it “flattening the group structure”!

Of course, there were too many shapes to analyze by hand. So I wrote some VBA code to detect shapes with sub-groups. The code draws a red rectangle around any shape that contains sub-groups. You can easily convert it to VB.NET, if that is the environment you are working with:

[code lang=”vb”]
Sub MarkShapesWithSubGroups()

Dim shp As Visio.Shape

For Each shp In ActivePage.Shapes
If m_shapeHasSubGroups(shp) Then
Call m_markShape(shp)
End If

End Sub

Private Function m_shapeHasSubGroups(ByRef shp As Visio.Shape) As Boolean

Dim s As Visio.Shape
For Each s In shp.Shapes

‘// Check the sub-shape’s shape count. Greater than 0
‘// means that it is a group:
If s.Shapes.Count > 0 Then
m_shapeHasSubGroups = True
Exit Function
End If


m_shapeHasSubGroups = False

End Function

Private Sub m_markShape(ByVal shp As Visio.Shape)

‘// Draws a ‘highlight’ rectangle around a Visio shape:      Dim l As Double, t As Double, r As Double, b As Double

Dim rect As Visio.Shape
Dim flags As Integer

‘// Get the bounds of shp, so we know how big to draw
‘// the rectangle:

flags = Visio.VisBoundingBoxArgs.visBBoxUprightWH

Call shp.BoundingBox(flags, l, b, r, t)
rect = shp.ContainingPage.DrawRectangle(l, b, r, t)

‘// Give the shape no fill and a red outline:
rect.Cells("Geometry1.NoFill").ResultIU = 1
rect.Cells("LineColor").Formula = "RGB(255,0,0)"

End Sub

We could write code to automatically ungroup all sub-groups, but there are cases where sub-groups are legitimate.

For instance, sometimes sub-elements need to be rotated and translated. It’s far easier to position such shapes by placing them in a sub-group that can easily be rotated and translated, all at once. Without sub-groups, you’d have to enter trigonometric formulas all over the place to get the sub-shapes properly positions.

Combining Shapes

Now that we’ve flattened out the groups, it’s time to combine shapes. You can combine shapes using Visio’s Boolean Operations. Combining shapes creates a single shape, with a single ShapeSheet, but with multiple geometry sections. You can do a quick test to se what we’re talking about:

  1. Draw two rectangles
  2. Select them both
  3. Choose: Shape > Operations > Combine
    You now have one single shape
  4. Choose: Window > Show ShapeSheet
    Note that there are two Geometry sections with five rows each.

Combining shapes reduced the file size, because only one ShapeSheet (and all of its overhead) is required for multiple geometries. But all the shapes need to have the same line and fill formatting for this to make sense, since one shape can only have one set of formatting attributes.

In the case of our Cisco shapes, the fill formatting is almost always white, but some shapes have thicker lines than others. We can look at the Navigation button and compare the sub-shapes before and after combination:

Making Shapes More Efficient - SubShapes

We can see that the number of sub-shapes is dramatically reduced, AND we uncovered an extra square that wasn’t needed!

Before & After Statistics

Now that we’ve flattened out the sub-grouping and combined sub-shapes, let’s have a look at the sub-shape count of our Cisco shapes:

Making Shapes More Efficient - Shape Count

File-size-wise, after all the ungrouping and combining, the file was only reduced by 10 KB. (172 KB to 162 KB). So the shapes were pretty clean from the start, and you’ve got to wonder if I used my time wisely.

But I’ve seen other situations where shapes were very heavy with nested groups and separate shapes. Addressing items #1 and #2 on the checklist resulted in significantly smaller file sizes!

Also, in a practical application, these shapes will likely be converted to masters and instanced many times. For every copy of a shape on a page, we’ll have space savings. If several hundred shapes are on a page, the file-size savings might be more significant than we see here.

Combining Isn’t Always Appropriate

We’ve hinted that combining isn’t always feasible. It is instructive to point out reasons NOT to combine shapes:

  1. Different line formatting
  2. Different fill formatting
  3. Each shape has its own text
  4. Z-order requirements

The Z-order problem can be seen by looking at the green headphones. While the headphone elements are all black, they are built in such a way that combination isn’t possible for all elements. Each earpiece is made of two shapes: a green piece that obscures the under-lying headband, and a black piece that lays on top:

Making Shapes More Efficient - Z-Order

The shape on the right shows the structure by changing the colors: the blue earpiece elements lay on top of the black headband. The red bits are then on top of the blue. In each case, the left and right elements were combined together, but the whole mess couldn’t be because of the coloring and the z-ordering.

Source Shapes?

When making shapes smaller and faster, we run into a developer-versus-user quandry. In one state, the shapes are easier for the developer to create, modify and update. But that state is usually less efficient for the end-user.

The ideal situation would be to have source shapes that can easily be modified, then pass them through some sort of automation treatment that simplifies the shapes for release. We’ve seen some sample code that points us in this direction.

Unfortunately, some of the operations require human judgement (or way too much programming). Z-order issues are among these.

Resize Behavior

In another article, , we’ll continue with the Cisco series by examining what happens when the shapes get resized, and how we can improve that behavior. You can read about it here: Smart LineWeight: Bigger Shape, Thicker Lines.


Leave a comment!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" extra="">

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.