Welcome to MSDN Blogs Sign in | Join | Help

Automating Visio with IronPython to Generate nice, consistent gradients

A needed to generate a series of consistent gradients in Visio this week for some diagrams. It's tedious to do this manually so I automated the task with IronPython 1.1.

Running this command line:

image

 

Produces launches Visio to 2007 produce this output.

 

image

 

The attached package with source is here: msdn_saveenr-2007-07-07-Automating Visio with IronPython.zip

It includes three files:

  • AutoVisio.Dll - where I wrote a lot of code to simplify the use of Visio from other managed code languages
  • Isotope.Color.Dll - some simple colorspace utilities (RGB, HSB, HSL)
  • gradient_explorer.py - the code that generates the gradients

gradient_explorer uses a seed color to generate a sequence of gradients automatically. Using different seed colors results in different colors. Examples are below:

image

Below is the gradient explorer source

 

 

 

"""

gradient_explorer

USAGE
-----
Run script. It will start visio and draw a series of gradients based on the seed_color.

HOW TO GET DIFFERENT GRADIENTS
------------------------------
-alter the seed_color
-play with the modify_color_x functions

HISTORY
-------

2007-07-06
Updated to produce multiple rows

2007-07-05
Initial Version

"""
import sys
import clr

import System

clr.AddReference("System.Drawing")
import System.Drawing

clr.AddReference("Microsoft.Office.Interop.Visio")
from Microsoft.Office.Interop import Visio


clr.AddReferenceToFileAndPath("AutoVisio.dll")
import AutoVisio

clr.AddReferenceToFileAndPath("Isotope.Color.dll")
import Isotope.Color


def modify_color_1( input_hsl ) :
    return input_hsl.Add( 1.1, -input_hsl.Saturation , -0.05 )

def modify_color_2( input_hsl ) :
    return input_hsl.Add( 0.0, 0.0 , -0.1 )

def modify_color_3( input_hsl ) :
    return input_hsl.Add( 0.0, 0.0 , -0.2 )

def modify_color_4( input_hsl ) :
    return input_hsl.Add( 0.0, 0.0 , -0.3 )

def modify_color_5( input_hsl ) :
    return input_hsl.Add( 0.02, 0.1 , -0.2 )

def modify_color_6( input_hsl ) :
    print input_hsl
    return input_hsl.Add( -0.02, 0.1 , -0.2 )


text_color_black = Isotope.Color.HSLColor.FromWebColorString("#000000") 
text_color_white = Isotope.Color.HSLColor.FromWebColorString("#ffffff") 

def calc_text_color( start_color, end_color ) :
    mid_lum = ((start_color.Luminance+ end_color.Luminance) /2.0)

    if ( mid_lum>0.6) :
        text_color = text_color_black
    else :
        text_color = text_color_white

    return text_color


def explore_gradients():

    seed_color = Isotope.Color.HSLColor.FromWebColorString( "#ff0000" )
    #seed_color = Isotope.Color.HSLColor.FromRGBBytes( 193,202,221)
    #seed_color = Isotope.Color.HSLColor.FromRGBBytes( 249,185,81)
    #seed_color = Isotope.Color.HSLColor.FromRGBBytes( 171,205,137)
    
    # number of blocks in each row
    steps = 20

    # 36 is a gradial gradient that begins in the upper left        
    grad_pattern_id = 36

    # One row will be drawn for each color function in this list
    color_funcs = [ modify_color_1, modify_color_2, modify_color_3 , modify_color_4 , modify_color_5, modify_color_6 ]


    grad_rows = []

    # caclculate an evenly spaced set of luminances starting from 0.0 to 1.0
    luminances = [ v*(1.0/(steps-1)) for v in xrange(steps) ]

    # using the seed color generate the starting color used for each row
    row_start_colors= [ Isotope.Color.HSLColor( seed_color.Hue, seed_color.Saturation, lum ) for lum in luminances ]


    # generate the colors for each row
    # each row will contain a tuple of (start,end) colors
    for color_func in color_funcs :
        row_end_colors = [ color_func(start_color) for start_color in row_start_colors ]
        grad_rows.append( zip( row_start_colors, row_end_colors) )


    # for debugging, print out all the color strings before drawing begins
    for grad_colors in grad_rows :
        for i,grad_color in enumerate(grad_colors):
            print i+1, grad_color[0].ToWebColorString(), "->", grad_color[1].ToWebColorString()
        print
    
    num_cols = steps
    num_rows = len( grad_rows )

    # each cell is one inch in width and height
    # the page has a 1 inch border on each of the four sides
    page_width = 2 + num_cols
    page_height = 2 + num_rows
    page_size = AutoVisio.Size( page_width ,page_height)

    # Launch Visio to do the drawing
    app = AutoVisio.VisioLib.StartVisio()

    # Create a document with an initial empty page    
    doc = AutoVisio.VisioLib.CreateDocument( app,  page_size )

    # Locate that first page
    page = doc.Pages[1]

    # for each row draw the gradients
    for grad_row_index, grad_colors in enumerate(grad_rows) :

        for n,grad_color in enumerate(grad_colors) :

            rect = AutoVisio.Rect( 1+n,1+grad_row_index,1+n+1,1+grad_row_index+1)
            start_color,end_color = grad_color

            # find the right text color that is visible on the gradient
            text_color = calc_text_color( start_color, end_color ) 
            
            # Draw the shape        
            shape= AutoVisio.VisioLib.DrawRectangle( page, rect )

            # Set the shape attributes
            AutoVisio.VisioLib.SetFillGradient( shape ,
                                                grad_pattern_id,
                                                start_color.ToSystemDrawingColor(),
                                                end_color.ToSystemDrawingColor() )
            AutoVisio.VisioLib.SetLinePattern( shape, 0 )

            # for debugging, can set the text content of the shape
            # shape.Text = str( grad_pattern_id )
            # AutoVisio.VisioLib.SetTextColor( shape, text_color.ToSystemDrawingColor()  )
    
if ( __name__ == '__main__' ) :
    explore_gradients()
    
    

Published Saturday, July 07, 2007 7:38 AM by saveenr

Attachment(s): msdn_saveenr-2007-07-07-Automating Visio with IronPython.zip

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Visio Guy » Blog Archive » Interesting Blog With Cool Visio Topics

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker