Welcome to MSDN Blogs Sign in | Join | Help

Whence my interest in Visio?

Looking back over the past year, I’ve created many posts on Visio. I’ve never made it clear why I am so passionate about a product I don’t work on. In this post I’m going to elaborate on my interest.

My background

First, I’ve had an interest in computer graphics for a long time. For example, I owned a KoalaPad over twenty years ago. In the 1980’s I was an avid user of NEOChrome, Degas, Deluxe Paint, Photon Paint. [1] Low resolutions, small color palettes, slow hardware , inconsistent UI - it was a primitive time. [2] But despite those limitations it was a new avenue to be creative – and be creative what I mean is satisfying that fundamental human impulse to make something out of nothing. [3]

 

Deluxe Paint 5.0 (screenshot from Wikipedia)

Image:DPVAboutBoxWithImage.png

 

Deluxe Paint 5.0 (screenshot from Wikipedia)

Image:DPVScreenFormat.png

 

PhotonPaint (screenshot from Wikipedia)

Image:HAM6example.png

Joining Microsoft

I almost pursued a career as a physician and despite (still) having a great curiosity about biology and medicine, I knew computers and technology and the world it opened up for people was where I truly wanted to be. In 1996, I interviewed at Microsoft hoping to work on something related to multimedia, but the team that I interviewed with was Microsoft Exchange and they were such fascinating set of people working on amazing things that I accepted the offer and began working on Microsoft Exchange on the version the world knows as Microsoft Exchange 5.0. I didn’t work on graphics, I worked on the component of Exchange that translated messages from internet formats used by SMTP, IMAP, POP, NNTP into the internal format used by Exchange Server.

Trivia for email buffs – I designed the infamous and sarcastic “TNEF is cool” T-shirt you might have seen some Exchange team members wear.  Everyone rightly hated TNEF.

 

Back to the Pixels

The allure of those little squares of color was unbearable, I left exchange in 1998 to join the PhotoDraw team. They had just released Microsoft PhotoDraw 2000 and wanted to get a major update as soon as possible. This PhotoDraw 2000 V2 released in 1999 I believe almost exactly a year after “V1”.

Despite my long interest as a user who worked with graphics, this was the first time I started learning about the technology. It was fascinating and let me assure you, despite its flaws PhotoDraw 2000 V2 was and continues to be one of the most technically and conceptually advanced graphics apps that has ever existed [4] [5].

I keep a Virtual Machine around with PhotoDraw installed, just in case.

PhotoDraw 2000 V2 running on Vista SP1 as a Hyper-V Virtual Machine 

image

In PhotoDraw 2000 V2 I worked on Setup, Scanners & Cameras, and a brand-new feature: the Batch Save Wizard. This was my first work in User Experience of any kind.

 

PhotoDraw 2000 V2’s Batch Save Wizard

image image image

A Bunch of Things Happened

PhotoDraw was canceled due to an internal reorganization in Microsoft. The short story is I joined a team focused on real-time collaboration (IM, telephony, desktop sharing) because I saw this as the logical evolution in my thinking about supporting the creative impulse – it allowed me to focus on how people collaborate to create as a group. More reorganizations followed and I joined a division working on security – my thinking here was that malware (viruses,etc.) was making it increasingly difficult to even use computers to create. I was happy to help create a more fundamentally secure environment for customers so that they could once again go back to satisfying their creative impulse. After over 4 years in security, I joined the Dynamics team to work on Business Intelligence and I saw this as a way of taking my background in graphics and UX and visualization and contributing towards a growing business at Microsoft.

Back to Visio and PhotoDraw

I always wanted to be able to take PhotoDraw and implement my own extensions (wizards, tools, etc) to both add features I needed and also to prototype new ideas. However, doing this was not so easy – MFC, C++, COM, Office APIs, heap management – and the ratio of effort to reward was not worth it.

In 2003, I started using Visio – I could probably find the first Visio diagram I ever drew. At first, I created flowcharts or simple network topology diagrams and the more I used it the more productive I became. I started using it for increasingly more conceptual diagrams and my thinking about the application evolved.

I viewed it more as tool that both satisfied the creative impulse, let me organize my thoughts, and allow me to communicate and collaborate more effectively. What I found was that the visual clarity helped drive the conceptual clarity and this, in turn, made me and my team more effective in our jobs.

And then the coding environment got *much* better – Visual Studio, .NET, C#, VST0, Visio’s Automation API – suddenly I found myself able to extend and experiment with this tool and do the things that I always wanted to try with PhotoDraw. So then I am bending the tool to my customized needs and it isn’t even taking that much effort.

Below are some examples of how I have extended Visio 2007.

image image image

Ultimately what I get out of all this is I get to take an amazing application and set of technologies and make them all support my own creative impulse and help me think and communicate and collaborate better.

 

And that is really cool.

 

 

Notes

[1] It may be an artifact of my memory, but I don’t believe I’ve found a bitmap graphics app that is as productive today in 2008 as Deluxe Paint was in the 80’s.

 

[2] At first if you wanted a “gradient fill” you had to manually place each pixel. Yes, that was tedious.

 

[3] Nostalgia – acute homesickness

“nostalgia” <- “nostos” + “algia”

“nostos” – (greek) to return home

“algia” – (greek) pain

 

[4] I can at least a couple of posts about this.

 

[5] And then I’ll tell you about what happened to the application and what we were planning to give you in the third version.

Posted by saveenr | 1 Comments

Simplifying Visio Automation with C# 3.0, Linq, and delegates

I saw a great post by the Visio Guy today ( Save Time & Simplify Your VBA Code With CallByName ) and thought it would be a good opportunity to demonstrate some of the simplification that you can achieve with the new features in C# 3.0 and using the VisioAutoExt library.

The point of his post was that you could use CallByName in VBA to reuse an algorithm – in this case applying a function to each element in a set of shapes. The sample code below does the same thing, but I hope you see how elegant it is in C# 3.0

 

Key points

  • The “using VisioAutomation.Extensions” and “Using System.Linq” statements are critical to making this work.
  • The ProcessShapes methods allows you to apply a method to a Visio Shapes collection or any IEnumerable set of shapes.

To use the ProcessShapes method

ProcessShapes( page.Shapes , SomeMethod );

or you can even do this …

ProcessShapes( page.Shapes , shape => { shape.SetFillForefroundColor( System.Drawing.Red ) } );

The FullSource Code

Below I’ve translated the source code from his original post into the C# 3.0 equivalent.

using System;
using System.Collections.Generic;
using System.Linq;
using IVisio = Microsoft.Office.Interop.Visio;
using VisioAutomation.Extensions;

namespace VisioAutomationSamples
{

    public partial class Demo
    {

        public static void sample4()
        {
            var visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
            var doc = visapp.Documents.Add(new Isotope.Drawing.Size(10, 10));
            var page = doc.Pages[1];

            draw_stuff(page);

            ProcessShapes(page.Shapes, MakeRed );
            ProcessShapes(page.Shapes, RotateLeft );
            ProcessShapes(page.Shapes, SetText );

        }

        public static void ProcessShapes( IEnumerable<IVisio.Shape> shapes , Action<IVisio.Shape> func)
        {

            foreach (var shape in shapes)
            {
                func(shape);
            }
        }

        public static void ProcessShapes( IVisio.Shapes shapes, Action<IVisio.Shape> func)
        {
            foreach (IVisio.Shape shape in shapes)
            {
                func(shape);
            }
        }

        public static void draw_stuff( IVisio.Page  page)
        {
            // Draw some rectangles
            int num_rows = 3;
            int num_cols = 3;
            var grid = new Isotope.Drawing.LayoutGrid(page.GetRect(), num_rows, num_cols, false);

            var cells = grid.EnumCells(num_rows, num_cols);
            var shapes = cells.Select(c => page.DrawRectangle(c.rect)).ToList();
        }

        public static void MakeRed( IVisio.Shape shape )
        {
            shape.SetFillForegroundColor( System.Drawing.Color.Red );
        }

        public static void RotateLeft( IVisio.Shape shape )
        {
            if ( shape.OneD == VisioAutomation.VisUtil.BoolToShort(false) )
            {
                double angle =
                    shape.CellsSRC(VisioAutomation.VisProps.ShapeRotation)
                    .get_Result(IVisio.VisUnitCodes.visDegrees);

                double new_angle = angle + (45.0*System.Math.PI/180.0);

                shape.CellsSRC(VisioAutomation.VisProps.ShapeRotation).ResultIU = new_angle;
            }

        }

        public static void SetText(IVisio.Shape shape)
        {
            shape.Text = "Hello World";
        }

    }

}

Posted by saveenr | 2 Comments

Visio Helper Add-in: Updates – Fill Designer improvements, Copy/Paste Size, Snap Size, Snap Position, Duplicate Page, etc.

Quick summary

  • New updates available to the  VisioAutoExt library
  • Gradient Helper renamed to Fill Designer
  • Fill Designer is a now a non-modal anchor window
  • Can copy the size of one shape and paste that size into another shape
  • Can snap shape sized (hard-coded to 0.25 inches)
  • Can snap the position (lower left corner) of a shape to the nearest 0.25 coordinate
  • Close all documents without saving
  • Duplicate a page
  • Still no setup available – use VS2008 to build and run the add-in

Suggestions?

  • Have something that you often do in Visio? let me know and I’ll see if it makes sense to incorporate as part of this add-in

Demo Video

Posted by saveenr | 2 Comments

Visio: “Visio Helper” an Add-In for Visio 2007 to optimize common tasks

Quick summary

  • The VisioAutoExt library now contains an Add-In to Visio2007 called “Visio Helper”
  • It’s an experimental add-in to help me optimize Visio for my tasks – creating new documents and drawing nice gradient fills
  • No setup.exe available yet, I run it by loading the project in Visual Studio 2008 and staring a debugging session
  • Beware: this is very early prototype code

Suggestions?

  • Have something that you often do in Visio? let me know and I’ll see if it makes sense to incorporate as part of this add-in

Demo

  • It takes a while to explain, and it’s easier for me to demonstrate, so I’ve uploaded a video to MSN Soapbox Videos

Posted by saveenr | 1 Comments

Visio: Programmatically creating an org chart from a simple text file

As a believer in the power of simple text formats, I wrote a tool to help make it easy to quickly draw org charts in visio by starting in notepad. It’s useful for more than “org charts” youcan use it to quickly render any simple hierarchical data.

 

Quick summary

  • The VisioAutoExt library now contains a command-line tool called MakeOrgChart
  • MakeFlowChart accepts simple indented text file draws an org chart based on the indentation level

Command-Line Usage

C:\>MakeOrgChart.exe d:\input1.txt

Example 1 – the input text file

 

Charlie
    Tim
        Chris
        Mort
    Julia
        Alice
        Akuma

 

Example 1 – the output drawing

image

 

Example 2 – the input text file

This example illustrates

  • a much larger orgchart
    • these org charts will tend to be very horizontal. you’ll have to use Visio’s org chart tools to re-layout sections to meet your needs
    • The larger these get, the longer it takes visio to draw them using its layout algorithm.
  • multiple roots nodes in the org chart
    • the drawing will compensate by adding a placeholder “ROOT” node, which you can manually delete
  • using the vertical bar character to add linebreaks in the the text

 

Charlie | President and CEO
    Tim | IT Manager
        Chris | Operations Engineer
        Simon | System Implementer
        Isaac | ISV Biz App Developer
        Mort | IT Systems Developer       
        Sean | Power User 
        Ivar | Inexp. VAR Sys Imp 

    Julia | Marketing Executive
        Kevin | Sales Manager
        Nicole | Marketing Staffer
        Benjamin | Marketing Manager
        David | Dedicated Sales Rep
        Michael | Account Manager 
        Susan | Order Processor 

    Marie | Cust. Serv Ops Mngr 
        Lisa | Cust. Service Rep 
        Daniel | Dispatcher 
        Rebecca | Receptionist/Admin 
        Terrence | Outbound Technician 
    Vince  | Operations Manager 
        Karl | Materials Manager 
        Ellen | Warehouse Manager 
        Inga | Purchasing Manager 
        Sammy | Shipping & Receiving 
        Alicia | Purchasing Agent 
        John | Warehouse Worker 
        Ted | Transportation Coord. 
        Tony | Production Manager 
        Lars | Shop Supervisor 
        Oscar | Process Engineer 
        Shannon | Machine Operator 
        Eduardo | Production Planner 
        Heather | Human Resources 
        Ricardo | Quality Assurance 
        Emil | Product Designer 
        June | Dir. of Prof. Services 
        Prakash | Project Manager 
        Reina | Resource Manager 
        Tricia | Project Team Member 
    Sara | CFO 
        Phyllis | Accounting Manager 
        Ken | Controller 
        Cassie | Accountant 
        Penny | Payroll 
        Arnie | Accounts Receivable 
        April | Accounts Payable 
        Annie | Bookkeeper 
        Connie | Credit & Collections Manager 
    Claire | HR Director / Manager 
        Brooke | HR Assistant 
        Grace | Training/Development Manager/ Specialist
        Jacob| Staffing Recruitment Manager/Specialist
        Jodi | Copensation and benifits Manger 
        Luke | HR Generalist

Stan |Small Business Owner 
    Debra | Office Manager 
    Lacy | Store Operations Mngr 
    Jeremy | Cashier 

 

 

Example 2  – the output drawing

Drawing4

Posted by saveenr | 0 Comments

Visio: Using MSAGL to Create Visio Flowcharts Programmatically

Inspired by Chris Roth’s post on creating flowcharts programmatically and my original post on MSAGL with Visio, I’ve uploaded a new version of the VisioAutoExt library that has lets you automatically create flowcharts from a simple XML file.

Quick summary

  • The VisioAutoExt library now contains a command-line tool called MakeFlowChart
  • MakeFlowChart accepts simple XML syntax and can layout a flowchart using MSAGL or Visio to position the flowchart shapes.
  • You are not restricted to flowcharts! It will draw any diagram. Though not all shapes work well with the Dynamic Connector used by the tool

Command-Line Usage

C:\>MakeFlowChart.exe d:\input1.xml

Example 1 – the input XML

