When you insert an image into Visio, the default behaviour is to add it to a containing shape with the full width and height of the image being visible. If you delve into the ShapeSheet, however, you can expand the image outside of containing shape’s bounds, with the extended area being hidden from view. Visio actually makes use of this in some of its Data Graphics functionality by having an icon strip and moving this left and right depending on which part of the image is required.
Of course you could extend this image shifting to two dimensions and then use a grid based approach in order to address each cell and that’s what I’m going to cover in this post…
I was hunting around for a series of example images to use and in the end created these weather icons in Visio, which I exported as a png file. The point of this post is not how to create the icons, but how to use an image as a grid - I admit that the weather symbols would be best produced as vector based Visio geometry. That minor health warning aside and we’ll get started.
The first step is to think about a logical layout for your images. In my weather example I’ve chosen to show the Sun on one dimension (rows) and Cloud & Rain on the other (columns). I’ve also opted to number the rows from the bottom up rather than the more standard top to bottom. The reason for this is that Visio’s coordinate system is based on a bottom left point of origin (0,0) and organising your rows in same way will make life easier later on when you begin to manipulate the image’s position within the shape. So here’s a picture of the weather image layout:
As you can see this corresponds to ‘No sun’ and ‘Sun’ for the two rows and varying levels of cloud and rain for the columns.
Creating the image
You can use any image editor from Photoshop to Paint.net to create your image, but remember that each image item must be the same size and aspect ratio. The overall image size is not important within reason, but the width to height ratio is. If you need your resulting Visio shape to have a specific aspect ratio then you need to ensure that your image components (ie each cell) start off with that same ratio.
Creating the image grid shape
Once you’ve got your image ready, click Insert / Picture from the ribbon or drag and drop the image onto the page. Right-click on the resulting shape and select Show ShapeSheet to see the properties for the shape. (Note – if you’re not familiar with the ShapeSheet or can’t see the Show ShapeSheet option in the context menu then you might want to have a quick read through to the first section of this Just for starters post.)
Now the ShapeSheet is open you can follow these steps:
- Change the Width and Height cells of the Shape Transform section to whatever size you want, but remember that they must match the individual image items’ aspect ratio. In my case the image items are square and so I’ve entered 25mm for both.
Right-click on the ShapeSheet, select Insert Section… and check the User-defined cells and Shape data options from the resulting dialog.
- Rename the first Shape Data row (Prop.Rows_1) to Prop.Rows. Right-click to insert a new row and rename this to Prop.Cols.
- In the Prop.Rows Label cell add =“Sun”
- In the Prop.Rows Type cell add =1
- In the Prop.Rows Format cell add =“No sun;Sun”
- In the Prop.Rows Value cell add =INDEX(0,Prop.Rows.Format)
- In the Prop.Cols Label cell add =“Cloud and rain”
- In the Prop.Cols Type cell add =1
- In the Prop.Cols Format cell add ="No cloud;Cloud;Cloud with rain;Cloud with heavy rain"
- In the Prop.Cols Value cell add =INDEX(3,Prop.Cols.Format)
- Rename the first User-defined Cells row (User.Rows_1) to User.ImageRow
- Set the formula for User.ImageRow Value cell to =LOOKUP(Prop.Rows, Prop.Rows.Format)
- Right-click to insert a new row and rename this to User.ImageCol
- Set the formula for User.ImageCol Value cell to =LOOKUP(Prop.Cols, Prop.Cols.Format)
- Right-click to insert a new row and rename this to User.RowCount
- Set the formula for User.RowCount Value cell to =2 (or however many image item rows your image contains)
- Right-click to insert a new row and rename this to User.ColCount
- Set the formula for User.ColCount Value cell to =4 (or however many image item columns your image contains)
- Finally, scroll down to the Foreign Image Info section and edit the formulae as per this picture:
So what’s going on here? Well there’s three key parts to this.
First off are the ordered lists of row and column names that we added (in steps 6 and 10) to the shape’s Shape Data.
Next, the corresponding User cells (ImageRow and ImageCol) keep track of which one is currently selected using a LOOKUP function.
Finally the actual size and position of the image is determined in step 20. The image’s width is set to be a multiple of the number of columns and the height is handled in a similar manner. The image’s position is also set relative to the shape’s origin - remember bottom left (0,0).
So, for example, when the Sun Shape Data is set to ‘Sun’ (index 1), the vertical offset (ImgOffsetY) is –25mm. Similarly, when the Cloud and rain Shape Data is set to ‘Cloud with rain’ (index 2), the horizontal offset (ImgOffsetX) is –50mm. If you toggle the ShapeSheet so that it displays Values rather than Formulas then you’ll see the following:
In the picture below I’ve added a copy of the image behind the shape to reflect the non-visible areas outside of the shape.
Extending the concept
Of course depending on your data you might want to extend this approach a little further by adding a third dimension:
The concept would remain the same but you might want to push the indexing logic into a group shape and then have multiple child shapes for each new layer. Something for another post perhaps…