I've recently been involved in a WPF based project that utilises Microsoft Virtual Earth and I thought it would make an interesting exercise to combine this with Visio's Save As Web output.
I've uploaded a live demo over here that shows how clicking a shape, containing a latitude and longitude string, can update a Virtual Earth map embedded in the toolbar panel on the left hand side.
I'm not going to go into lots of detail about how to use Virtual Earth as the main purpose of this post is to demonstrate how to connect it to Visio web output, but if you want to find out more then here are a few links to get you going:
Adding a widget
Visio's Save as Web 'toolbar' panel contains a series of widgets that are all kept in the widgets.htm file. The selection available depends on which items were checked in the Publishing options section of the Save As Web dialog as Visio generated the files:
Each widget follows a roughly similar pattern using a table to hold a title bar and content that can be expanded and collapsed. Once the content has been initialised it is added to a collection of widgets and it's then just a case of wiring up the new widget content to respond to changes made by the user.
Latitude and longitude
It strikes me that a good point to connect the Virtual Earth map (widget) and our shapes is when the details table gets updated (in CreatePropTable function in frameset.js) as it's at this stage that the shape data is being interrogated. The code, therefore, looks for a shape data name of visVELatLong and if it finds it passes the associated value string to the map.
Ok, so that's quick overview, but following is a walkthrough of how to add the functionality to your own files.
Walkthrough - Part 1 (original Visio document)
1 - Add a shape data row (custom property) named visVELatLong to each master or shape that you want to receive map functionality. (Note - The label cell must be blank or also named visVELatLong.)
2 - Add latitude and longitude data in the value cell in the following format:
latitude,longitude,zoom51.392351,-1.326599,12
Note - the final zoom level figure is optional and if included must be an integer between 1 and 19. (You can see the zoom level in operation in the above demo by clicking on the 'Group' shape. All other shapes do not contain a zoom setting and so default to zoom level 4.)
3 - Save the Visio document and then click File / Save As Web Page... (ensuring you click the Publish button on the subsequent dialog).
Walkthrough - Part 2 (widgets.htm)
1 - Open your widgets.htm file in a text editor and search for the following div tag (this assumes that you included Search in your Publishing options above):
<div id="divSearch" class="holder">
2 - Paste in the code from this text file, just above the div tag you've just found.
3 - Now navigate back up the same file to find the page's load function and add the code below (highlighted in blue):
function load()
{
parent.g_WidgetsLoaded = true;
{
parent.g_WidgetsLoaded = true;
if (parent.g_LoadingWidgets)
{
parent.g_LoadingWidgets = false;
parent.location.reload();
}
//Load VE map
GetMap();
}
{
parent.g_LoadingWidgets = false;
parent.location.reload();
}
//Load VE map
GetMap();
}
4 - Continue up the file again until you find the ToggleAll function and then add the following code just inside the function's final brace (again in blue):
if(this.PNZ)
{
OpenCloseFunc(this.PNZ)
}
// Include VE widget in toggle
if (this.Map) {
OpenCloseFunc(this.Map)
}
}
{
OpenCloseFunc(this.PNZ)
}
// Include VE widget in toggle
if (this.Map) {
OpenCloseFunc(this.Map)
}
}
5 - Finally head right up to the top of the file, and inside the main script block, add a variable for the map itself:
<script type="text/jscript" language="jscript">
var g_VEMap = null;
var imgMin = new Image();
var imgMin = new Image();
6 - Save the file and close.
Walkthrough - Part 3 (frameset.js)
1 - Open your frameset.js file in a text editor and search for the CreatePropTable function. Near the bottom of the function add the code (that's right, in blue) that calls the map function:
strCPHTML += strValueText + "</TD></TR>";
}
}
//Set map lat long if correct shape data found
if (frames[0].g_VEMap != null) {
if (strLabelText === "visVELatLong") {
frames[0].SetVEMapLocation(strValueText);
}
}
}
if (frames[0].g_VEMap != null) {
if (strLabelText === "visVELatLong") {
frames[0].SetVEMapLocation(strValueText);
}
}
}
if(strCPHTML != "")
{
strCPHTML = strStartTable + strCPHTML + strEndTable;
}
else
{
strCPHTML = "No Details Available.";
}
{
strCPHTML = strStartTable + strCPHTML + strEndTable;
}
else
{
strCPHTML = "No Details Available.";
}
2 - Save the file and close.
Wrap up
So I hope that gives a reasonable base for adding Virtual Earth functionality to Visio's Save As Web output. There's obviously plenty of scope for extending this with pushpin and route data, for example, and if that sounds interesting then you might also want to check out a couple of posts from David Parker in which he deals with how to use KML based data with Visio:
[UPDATE 26.04.10 - Johannes Kebeck, of Bing Maps fame, has recently written great post on integrating Floorplans and Photosynth on Bing Maps using Visio.][UPDATE 21.07.14 - Images for the above link got lost when Johannes' blog moved home, but you can still see the original images here: http://web.archive.org/web/20101101221130/http://jkebeck.wordpress.com/2010/04/25/floorplans-and-photosynth-on-bing-maps/ ]