<autolayoutdrawing>
  <renderoptions
    usedynamicconnectors="true"
    connectorlineweight="3"
    connectorarrowsize="5"
    resizetofitcontents="true"
    />
  <shapes>
    <shape id="n1" label="FOO1" stencil="server_u.vss" master="Server" />
    <shape id="n2" label="FOO2" stencil="server_u.vss" master="Email Server" />
    <shape id="n3" label="FOO3" stencil="server_u.vss" master="Proxy Server" />
    <shape id="n4" label="FOO4" stencil="server_u.vss" master="Web Server" />
    <shape id="n5" label="FOO4" stencil="server_u.vss" master="Application Server" />
  </shapes>

  <connectors>
    <connector id="c1"  from="n1" to="n2" label="LABEL1" />
    <connector id="c2" from="n2" to="n3" label="LABEL2" />
    <connector id="c3" from="n3" to="n4" label="LABEL1"  />
    <connector id="c4" from="n4" to="n5" label=""/>
    <connector id="c5" from="n4" to="n1" label=""/>
    <connector id="c6" from="n4" to="n3" label=""/>
  </connectors>

</autolayoutdrawing>

 

Example 1 – the output drawing

 

image

Layout – the initial placement of nodes

An initial layout of nodes is always done using MSAGL.

 

Controlling whether to use Dynamic Connectors or Bezier curves

For a proper Visio diagram we should use Dynamic Connectors, but MSAGL draws the edges with Bezier curves.

The usedynamicconnectors attribute controls whether to use dynamic connectors or just draw the bezier curves that MSAGL defines for the drawing.

 

For example, if usedynamicconnectors is set to “false” in Example 1 , the output would look like the image below. The bezier curves look nice, but are cannot respond to editing the diagram, unlike Dynamic Connectors.

image

 

Not satisfied with the MSAGL placement of nodes?

If you specified the use of dynamic connectors, you can always force the output to relayout using Visio’s algorithm via the Shape > Re-layout Shapes menu item.

image

Which will product this result for example 1

image

The node spacing is a bit tight by default. This can again be controlled via Shape > Configure Layout

image

 

image

And picking a larger number for Spacing.

 

Using different stencils and masters

Just specify the stencil and master name in the stencil and master attributes

 

<autolayoutdrawing>
  <renderoptions
    usedynamicconnectors="true"
    connectorlineweight="3"
    connectorarrowsize="5"
    resizetofitcontents="true"
    />
  <shapes>
    <shape id="n1" label="FOO1" stencil="basflo_u.vss" master="Decision" />
    <shape id="n2" label="FOO2" stencil="basflo_u.vss" master="Process" />
    <shape id="n3" label="FOO3" stencil="basflo_u.vss" master="Data" />
    <shape id="n4" label="FOO4" stencil="basflo_u.vss" master="Process" />
    <shape id="n5" label="FOO4" stencil="basflo_u.vss" master="Data" />
  </shapes>

  <connectors>
    <connector id="c1"  from="n1" to="n2" label="LABEL1" />
    <connector id="c2" from="n2" to="n3" label="LABEL2" />
    <connector id="c3" from="n3" to="n4" label="LABEL1" />
    <connector id="c4" from="n4" to="n5" label=""/>
    <connector id="c5" from="n4" to="n1" label=""/>
    <connector id="c6" from="n4" to="n3" label=""/>
  </connectors>

</autolayoutdrawing>

image

Posted by saveenr | 1 Comments

Speeding up Visio automation by batching via SetFormulas(), GetFormulas() and VisDOM

If you've read this post by Bill Morein and this one by Mai-lan, you know that using page.SetFormulas() and page.GetFormulas() can really speed things up when drawing via Automation.

In this post I'm going to show a range of techniques to use SetFormulas() and GetFormulas() to achieve this performance win. The code here is on the latest release (3.0.2) of AutoVisioExt on CodePlex.

First, let's use the VisioAutoExt library and some basic code that draws a 15x15 grid of squares and sets them to have a circular fill gradient with different starting and ending transparencies (something that can't be done in the Vision 2007) UI.

The output should look like this:

image

 

The first attempt without any batching

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IVisio = Microsoft.Office.Interop.Visio;
using VisioAutomation;

namespace VisioAutomationSamples
{

    public partial class Demo
    {

        public static void sample3_a()
        {
            IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
            IVisio.Document doc = visapp.Documents.Add(new Isotope.Drawing.Size(10, 10));

            IVisio.Page page = doc.Pages[1];

            int num_rows = 15;
            int num_cols = 15;
            Isotope.Drawing.LayoutGrid grid = new Isotope.Drawing.LayoutGrid( page.GetRect(), num_rows,num_cols,false);

            var cells = grid.EnumCells(num_rows, num_cols);
            var shapes = cells.Select(c => page.DrawRectangle(c.rect)).ToList();

            format_shapes_no_batching(page, shapes);
        }

        public static void format_shapes_no_batching( IVisio.Page page, IEnumerable<IVisio.Shape> shapes)
        {
            // no batching
            foreach (IVisio.Shape shape in shapes)
            {
                shape.SetFillPattern(FillPatternType.RadialCenter);
                shape.SetFillForegroundColor(System.Drawing.Color.Red);
                shape.SetFillForegroundTransparency(0);
                shape.SetFillBackgroundColor(System.Drawing.Color.Black);
                shape.SetFillBackgroundTransparency(50);
            }
        }

    }

}

 

This example uses the VisioAutoExt library so the code is in general a bit simpler than "pure" Visio automation code. If you run the code, you'll notice the delay as each shape is drawn and then an even greater delay as the fill properties are set on each shape.

 

 

The second attempt using SetFormulas() and GetFormulas()

Now let's take the performance advice and use SetFormulas() and GetFormulas(). We'll replace format_shapes_no_batching() with this function format_shapes_batching_1()

 

public static void format_shapes_batching_1(IVisio.Page page, List<IVisio.Shape> shapes)
{

    List<short> shapesheet_info = new List<short>();

    foreach (IVisio.Shape shape in shapes)
    {
        shapesheet_info.Add((short)shape.ID);
        shapesheet_info.Add((short)IVisio.VisSectionIndices.visSectionObject);
        shapesheet_info.Add((short)IVisio.VisRowIndices.visRowFill);
        shapesheet_info.Add((short)IVisio.VisCellIndices.visFillPattern);
        shapesheet_info.Add((short)shape.ID);
        shapesheet_info.Add((short)IVisio.VisSectionIndices.visSectionObject);
        shapesheet_info.Add((short)IVisio.VisRowIndices.visRowFill);
        shapesheet_info.Add((short)IVisio.VisCellIndices.visFillForegnd);
        shapesheet_info.Add((short)shape.ID);
        shapesheet_info.Add((short)IVisio.VisSectionIndices.visSectionObject);
        shapesheet_info.Add((short)IVisio.VisRowIndices.visRowFill);
        shapesheet_info.Add((short)IVisio.VisCellIndices.visFillForegndTrans);
        shapesheet_info.Add((short)shape.ID);
        shapesheet_info.Add((short)IVisio.VisSectionIndices.visSectionObject);
        shapesheet_info.Add((short)IVisio.VisRowIndices.visRowFill);
        shapesheet_info.Add((short)IVisio.VisCellIndices.visFillBkgnd);
        shapesheet_info.Add((short)shape.ID);
        shapesheet_info.Add((short)IVisio.VisSectionIndices.visSectionObject);
        shapesheet_info.Add((short)IVisio.VisRowIndices.visRowFill);
        shapesheet_info.Add((short)IVisio.VisCellIndices.visFillBkgndTrans);
    }

    System.Array shapesheet_info_array = (System.Array)shapesheet_info.ToArray();

    System.Array formula_array;
    page.GetFormulas(ref shapesheet_info_array, out formula_array);

    int i=0;
    foreach (var shape in shapes)
    {
        formula_array.SetValue("40", i++);
        formula_array.SetValue("rgb(255,0,0)", i++);
        formula_array.SetValue( "0%", i++);
        formula_array.SetValue("rgb(0,0,0)", i++);
        formula_array.SetValue("50%", i++);
    }
    short flags = 0;
    page.SetFormulas(ref shapesheet_info_array, ref formula_array, flags);

}

 

How wonderfully painful. At least it's really fast compared to the first example.

 

 

The third example: Using VisBatchFormulaApplier

We can get much simpler code and all the performance benefits if we use the VisBatchFormulaApplier class found in the VisioAutoExt library.

 

public static void format_shapes_batching_2(IVisio.Page page, IEnumerable<IVisio.Shape> shapes)
{
    VisioAutomation.VisBatchFormulaApplier batch = new VisBatchFormulaApplier();
    foreach (IVisio.Shape shape in shapes)
    {
        batch.SetFormula( shape, VisProps.FillPattern, (int) FillPatternType.RadialCenter );
        batch.SetFormula( shape, VisProps.FillForegroundColor , System.Drawing.Color.Red );
        batch.SetFormula( shape, VisProps.FillForegroundTransparency, 0, VisUnit.Percent);
        batch.SetFormula( shape, VisProps.FillBackgroundColor, System.Drawing.Color.Black);
        batch.SetFormula( shape, VisProps.FillBackgroundTransparency, 50, VisUnit.Percent);

    }
    batch.ApplyFormulas(page);
}

 

It isn't quite as readable as the first example, but it's much better then the second example, but it is very fast.

VisBatchFormulaApplier will generally make things much simpler.

Some issues:

  • it will only with shapes on the same page
  • you have to write your automation code to create all the objects first and then work use the applier.
  • you have to remember that some properties require you to specify the unit to work (for example VisUnit.Percent for transparencies)

 

 

