## Polyline Shape Maker

Sometimes your Visio SmartShapes can be like beauty pageant contestants: they just need to look good, but don’t need a lot of intelligence. The creators of Visio realized this (after five versions) and gave us a way to streamline lots of “dumb” vector data. The ShapeSheet function: **POLYLINE** and the geomettry row: **PolyLineTo **will help you get the job done.

#### The Problem: Too Many ShapeSheet Rows

We’ll start with a shape that has lots and lots of geometry rows. At right, you see an outline of Washington State. This is where your Starbucks Coffee, your Amazon Books, your Boeing Airplanes, your Microsoft Software, and, curiously your Apples come from!

The Washington shape has **4** geometry sections and a whopping **279** total geometry rows! That’s a lot of ShapeSheet cells. And in all of those cells there are exactly *zero smart formulas*. The formulas are simply proportions of the Width and Height of the shape. Nothing smart about them at all.

When you open the ShapeSheet, you immediately get a headache because of all the data you have to scroll through. Wouldn’t it be nice if we could somehow simplify this mess? Well there are a couple of solutions…

#### First Stop: Metafiles

One way to make this shape more efficient is to convert it to a meta file.You can do this by following these steps:

- Copy the shape with Ctrl + C
- Choose Edit > Paste Special
- Select:
**Picture**or**Picture (Enhanced Metafile)**from the list in the dialog box.

The ShapeSheet behind your meta file shape will be vastly simplified, but it will also be a lot less flexible. You won’t be able to give the shape any line or fill formatting. The shape truly becomes a foreign object.

#### Enter PolyLineTo and PolyLine( )

If you examine the image above, you’ll see two oddities: a **PolyLineTo** row, and a **POLYLINE** function in the A column.

The POLYLINE ShapeSheet function essentially allows us to enter a string of x, y coordinates that define every vertex of a shape. That list can be very, very long, and will have to be to describe the geometries in our Washington shape! In the image above, the Geometry describes a rectangle, drawn clock-wise from the lower-left corner.

The POLYLINE function only makes sense to Visio if it is inserted into the A-column of a PolyLineTo geometry cell. Most geometry cells that you see are MoveTo or LineTo cells. The PolyLineTo row is simply another flavor of geometry-row.

It’s easy to convert a LineTo or other Geometry row to a PolyLineTo row. All you have to do is right-click a cell in the row, and choose **Change Row Type** from the menu. A dialog will pop-up, and you can choose PolyLineTo from the list.

The most efficient setup is to have a geometry section with two rows: the first being a MoveTo row, the second being a PolyLineTo row–just as the image above shows.

So let’s take a look at our rectangle, with the various Geometry-row bits written next to the respective vertices:

A couple of notes:

- Geometry1 and Geometry2 represent the same point. This is because the shape needs to close, so that it can have a fill. Closed geometry sections always “return home” at there last row.
- The
*first*two arguments in the POLYLINE function describe the x- and y-types for the points. 0 indicates the points are proportions of width and height, respectively. 1 indicates that the points are local coordinates within the shape. If the points have no units, then they will be understood as Visio’s internal units, which are always inches. In our shape above, they’re both 0, so the following x,y pairs represent “width-times-a-proportion” and “height-times-a-proportion”.

#### What Do We Gain?

Despite the HUGE reduction in ShapeSheet rows, the file size gains are, rather modest–somewhere on the order of 10%. Visio probably does a good job of compressing all those dumb geometry rows in the non-polylin-ed shapes. Interestingly, the meta files can be quite a bit smaller in file size, but again, this is at the expense of being able to format the shape.

However, the actual performance of the shape is better with the polyline info. You’ll notice that the “live dynamics” of the shape are more fluid, and quicker to respond while you are resizing it.

Another interesting stuff is that your hard-earned POLYLINE stuff survives the Combine boolean operation. Fragment and Union, however tend to take you back to lots and lots of individual geometry rows.

#### How Do I Convert a Huge Shape to Polylines?

*“So, Visio Guy, now that we know how to reduce complicated shapes to lists of points, how do we go about converting our shapes without tediously entering each point by hand?”*

Glad you asked! Just download the custom Visio diagram that I’ve created. It contains VBA code that will automatically “polyline-ify” every geometry section in your selected shape. And don’t worry about messing up your shapes, the code creates a copy of the selected shape before it does any modifications!

#### Geek Notes on POLYLINE()

I’ve noticed that the POLYLINE function seems to do fairly sophisticated parsing. You can mix units and formulas in your list of points! I modified the formula from our rectangle above to:

POLYLINE( 0, 1, 0, Height*2, 1, 1, 1, 1mm )

Notice the mixing of formulas, constants, and different units! It functioned perfectly fine. So here, we have all the x-points being proportional to the width, all the y-points being absolute in inches, except the last point, which is 1mm, and the first point which is twice the height. Strange, but it works!

What I can’t say for sure is whether or not Microsoft recommends mixing formulas and units in the POLYLINE function.

#### Polyline Resources

- POLYLINE Function on MSDN, in the Visio 2003 SDK DocumentationÂ
- PolyLineTo Geometry Row on MSDN, in the Visio 2003 SDK DocumentationÂ

Interesting article. Is there any way this works on groups of shapes? Can I convert a bunch of grouped shapes into a single polyline?

Hey Adam,

The freebee code in this document just optimizes singe geometry sections in a single shape – ie: it “polylines” each geometry section in the shape. It doesn’t combine sections in any way.

If you used it on a group (probably with some code mods first to walk the group!), the group would have the same number of shapes, and the same number of geometry sections, but the total row count in the geometry sections can be drastically reduced.

Last caveat, it only works well for geometry that consists of straight line segments. This thing will seriously munge a shape with lots of curved segments–if those curves are actually noticeable.

One note: I think metafiles turn curves into straight-line segments. So imported graphics might have curves that are composed of lots of small line segments anyway. I’m not sure how well Visio imports curved line segments from other format in the first place.

[…] I used the Polyline Shape Maker to reduce all the geometry sections to single rows, with big, long POLYLINE functions. Zap! Pow! […]

hey adam,

thanks for the polyline maker it is really useful

But i need ur help , when i use shapes in svgz format, the shapes line gets thicker and it affects the shape please give some solution on it.

so looking forward for your help.

Well, I’m not Adam, but perhaps you can edit the lineweight attribute in the SVG file (whatever the attribute is called)?

Is there a way to call the POLYLINE() function with a variable list of coordinates, e.g. POLYLINE(1,1,Scratch.A1), where the ShapeSheet cell Scratch.A1 contains the actual list of coordinates?

Hi Guy,

I don’t think that will work. You could make a variable list of coordinates using concatenation (ie: 3.0 & “,” & 4.0 & “,” & 5.0 & “,” & 6.0) but the ShapeSheet will probably just understand as a single string.

You could have several cells with the POLYLINE function, then refer to them based on conditions. I just tried this and it worked fine:

‘// User.Key is the flag that chooses between polyline definitions:

User.Key = 0 (or 1)

User.P_Rect = POLYLINE(0,0,0,1,1,1,1,0)

User.P_Triangle = POLYLINE(0,0,0,1,1,1)

User.P = IF(User.Key=0,User.P_Rect,User.P_Triangle)

‘// The actual ‘A’ cell for the PolyLineTo row:

Geometry1.A2 = User.P