#!/usr/local/bin/tclsh8.0 -f # # This example builds a barchart from sample data # (this is the sort of application one might have in mind for building live web displays) # # Sorry it doesn't do this with a set of procedures.... # # The hardest thing to understand about the example is that the units for the image # start at 0 on the TOP of the image. This makes everything else seem "upside down" # if [ catch { package require gd } err ] { load gd.dll } set data { { 1990 27.2 } { 1991 31.6 } { 1992 35.0 } { 1993 22.1 } { 1994 12.0 } { 1995 26.1 } { 1996 30.1 } { 1997 41.2 } } set width 640 set height 480 # Get some data information prepared: How many items, and min/max range set numitems [ llength $data ] set itemwid [ expr round ( ( $width - 40 ) / $numitems ) ] set min [ lindex [ lindex $data 0 ] 1 ] set max $min foreach row $data { set val [ lindex $row 1 ] if { $val > $max } { set max $val } elseif { $val < $min } { set min $val } } # Assume 10 is a reasonable scale. set min [ expr round( [ expr $min / 10.0 ] ) * 10.0 ] set max [ expr round( [ expr ( $max + 9.9 ) / 10.0 ] ) * 10.0 ] # Save 20 pixels on all sides set unitheight [ expr ( $height - 40 ) / ( $max - $min ) ] # Create a tile for filling rectangles # This will be used later as a -fill %$tile argument to the rectangles. # The pattern is just diagonal black lines against a yellow background. set tile [ gd open -width 8 -height 8 -background "255 255 0" ] gd line $tile 0 1 1 0 -fill "0 0 0" gd line $tile 0 5 5 0 -fill "0 0 0" gd line $tile 2 7 7 2 -fill "0 0 0" gd line $tile 6 7 7 6 -fill "0 0 0" # Create an image with a blue background set im [ gd open -width $width -height $height -background "0 0 255" ] # Draw axes in green gd line $im 20 20 20 [ expr $height - 20 ] -fill "0 255 0" gd line $im 20 [ expr $height - 20 ] [ expr $width - 20 ] [ expr $height - 20 ] -fill "0 255 0" # Draw a grid every 10 units in black and put black text next to it for { set i [ expr round( $min ) ] } { $i < $max } { incr i 10 } { set y [ expr $height - 20 - ( $unitheight * ( $i - $min ) ) ] gd text $im 4 $y -text $i -orientation vertical -fill "0 0 0" -font mediumbold gd line $im 18 $y 22 $y -fill "0 0 0" } # Build bars according to the data, all bars in the tile pattern with red outlines. # Put data values in a light cyan immediately above the bars set x 20 foreach item $data { set y [ expr $height - ( [ lindex $item 1 ] - $min ) * $unitheight ] gd text $im $x [expr $height - 16 ] -text [lindex $item 0] -fill "#1" -font giant gd rectangle $im [ expr $x + 2 ] [ expr $height - 20 ] [ expr $x + $itemwid - 2 ] $y -outline "255 0 0" -fill %$tile gd text $im [expr $x + $itemwid / 3 ] [ expr $y - 16 ] -text [ lindex $item 1 ] -font mediumbold -fill "255 128 255" incr x $itemwid } # Just for fun, what if we make color 0 (background) transparent? # Try it without this for contrast gd config $im -transparent "#0" gd close $im -file barchart.png -filetype png if { $tcl_interactive == 0 } { exit }