The fourth example: using VisDOM

And now, we use the new experimental VisDOM support. VisDOM is essentially a small set of classes that will automatically draw shapes and apply them in batch. As an extra benefit, things are much more readable and strongly typed than any of the examples above. Here's the full example:

 

public static void sample3_b()
{

    VisDOM.Document doc = new VisDOM.Document();
    VisDOM.Page page1 = new VisDOM.Page(10, 10);
    doc.Pages.Add(page1);

    int num_rows = 15;
    int num_cols = 15;
    Isotope.Drawing.LayoutGrid grid = new Isotope.Drawing.LayoutGrid(page1.Rect, num_rows, num_cols, false);

    var cells = grid.EnumCells(num_rows, num_cols);
    var shapes = cells.Select(c => page1.DrawRectangle(c.rect)).ToList();

    foreach (VisDOM.Shape shape in shapes)
    {
        shape.FillPattern.Value = FillPatternType.RadialCenter;
        shape.FillForegroundColor.Value = System.Drawing.Color.Red;
        shape.FillBackgroundColor.Value = System.Drawing.Color.Black;
        shape.FillForegroundTransparency.Value = 0;
        shape.FillBackgroundTransparency.Value = 50;

    }

    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    VisDOM.VisDOMRenderer.RenderToVisio(doc, visapp,false,false);

}

 

VisDOM constructs a document in memory and then the VisDOMRenderer.RenderToVisio() method does all the Visio magic for batching.

Notice how the properties like FillForegroundTransparency are strongly typed, will work with Intellisense, and don't require knowledge of the VisUnit codes.

Posted by saveenr | 0 Comments

My Latest enhancements to the VisioAutoExt library

I've published a big update to the VisioAutoExt library on Codeplex. The changes are significant enough with enough breaking changes from the old code that I'm calling this version 3.0.

 

 

Three things I'll talk about in this post:

  • What changed
  • Why it's interesting to use the library
  • How to use the library

 

What changed

  • UPDATES: Lots of renaming and refactoring
  • NEW: Added a DemoVisioAutomation winform application. It makes it easer to see what can be done with the library
  • NEW: Enhanced Batching support via BatchFormulaApplier
  • UPDATES: Lots of the test cases now use the Batching support and so drawing takes place much faster.
  • NEW: An experimental library called VisDOM added to support even simpler and faster drawing in batch and perhaps one day emit Visio XML directly without launching the app
  • UPDATE: Kuler demo updated to latest XML schema, added test cases
  • NEW: VisioHelper a winform app that helps in drawing nice gradients in visio
  • NEW: VisProps, a class that contains predefined section,row,and cell tuples. Makes using CellsSRC much easier

 

Why use it?

This is best illustrated by walking through a simple project (create a new doc and draw a rectangle programmatically).

 

The desired result

The output we want is simple:

image

Step 1: Starting point: let's do this without the VisioAutoExt library

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IVisio = Microsoft.Office.Interop.Visio;
using VisioAutomation;

namespace VisioAutomationSamples
{

    public partial class Demo
    {

        public static void sample1_a()
        {
            IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
            IVisio.Document doc = visapp.Documents.Add("");
            IVisio.Page page = doc.Pages[1];

            page.PageSheet.get_CellsSRC(
                (short)IVisio.VisSectionIndices.visSectionObject,
                (short)IVisio.VisRowIndices.visRowPage,
                (short)IVisio.VisCellIndices.visPageWidth).Formula = "5";
            page.PageSheet.get_CellsSRC(
                (short)IVisio.VisSectionIndices.visSectionObject,
                (short)IVisio.VisRowIndices.visRowPage,
                (short)IVisio.VisCellIndices.visPageHeight).Formula = "5";

            IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
        }

    }

}

 

The first improvement: No longer need to use the awkward "get_CellsSRC", now it's just CellsSRC

This makes it look much more like VB code that Visio emits when it records Macros. So that's an easy, cheap win.

public static void sample1_b()
{
    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    IVisio.Document doc = visapp.Documents.Add("");
    IVisio.Page page = doc.Pages[1];

    page.PageSheet.CellsSRC(
        (short)IVisio.VisSectionIndices.visSectionObject,
        (short)IVisio.VisRowIndices.visRowPage,
        (short)IVisio.VisCellIndices.visPageWidth).Formula = "5";
    page.PageSheet.get_CellsSRC(
        (short)IVisio.VisSectionIndices.visSectionObject,
        (short)IVisio.VisRowIndices.visRowPage,
        (short)IVisio.VisCellIndices.visPageHeight).Formula = "5";

    IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}

 

The second improvement: No more casting to "short" with CellsSRC

Enums such as VisSectionIndices are ints. But CellSRC accepts shorts and this results in code always casting these values to type short. Now that is no longer necessary. And again this looks more like the code that Visio generates for macros. Another easy, cheap, win.

public static void sample1_c()
{
    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    IVisio.Document doc = visapp.Documents.Add("");
    IVisio.Page page = doc.Pages[1];

    page.PageSheet.CellsSRC(
       
IVisio.VisSectionIndices.visSectionObject,
        IVisio.VisRowIndices.visRowPage,
        IVisio.VisCellIndices.visPageWidth
).Formula = "5";
    page.PageSheet.CellsSRC(
        IVisio.VisSectionIndices.visSectionObject,
        IVisio.VisRowIndices.visRowPage,
        IVisio.VisCellIndices.visPageHeight
).Formula = "5";

    IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}

The third improvement: Much less typing and memory required to use CellsSRC

The problem with CellsSRC is that you always need three parameters and have get them correct. This has gotten much simpler in v3. The CellsSRC now takes an object that bundles all three together and a predefined list of these is available under the VisProps class.

So instead of remembering

IVisio.VisSectionIndices.visSectionObject, IVisio.VisRowIndices.visRowPage, IVisio.VisCellIndices.visPageWidth

You now just have to remember:

VisProps.PageWidth

And so the code gets much shorter.

public static void sample1_d()
{
    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    IVisio.Document doc = visapp.Documents.Add("");
    IVisio.Page page = doc.Pages[1];

    page.PageSheet.CellsSRC( VisProps.PageWidth ).Formula = "5";
    page.PageSheet.CellsSRC( VisProps.PageHeight ).Formula = "5";

    IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}

 

The fourth improvement: Convenience. Common tasks are easy available.

Extension methods have been added Visio classes that "just work". See how easy it is to set the page size?

public static void sample1_e()
{
    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    IVisio.Document doc = visapp.Documents.Add("");
    IVisio.Page page = doc.Pages[1];

    page.SetSize(5, 5);

    IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}

 

More convenience ...

You can just create the page with the correct size in the first place.

public static void sample1_f()
{
    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    IVisio.Document doc = visapp.Documents.Add( new Isotope.Drawing.Size(5,5) );
    IVisio.Page page = doc.Pages[1];

    IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}

 

The Diff

Red is what was removed. Light red means a removal occurred on that line.

Yellow is what was added. Light yellow means an addition occurred on that line.

image

 

 

How to start using the Library

Step 1- Create a new project in Visual Studio 2008 , Make sure to select .NET Framework 3.5

image

 

Step 2 - Add a reference to VIsio 2007 Primary Interop Assembly

Right-click on <project> / References  then select Add Reference

image

Select Microsoft.Office.Interop.Visio. Make sure you select Version 12, not 11

image

It will show in the references ...

image

 

 

 

Step 3 -Alias "IVisio" to Microsoft.Office.Interop.Visio

Add this line to the top part of the file "using IVisio = Microsoft.Office.Interop.Visio;"

image

 

Step 4. Add a reference to Isotope.Drawing.DLl and Isotope.Common.DLl, VisioAutomation.DLL

image

You'll see them in the references

image

Step 5. add using VisioAutomation

To use it effectively you must have a "using VisioAutomation" because that is how the extension methods get bound.

image

 

Let's compare, look at what Intellisense shows on Shape if you do not add this using line...

 

See After SetCenter there are just three methods before you see the ShapeAdded event.

 

image

 

Now when you add "using VisioAutomation" you'll see a all the extension methods are available.

 

image   

 

The Extension methods are clearly marked with the downward blue arrow

 

image

 

Now try it out...

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IVisio = Microsoft.Office.Interop.Visio;
using VisioAutomation;

public class Demo

{

public static void sample1_f()
{
    IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
    IVisio.Document doc = visapp.Documents.Add( new Isotope.Drawing.Size(5,5) );
    IVisio.Page page = doc.Pages[1];

    IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}

}

 

Reference: Here's what VisProps contains

image

Posted by saveenr | 4 Comments

Visio Export To Xaml: Now with an Installer

I added an installer program for VisioExportToXaml so that you can just try the export without being forced to compiling the source. I also made some minor UI changes.

 

How to Install

  • Remove any previous versions of VisioExportToXaml
  • Make sure you've installed Visio 2007.
  • Download the ZIP for the installer from the VisioExportToXAML codeplex project and extract to a folder
  • Then run the Setup.EXE.
  • If needed .NET Framework 3.5 and VSTO 3.0,  will be downloaded and installed.
  • Once the install is finished verify that it is enabled in Visio...
  • In Visio, navigate to Tools / Trust Center

image

  • Click Add-Ins
  • Verify that Manage is set to "COM Add-ins"
  • Click Go

image

  • Check VisioExportToXAML if it is not already checked (In the screenshot below you'll see that the reason that there was a failure loading the add in ... something I've seen with Windows XP but not with Vista)

image

Posted by saveenr | 4 Comments

Visio Trick: One-Color and Two-Color Glows

In which shapes will receive a spotlight

Let's suppose you have the network diagram below.

image

And what you'd like to to provide a little extra attention on server A. For example to emphasize it's importance or status. Perhaps we wish to indicate it's in a "warning" state.

You could try setting the fill color ...

image

And that would work. But given the nice 3-point gradient used in the diagram, we want to go the extra mile and make highlight A in a more subtle manner. What we want is this:

image

And now we'll learn how to make a "glow" shape that you can use to highlight other shapes.

First, draw a rectangle, and right-click and select Format / Fill

image

The Fill dialog launches

image

for Pattern select 40 ( a radial fill(

image

Then for Color select Orange

image

Then for Fill Pattern select Orange

image

Then click OK.

image

Enable the shapesheet by going to Tools/Options/Advanced and selecting run in developer mode

image

Right click on Show Shapesheet and in the Fill Format section, change the FillBkgndTrans to 100%.

image

The shape will now look like this:

image

Get rid of the line ...

image

And now the shape will look like this:

image

Now place it above the background but underneath the server A shape and you get:

image

At this point, you've got a nice highlight effect. But we can do better. Leveraging the technique for the 3-point gradients, we are going to make a two color glow.

To help visualize the differences:

image

In the 2-color glow, we have the same orange color, but toward the center it gets progressively brighter to white.

NOTE: the 2-color glow is still 1 shape.

How to achieve this?

First, draw a 1-color glow using the color white.

image

Select that shape and choose Format / Shadow

image

In the Shadow dialog

  • Set Style to 13: Offset, custom
  • Set Color to orange (or whatever you want)
  • Set Pattern to 40
  • Set Pattern Color to orange (or whatever you selected for Color)
  • Set the X Offset & Y Offset to 0 and 0
  • Set Magnification to 170%

And close the Shadow dialog

You should see this:

image

Right click on the shape and select Show Shapesheet

And in the Fill Format section set ShdwBkgndTrans to 100%

image

And you will now have this

image

Which you can then use as a more intense highlight for Server A

image

Notice boundary of the shape.

Keep in mind that the orange glow is beyond the shape's selection area and is thus not selectable. You'll have to click on the "inner" glow. The picture below should make it clear.

image

Also, you can have fun with the glows to make some nice backgrounds.

image

A visio file with all the shapes is attached to this post.

Posted by saveenr | 3 Comments

Attachment(s): two-color-glow-samples.vsd

Visio 2007 Trick: 3-Point Gradient Fills with Transparency

A Question

How many shapes are required to draw the image below in Visio?

image

The Answer

5 shapes.

No groups, no wierd geometries. Just 5 shapes.

What I want

I want rich, smooth, multi-color gradient fills with independent transparencies for each color.

I could get what I want by drawing multiple shapes. That can work. But, sometimes it's irritating. The shapes have to be perfectly aligned, you'll have some selection wierdness, etc. Simpler to have 1 shape.

What is a  3-Point Gradient Fill with Transparency?

Before I show the steps. Let me give you a clearer understanding of what I mean.

First, here is a conceptual drawing the 3-point I really want to draw:

image

Now, without getting into the explanation, the gradient we'll be able to draw will be more like this:

image

So visualize it forming like this:

image

Implementing 3-Point Gradient Fill with Transparency

We are going to use a combination of the normal shape fills and the SHADOW feature to draw a 3-point gradient.

It's not perfect, it doesn't do everything you'd expect in an application like Illustrator, but I'm sure it's more than what you've seen with Visio so far.

Just so that the goal is clear: here is what we will end-up with:

image

  • ORANGE in the upper left
  • LIGHT BLUE in the upper-right
  • DARK BLUE in along the bottom

Steps

  • Launch Visio
  • Create a new document
  • Draw a rectangle

image

  • Select the rectangle, right-click, and choose Format / Fill...

image

  • The Fill dialog will appear

image

  • Set the colors appropriately (pay attention)
  • Set the Fill / Pattern to 36

image

  • Set Fill / Color and FIll / Pattern Color to the color you want for the upper left (ORANGE)

image

  • Don't touch the transparency for now
  • Set the Shadow / Pattern to 28

image

  • Set Shadow / Color to the color you want along the bottom of the shape (DARK BLUE)
  • Set Shadow / Pattern Color to the color you want at the upper right of the shape (LIGHT BLUE)
  • Click OK
  • Here is what you have now

image

  • Turn on the shape sheet via Tools / Options / Advanced / Run in developer mode and click OK to close the Tools / Options dialog

image

  • Select the shape, right click, and select Show ShapeSheet
  • Find the FIllBkgndTrans cell and change the value from 0% to 100%

image

  • You'll notice the change in the shape once you finish making this change

image

  • close the shapesheet window

image

  • A closer look

image

  • Select the shape
  • Form the menu, select Format / Shadow ...