sgraph.tcl 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507
  1. ###############################################################
  2. #
  3. # sgraph
  4. #
  5. # This "supergraph" is an enhanced BLT graph widget.
  6. # The sgraph includes the standard BLT graph, plus
  7. # a number of buttons for Zoom, Save, and Print
  8. # functionality. Sgraph also includes scrollbars.
  9. #
  10. # usage:
  11. #
  12. # package require sgraph
  13. # set g [sgraph::sgraph .myGraph]
  14. # pack $g -expand y -fill both
  15. #
  16. #
  17. # Implementation:
  18. #
  19. # The sgraph command actually creates a frame widget and
  20. # chucks all the interesting extra stuff (like buttons and
  21. # the "real graph" widget) into the frame. The widget
  22. # command is aliased (using a technique outlined at
  23. # http://wiki.tcl.tk/1146) so that you can directly
  24. # access all the regular blt::graph subcommands and
  25. # configuration options.
  26. #
  27. #
  28. # Added calls that can be used in the application:
  29. # ::sgraph::Save
  30. # graph - graph created with ::sgraph::sgraph
  31. # psfilename - name of the PostScript file
  32. # ::sgraph::Print
  33. # graph - graph crated with ::sgraph::sgraph
  34. # flg - 1 to popup print options dialog
  35. # 0 for no popup, will use existing
  36. # values
  37. # ::sgraph::SetPrinter
  38. # prntrNme - name of the printer
  39. # ::sgraph::SetLandscape
  40. # val - 0 for portrait
  41. # - 1 for landscape
  42. # ::sgraph::SetMaxpect 0 or 1
  43. # val - 0 for no maxpect
  44. # - 1 for maxpect
  45. # ::sgraph::SetDecorations 0 or 1
  46. # val - 0 for no decorations
  47. # - 1 for decorations
  48. # ::sgraph::SetColormode color or grayscale
  49. # val - color
  50. # - grayscale
  51. #
  52. ################################################################
  53. package provide sgraph 1.0
  54. package require Tk
  55. package require BLT
  56. package require BWidget
  57. ################################################################
  58. # namespace for sgraph
  59. ################################################################
  60. namespace eval ::sgraph {
  61. # Set up the display of the Zoom box outline
  62. variable interval
  63. variable afterId
  64. # Index of currently active graph
  65. variable curIndx -1
  66. # Currently active graph
  67. variable curGraph 0
  68. # Last zoom extents
  69. variable oldxA 0
  70. variable oldyA 0
  71. variable oldxB 0
  72. variable oldyB 0
  73. # First time into zoom
  74. variable first
  75. # Index for for grph array
  76. variable grph_cnt -1
  77. # array of grph identifiers
  78. variable grph
  79. array set grph {}
  80. # arrays of graph extents
  81. variable grph_xmin
  82. variable grph_ymin
  83. variable grph_xmax
  84. variable grph_ymax
  85. # Icon images for the zoom-in, zoom-out,
  86. # zoom-all and print buttons
  87. variable print
  88. variable viewall
  89. variable viewin
  90. variable viewout
  91. variable saveas
  92. variable info
  93. variable active_mode
  94. array set active_mode {}
  95. variable text_frme 0
  96. # Variables used for printing/saving to
  97. # an output file
  98. variable dlg 0
  99. variable landscape 1
  100. variable maxpect 1
  101. variable decorations 0
  102. variable colormode color
  103. variable save_file 0
  104. # Printer info collected on unix
  105. variable current_printer {}
  106. variable printer_list {}
  107. variable default_printer {}
  108. # Output file name
  109. variable file_name {}
  110. namespace export sgraph
  111. }
  112. image create photo sgraph::viewout -data {
  113. R0lGODlhEAAQAIYAAPwCBHSi1ISu3Hym1HSizGSWxJS65LTW9OT2/Pz+/PT+
  114. /PT6/KTK5DxmjOz2/Oz+/Lzm/BxGdHSe1Lza9Nzq/FSKtIyy5Lze/KzW/AQy
  115. VLTW/KzS/LTS/JTC9MTq/MTi/KzK/KTG/KTC/Jy+/BQuRKzG/Jy6/JSy/Jy2
  116. /DRmpAQOHER6rJSy9Iym9GSK9FyKpIyCBDxypHSi3HyW/DxuxFxqfPT+dPzm
  117. bHRCBAQmPBxWlARGfMRyDOSiLNzCnOzCfIRKDMSGNOTGlIxODOzChIROBGyi
  118. 1MyORLRyFER6tAxSjJxeJGQ6BCQWBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  119. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  120. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  121. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAA
  122. LAAAAAAQABAAAAeggACCAQIDBAWCiYoABgcICQoLDA2LggYOCQkLmw8QEYsS
  123. E5mbCBQUEBWLFqObphcXGBmKAw6kFBcaGxwdsokBHh/BHBsgISIjvYIkIhMH
  124. GyUiJicoKSqLKxcc0CwtLS4vMJUxMiLcMzQ1Njc4lTk67zsqPD0+P+yVi0BB
  125. Qvb4i0NBiPwoIkGCERn+hhw5giTJCiU7/AEosoSJxEVNAPgJBAAh/mhDcmVh
  126. dGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAx
  127. OTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRl
  128. dmVsY29yLmNvbQA7
  129. }
  130. image create photo sgraph::viewin -data {
  131. R0lGODlhEAAQAIYAAPwCBHSi1Iyy5Hym3Hym1GSWxJS65Lza/OT2/Pz+/PT+
  132. /KTK5DxmlJS67PT6/Pz6/Lzm/BRGhHSe1MTe/OTy/Oz2/Mzm/NTq/FSKtJS2
  133. 7PT2/MTi/LTa/AQyVOTu/Lze/LTS/JTC9MTq/Mzi/KzK/KTC/KS+/BQuRJzG
  134. /KzO/LTO/KS6/Jy2/DRmpAQOHEx+rLTK/Jy+/Iym/Jyq/GSK/GSOrIyCBHSi
  135. 5HyW/DxuxFxqhPT+dPzqbHRCBAQmPBxenBxSjBxanARGfMRyDOymNOTCnPTG
  136. fIRKDMyGNOzGlISu7GSOzIROBPTGjJSy9EyGvIxODNSORMSWTLxyFDx6tBxe
  137. lKRiJGQ6BCQWBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  138. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  139. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAA
  140. LAAAAAAQABAAAAesgACCAQIDBAWCiYoABgcICQoJCwyLgg0OCQkPmgoQEYsS
  141. E5mYFBUWFxiLGZmbGhoWGxMcHYoDChoOFR4fByAcIbSJAyIXIxYgICQkJSbB
  142. gicovCkqJSssKy0uiy8bIDAxLDIzNDU2lS031TI4OTo7PD2VPj9AQUIuQ0RF
  143. RvGVi0dIkvATpGSJPwBMkDQxwkSCkyc3DkKJImUKlSdVhBxEaOUKACVVNgrC
  144. AsBPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0K
  145. qSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpo
  146. dHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
  147. }
  148. image create photo sgraph::viewall -data {
  149. R0lGODlhEAAQAIYAAISu5Iyy5Iyy7Hyu5Hyq7HSm5Gyi7GSe5GSe7GSi7ESa
  150. 7AQ2XAT+BLTa/JTK/Hy+/FSq/DSW/AyG/AR+/AR2/AR6/AQyVJS65Mze9MzW
  151. 9LTK9KTO/JzO9JzC/IzK9IS+9Iy27Fy2/PyipOwiLPQ2PPSutPz+/PT6/PT+
  152. /Pzu9PReZPwqNPxOTJy+5AQyXKTS/PSOlPwCBPwmLPTS1Oz+/Oz6/ORqdIS+
  153. 7AQ2ZOxyfPQmLPQiLOTK1OT+/OT6/KTC7PS6xPRyfOzu9OT2/NyyxOTy/OTq
  154. /ITC9Nzy/Nz2/NT2/ITG9KS+7NT6/NTy/Nz6/Oy6xORufMzy/NTi9JzO/PQq
  155. NOxufPwCDPSSnNTu/PQmNAQ2VPyirPSuvPxOXGSq5Iy+7IS67HzC9AQeNAAA
  156. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  157. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAwA
  158. LAAAAAAQABAAAAfsgAABAgMEBQYHCAcJBwYKCwwCDQ4PEBESExQVFROcFgwX
  159. GBkaGhscHR4fIB8dIZ8cIiMkJSYnJigpKissLS4MLzAxMjO1JzQ1NjErNzgM
  160. GzA5Ojs8PT4+OTE5KiCQPykmQEFCKEM1RDlFRke+LbU0ND1CQ0g+SUpKS59M
  161. KO/H80VKmjh54kGfEBpQcghJgkQJkShSpjz4RAVGkCojqDlRYuWKDRUAmnnA
  162. EmNajyxOpEhJpuXGll9cZJDo0mNIkScYdHn50OxLBzBhbngQM9QDgBs3Qvha
  163. 4AKHCxcWnlqwgKMqjjEMsmrdyjWrn0AAIf5oQ3JlYXRlZCBieSBCTVBUb0dJ
  164. RiBQcm8gdmVyc2lvbiAyLjUNCqkgRGV2ZWxDb3IgMTk5NywxOTk4LiBBbGwg
  165. cmlnaHRzIHJlc2VydmVkLg0KaHR0cDovL3d3dy5kZXZlbGNvci5jb20AOw==
  166. }
  167. image create photo sgraph::print -data {
  168. R0lGODlhEAAQAIYAAPwCBHSm/KzG/IS2/LTS/Pz+/Ozy/KS63Gye7ISu/Ozu
  169. /Pz6/OTm/JzC/ExmpKTG/PT2/Mze/NTi/NTm/OTq/CQ6dHyi/OTu/LzW/LzS
  170. /MTW/NTW/Nzu/HSO1MzK/LzC9LS69PT+/Mzi/LTO/CQ6ZPz29GRenFRKfKSi
  171. zNTq/MTa/HyS1Ly6/Pz2/Ly+zISKpFRShFRelDRGnNze/Ozq/JSSrGRijDQ2
  172. ZFxytJSOvJR2vEwufNzS/Hx+tLy+3GRqjGRmjNze7PTy/JR+1BwKLExWpLzW
  173. 9Iyi3ISGzJym/HyC/KTO5PT6/JSizFx6zKSm5ISS/IR+9CxSrERmtJSWzHyG
  174. /IyK9DQiTOT2/FyC3EQ2jHRerJyi/DQeTCw+dFyC1FyG5AQOJEQubAAAAAAA
  175. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  176. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAA
  177. LAAAAAAQABAAAAe7gACCgwABAgOEiYQEBQYHCIqECQoFlQsMDQ6RDwUQDBES
  178. ExQVihYLFxgZGhscHYkeHyAhIqoYESMkhB4lJicoHykqKiIrhCwFLS4vJDAx
  179. IBERMoQfMyULBTQ1Njc2ODk6O4I8Kjg9Gy3YPj9AQUJDRABFRipHMUgoQgUK
  180. DBtJSvBLKhVg0sRJjCczNiiBEoWIlCY0BHaaQsVDlSpWrgwisaISlixatnjg
  181. EqWLIi9fwIQRJEaMyUgwB/kJBAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBy
  182. byB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdo
  183. dHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
  184. }
  185. image create photo sgraph::saveas -data {
  186. R0lGODlhEAARAIUAAPwCBGRebFxaZOTm9OTi7ExWZPz+/NTS7MTC5Pz6/MS+
  187. 3Nza7Nza9LS21MzO5NTK5CwqLIR+tFxabLSu1Ozm9JSSxOTa5DQyPISCvBQW
  188. HAQCBIyKvFRSdOTu9GxmpHRyrHx+tBwaHOTe9Kyq1GxqpKSmzBwWHGRinHx6
  189. tFxenExKjFxanAwKFGxqjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  190. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABEAAAaR
  191. QIBwKAwQj0fBQIBEBggFg7EpFEANWGYzcAhgv1OiACEwJL5ZYkCBQHgTC8Zi
  192. 0a02FAIH+fA4zCEREgETDQIUAgcVARQWFBcYGBkaZBQMhxUbHB0QHh8ZQhoU
  193. FBOWEhggIR+eRBoHIhMUIwIfJKtHGiIUFSUmJyifTRojvCm2VBoZKisZHFRD
  194. GpHNzkMsLU0yQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9u
  195. IDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2
  196. ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
  197. }
  198. ################################################################
  199. # sgraph
  200. #
  201. # w : the name of the frame to be created - this frame
  202. # will contain the graph, buttons and the scroll-bars
  203. #
  204. # args: arguments to be used when the graph is being
  205. # created
  206. #
  207. # This routine wil overload the frame widget so all commands
  208. # sent to the frame will be passed to the graph widget.
  209. #
  210. ################################################################
  211. proc ::sgraph::sgraph { w args } {
  212. #
  213. # Increment the counter for the grph array
  214. #
  215. incr sgraph::grph_cnt
  216. #
  217. # Create a frame and a graph
  218. #
  219. frame $w
  220. set grph [eval blt::graph $w.realgraph $args]
  221. #
  222. # Create scrollbars and configure them to work with x and y axis
  223. #
  224. set scrllx [scrollbar $w.hs1 \
  225. -command [list $w.realgraph axis view x ] \
  226. -orient horizontal]
  227. set scrlly [scrollbar $w.vs1 \
  228. -command [list $w.realgraph axis view y] \
  229. -orient vertical]
  230. $grph axis configure x -scrollcommand [list $scrllx set]
  231. $grph axis configure y -scrollcommand [list $scrlly set]
  232. set sgraph::active_mode($sgraph::grph_cnt) " Active mode"
  233. set sgraph::text_frme [LabelFrame $w.infofrme -anchor w \
  234. -textvariable sgraph::active_mode($sgraph::grph_cnt) -side right]
  235. set frme [$sgraph::text_frme getframe]
  236. #
  237. # Create active buttons in a buttonbox
  238. #
  239. set bbox [ButtonBox $frme.bbox]
  240. $bbox add -image sgraph::viewin \
  241. -helptext "Zoom In by defining diagonal corners of a rectangle" \
  242. -command [list sgraph::ZoomIn $sgraph::grph_cnt]
  243. $bbox add -image sgraph::viewout \
  244. -helptext "Zoom Out by picking the center point of the new window" \
  245. -command [list sgraph::ZoomOut $sgraph::grph_cnt]
  246. $bbox add -image sgraph::viewall \
  247. -helptext "Display the full graph" \
  248. -command [list sgraph::ZoomAll $sgraph::grph_cnt]
  249. $bbox add -image sgraph::saveas \
  250. -helptext "Save to a file as PostScript or Metafile" \
  251. -command [list sgraph::SaveGraph $sgraph::grph_cnt]
  252. $bbox add -image sgraph::print \
  253. -helptext "Output the graph to a printer" \
  254. -command [list sgraph::PrintTheGraph $sgraph::grph_cnt]
  255. #
  256. # Grid the buttons, graph, and scrollbars
  257. #
  258. grid $bbox -sticky w
  259. grid $sgraph::text_frme -sticky w
  260. grid $grph $scrlly -sticky news
  261. grid $scrllx -sticky news
  262. #
  263. # Set for resizing the graph - row 1, column 0 will grow
  264. # if the window is enlarged.
  265. #
  266. grid columnconfigure $w 0 -weight 1
  267. grid rowconfigure $w 1 -weight 1
  268. #
  269. # Save the graph and graph count. Set flag that graph
  270. # graph was just created
  271. #
  272. set sgraph::first($sgraph::grph_cnt) 1
  273. set sgraph::grph($sgraph::grph_cnt) $grph
  274. set sgraph::curIndx $sgraph::grph_cnt
  275. set sgraph::curGraph $grph
  276. #
  277. # If unix, this will get the list of available printers
  278. # and the default printer
  279. #
  280. sgraph::InitializePrinter
  281. #
  282. # Keep the original frame widget command - won't be using
  283. #
  284. rename $w _$w
  285. #
  286. # Use the interpreter command aliases to take advantage of
  287. # the ability to add extra arguments to the command via
  288. # the alias. The following command will Send all frame
  289. # widget commands to the graph widget
  290. interp alias {} $w {} $grph
  291. #
  292. # Return the frame widget
  293. #
  294. return $w ; # like the original graph command
  295. }
  296. option add *zoomOutline.dashes 4
  297. option add *zoomOutline.lineWidth 2
  298. option add *zoomOutline.xor yes
  299. ################################################################
  300. # Allow the user to set the printer and PostScript options.
  301. ################################################################
  302. proc ::sgraph::SetPrinter { prntrNme } {
  303. set sgraph::current_printer $prntrNme
  304. }
  305. proc ::sgraph::SetLandscape { val } {
  306. set sgraph::landscape $val
  307. }
  308. proc ::sgraph::SetMaxpect { val } {
  309. set sgraph::maxpect $val
  310. }
  311. proc ::sgraph::SetDecorations { val } {
  312. set sgraph::decorations $val
  313. }
  314. proc ::sgraph::SetColormode { val } {
  315. if { $val != "color" && $val != "grayscale" } {
  316. tk_messageBox -message "Colormode of \"$val\" not valid: \
  317. \"color\" or \"grayscale\" are the valid values"
  318. return
  319. }
  320. set sgraph::colormode $val
  321. }
  322. ################################################################
  323. # Generate hardcopy of the graph with a flag whether to popup
  324. # the dialog to set the printer/PostScript options.
  325. ################################################################
  326. proc ::sgraph::Print { graph flg } {
  327. foreach { indx g } [array get sgraph::grph] {
  328. if { [string first $graph $g] > -1 } {
  329. sgraph::PrintTheGraph $indx $flg
  330. }
  331. }
  332. }
  333. ################################################################
  334. # Draw an outline of the rectangle that will define the area of
  335. # the graph to display
  336. ################################################################
  337. proc ::sgraph::Box { graph } {
  338. #
  339. # Sometimes a pick is not inside the data window and sets value to ""
  340. #
  341. if { ($sgraph::info($graph,A,x) == "") || \
  342. ($sgraph::info($graph,B,x) == "") } {
  343. return
  344. }
  345. #
  346. # Save the lower-left and upper-right coordinates of the window
  347. #
  348. if { $sgraph::info($graph,A,x) > $sgraph::info($graph,B,x) } {
  349. set x1 [$graph xaxis invtransform $sgraph::info($graph,B,x)]
  350. set y1 [$graph yaxis invtransform $sgraph::info($graph,B,y)]
  351. set x2 [$graph xaxis invtransform $sgraph::info($graph,A,x)]
  352. set y2 [$graph yaxis invtransform $sgraph::info($graph,A,y)]
  353. } else {
  354. set x1 [$graph xaxis invtransform $sgraph::info($graph,A,x)]
  355. set y1 [$graph yaxis invtransform $sgraph::info($graph,A,y)]
  356. set x2 [$graph xaxis invtransform $sgraph::info($graph,B,x)]
  357. set y2 [$graph yaxis invtransform $sgraph::info($graph,B,y)]
  358. }
  359. #
  360. # Draw the zoom outline
  361. #
  362. set coords { $x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1 }
  363. if { [$graph marker exists "zoomOutline"] } {
  364. $graph marker configure "zoomOutline" -coords $coords
  365. } else {
  366. set X [lindex [$graph xaxis use] 0]
  367. set Y [lindex [$graph yaxis use] 0]
  368. $graph marker create line -coords $coords -name "zoomOutline" \
  369. -mapx $X -mapy $Y
  370. set interval $sgraph::interval
  371. set id [after $interval [list sgraph::MarchingAnts $graph 0]]
  372. set sgraph::afterId $id
  373. }
  374. }
  375. ################################################################
  376. # Set up to display the marching ants for the box outline
  377. ################################################################
  378. proc ::sgraph::MarchingAnts { graph offset } {
  379. incr offset
  380. if { [$graph marker exists zoomOutline] } {
  381. $graph marker configure zoomOutline -dashoffset $offset
  382. set interval $sgraph::interval
  383. set id [after $interval [list sgraph::MarchingAnts $graph $offset]]
  384. set sgraph::afterId $id
  385. }
  386. }
  387. ################################################################
  388. # Add an event to the graph
  389. ################################################################
  390. proc ::sgraph::AddBindTag { graph name } {
  391. set oldtags [bindtags $graph]
  392. if { [lsearch $oldtags $name] < 0 } {
  393. bindtags $graph [concat $name $oldtags]
  394. }
  395. }
  396. ################################################################
  397. # Reset the display of the active mode to "Active Mode"
  398. ################################################################
  399. proc ::sgraph::ResetActiveMode {} {
  400. set sgraph::active_mode($sgraph::curIndx) " \"Active Mode\""
  401. sgraph::TurnOffActions
  402. }
  403. ################################################################
  404. # Turn off all actions and set the cursor to the crosshair
  405. ################################################################
  406. proc ::sgraph::TurnOffActions {} {
  407. #
  408. # Turn off all events
  409. #
  410. bind bltZoomGraph <ButtonPress-1> {}
  411. bind bltZoomGraph <ButtonRelease-1> {}
  412. bind $sgraph::curGraph <Motion> {}
  413. bind bltZoomOutGraph <ButtonPress-1> {}
  414. $sgraph::curGraph configure -cursor crosshair
  415. }
  416. ################################################################
  417. # Display the full graph
  418. ################################################################
  419. proc ::sgraph::ZoomAll { indx } {
  420. #
  421. # Check that the indx value is valid.
  422. #
  423. if { $indx < 0 || $indx >= [array size sgraph::grph] } {
  424. tk_messageBox \
  425. -message "Graph indx of $indx to sgraph::PrintTheGraph is out of range!"
  426. return
  427. }
  428. #
  429. # Check if have switched graphs -- if so, reset sgraph::active_mode
  430. # to let user know that no action is active on the graph just left.
  431. #
  432. if { $sgraph::curIndx != $indx } {
  433. sgraph::ResetActiveMode
  434. }
  435. #
  436. # Save the index to the currently active graph
  437. #
  438. set sgraph::curIndx $indx
  439. set sgraph::curGraph $sgraph::grph($indx)
  440. set sgraph::active_mode($sgraph::curIndx) \
  441. " \"Display full extents of graph\""
  442. #
  443. # Delete any part of the zoom outline
  444. #
  445. eval $sgraph::curGraph marker delete \
  446. [$sgraph::curGraph marker names "zoom*"]
  447. #
  448. # Turn off all events
  449. #
  450. sgraph::TurnOffActions
  451. #
  452. # Display the full extents of the graph
  453. #
  454. foreach axis { x y } {
  455. # puts "Autoscale the $axis axis"
  456. # puts "$axis limits : [$sgraph::curGraph axis limits $axis]"
  457. # puts "$axis min : [$sgraph::curGraph axis cget $axis -min]"
  458. # puts "$axis max : [$sgraph::curGraph axis cget $axis -max]"
  459. # puts "$axis stepsize : [$sgraph::curGraph axis cget $axis -stepsize]"
  460. # puts "$axis tickdivider: [$sgraph::curGraph axis cget $axis -tickdivider]"
  461. # puts "$axis majorticks : [$sgraph::curGraph axis cget $axis -majorticks]"
  462. # puts "$axis minorticks : [$sgraph::curGraph axis cget $axis -minorticks]"
  463. if { [catch { $sgraph::curGraph axis configure $axis -min {} -max {} } result] != 0 } {
  464. puts " ===> configure of $axis axis failed"
  465. }
  466. ## $sgraph::curGraph axis configure $axis -min {} -max {}
  467. ## $sgraph::curGraph axis configure $axis -min {} -max {}
  468. # puts "Done with the ZoomAll ... returning!"
  469. }
  470. }
  471. ################################################################
  472. # Process the pan/zoom
  473. ################################################################
  474. proc ::sgraph::ProcessZoom { graph } {
  475. #
  476. # Delete any part of the zoom outline
  477. #
  478. eval $graph marker delete [$graph marker names "zoom*"]
  479. if { [info exists sgraph::info($graph,afterId)] } {
  480. after cancel $sgraph::info($graph,afterId)
  481. }
  482. #
  483. # Get the corners of the zoom outline
  484. #
  485. set x1 $sgraph::info($graph,A,x)
  486. set y1 $sgraph::info($graph,A,y)
  487. set x2 $sgraph::info($graph,B,x)
  488. set y2 $sgraph::info($graph,B,y)
  489. if { ($x1 == $x2) || ($y1 == $y2) } {
  490. # No change so return
  491. return
  492. }
  493. #
  494. # The busy command provides a simple means to block keyboard,
  495. # button, and pointer events from Tk widgets, while overriding
  496. # the widget's cursor with a configurable busy cursor
  497. #
  498. blt::busy hold $graph
  499. # This update lets the busy cursor take effect.
  500. update
  501. #
  502. # Convert the (x,y) value to graph coordinates
  503. #
  504. set min [$graph axis invtransform x $x1]
  505. set max [$graph axis invtransform x $x2]
  506. if { $min == $max } {
  507. #
  508. # Zoom window too small - use the previous zoom
  509. # coordinates
  510. #
  511. set sgraph::info($graph,A,x) $sgraph::oldxA
  512. set sgraph::info($graph,A,y) $sgraph::oldyA
  513. set sgraph::info($graph,B,x) $sgraph::oldxB
  514. set sgraph::info($graph,B,y) $sgraph::oldyB
  515. blt::busy release $graph
  516. return
  517. }
  518. #
  519. # Check if the x-min is smaller than the defined extents
  520. #
  521. if { $min < $sgraph::grph_xmin($sgraph::curIndx) } {
  522. set min $sgraph::grph_xmin($sgraph::curIndx)
  523. set sgraph::info($graph,A,x) \
  524. [$graph axis transform x $min]
  525. }
  526. #
  527. # Check if the x-max is larger than the defined extents
  528. #
  529. if { $max > $sgraph::grph_xmax($sgraph::curIndx) } {
  530. set max $sgraph::grph_xmax($sgraph::curIndx)
  531. set sgraph::info($graph,B,x) \
  532. [$graph axis transform x $max]
  533. }
  534. #
  535. # Configure the x axis with new values
  536. #
  537. if { $min > $max } {
  538. $graph axis configure x -min $max -max $min
  539. } else {
  540. $graph axis configure x -min $min -max $max
  541. }
  542. #
  543. # Convert the (x,y) value to graph coordinates
  544. #
  545. set max [$graph axis invtransform y $y1]
  546. set min [$graph axis invtransform y $y2]
  547. if { $min == $max } {
  548. #
  549. # Zoom window too small - use the previous zoom
  550. # coordinates
  551. #
  552. set sgraph::info($graph,A,x) $sgraph::oldxA
  553. set sgraph::info($graph,A,y) $sgraph::oldyA
  554. set sgraph::info($graph,B,x) $sgraph::oldxB
  555. set sgraph::info($graph,B,y) $sgraph::oldyB
  556. blt::busy release $graph
  557. return
  558. }
  559. #
  560. # Check if the y-min is smaller than the defined extents
  561. #
  562. if { $min < $sgraph::grph_ymin($sgraph::curIndx) } {
  563. set min $sgraph::grph_ymin($sgraph::curIndx)
  564. set sgraph::info($graph,A,y) \
  565. [$graph axis transform y $min]
  566. }
  567. #
  568. # Check if the y-max is larger than the defined extents
  569. #
  570. if { $max > $sgraph::grph_ymax($sgraph::curIndx) } {
  571. set max $sgraph::grph_ymax($sgraph::curIndx)
  572. set sgraph::info($graph,B,y) \
  573. [$graph axis transform y $max]
  574. }
  575. #
  576. # Configure the y axis with new values
  577. #
  578. if { $min > $max } {
  579. $graph axis configure y -min $max -max $min
  580. } else {
  581. $graph axis configure y -min $min -max $max
  582. }
  583. # This "update" forces the graph to be redrawn
  584. update
  585. blt::busy release $graph
  586. #
  587. # Save the current zoom settings
  588. #
  589. set sgraph::oldxA $x1
  590. set sgraph::oldyA $y1
  591. set sgraph::oldxB $x2
  592. set sgraph::oldyB $y2
  593. }
  594. ################################################################
  595. # Get the coordinates
  596. ################################################################
  597. proc ::sgraph::GetCoords { graph x y index } {
  598. #
  599. # Save the screen coordinates for the mouse pick
  600. #
  601. if { [$graph cget -invertxy] } {
  602. set sgraph::info($graph,$index,x) $y
  603. set sgraph::info($graph,$index,y) $x
  604. } else {
  605. set sgraph::info($graph,$index,x) $x
  606. set sgraph::info($graph,$index,y) $y
  607. }
  608. }
  609. ################################################################
  610. # Zoom in on the graph
  611. ################################################################
  612. proc ::sgraph::ZoomIn {indx} {
  613. #
  614. # Check that the indx value is valid.
  615. #
  616. if { $indx < 0 || $indx >= [array size sgraph::grph] } {
  617. tk_messageBox -message "Graph indx of $indx to \
  618. sgraph::PrintTheGraph is out of range!"
  619. return
  620. }
  621. #
  622. # Check if have switched graphs -- if so, reset sgraph::active_mode
  623. # to let user know that no action is active on the graph just left.
  624. #
  625. if { $sgraph::curIndx != $indx } {
  626. sgraph::ResetActiveMode
  627. }
  628. #
  629. # Save the index to the currently active graph
  630. #
  631. set sgraph::curIndx $indx
  632. set sgraph::curGraph $sgraph::grph($indx)
  633. set sgraph::active_mode($sgraph::curIndx) \
  634. " \"Zoom In: MB1 drag MB1 to define rectangle\""
  635. update
  636. #
  637. # The first time this routine is called, save the extents of
  638. # the graph. These extents are used to stop the zooming out.
  639. #
  640. if { $sgraph::first($indx) } {
  641. #
  642. # Get the extents of the graph. A list of the minimum and maximum
  643. # limits for the axis is returned. The order of the list is min max.
  644. #
  645. set strg [$sgraph::curGraph axis limits x]
  646. scan $strg {%f %f} xmin xmax
  647. set strg [$sgraph::curGraph axis limits y]
  648. scan $strg {%f %f} ymin ymax
  649. if { $xmax == 0 && $ymax == 0 } {
  650. return
  651. }
  652. set wdth_adjx [expr { abs($xmax - $xmin) * 0.2 }]
  653. set hght_adjy [expr { abs($ymax - $ymin) * 0.2 }]
  654. set xmin [expr { $xmin - $wdth_adjx }]
  655. set ymin [expr { $ymin - $hght_adjy }]
  656. set xmax [expr { $xmax + $wdth_adjx }]
  657. set ymax [expr { $ymax + $hght_adjy }]
  658. set sgraph::grph_xmin($indx) $xmin
  659. set sgraph::grph_ymin($indx) $ymin
  660. set sgraph::grph_xmax($indx) $xmax
  661. set sgraph::grph_ymax($indx) $ymax
  662. set sgraph::first($indx) 0
  663. }
  664. sgraph::InitVars $sgraph::curGraph
  665. $sgraph::curGraph configure -cursor crosshair
  666. bind bltZoomOutGraph <ButtonRelease-1> {}
  667. bind bltZoomGraph <ButtonPress-1> { sgraph::SetZoomPoint %W %x %y 0 }
  668. bind bltZoomGraph <ButtonRelease-1> { sgraph::SetZoomPoint %W %x %y 0 }
  669. sgraph::AddBindTag $sgraph::curGraph bltZoomGraph
  670. }
  671. ################################################################
  672. # Zoom out on the graph
  673. ################################################################
  674. proc ::sgraph::ZoomOut { indx } {
  675. #
  676. # Check that the indx value is valid.
  677. #
  678. if { $indx < 0 || $indx >= [array size sgraph::grph] } {
  679. tk_messageBox -message "Graph indx of $indx to \
  680. sgraph::PrintTheGraph is out of range!"
  681. return
  682. }
  683. #
  684. # Check if have switched graphs -- if so, reset sgraph::active_mode
  685. # to let user know that no action is active on the graph just left.
  686. #
  687. if { $sgraph::curIndx != $indx } {
  688. sgraph::ResetActiveMode
  689. }
  690. #
  691. # Save the index to the currently active graph
  692. #
  693. set sgraph::curIndx $indx
  694. set sgraph::curGraph $sgraph::grph($indx)
  695. set sgraph::active_mode($sgraph::curIndx) " \"Zoom Out: MB1 on new center-point\""
  696. #
  697. # Delete any part of the marching ants rectangle for defining
  698. # a new zoom window
  699. #
  700. eval $sgraph::curGraph marker delete \
  701. [$sgraph::curGraph marker names "zoom*"]
  702. set sgraph::info($sgraph::curGraph,corner) "A"
  703. #
  704. # Turn off the actions for the zoom-in
  705. #
  706. bind bltZoomGraph <ButtonPress-1> {}
  707. bind bltZoomGraph <ButtonRelease-1> {}
  708. bind $sgraph::curGraph <Motion> {}
  709. $sgraph::curGraph configure -cursor center_ptr
  710. #
  711. # Set the actions for the zoom out
  712. #
  713. bind bltZoomOutGraph <ButtonRelease-1> { sgraph::SetZoomPoint %W %x %y 1 }
  714. sgraph::AddBindTag $sgraph::curGraph bltZoomOutGraph
  715. }
  716. ################################################################
  717. # Initialize the vars
  718. ################################################################
  719. proc ::sgraph::InitVars { graph } {
  720. set sgraph::interval 100
  721. set sgraph::afterId 0
  722. set sgraph::info($graph,A,x) {}
  723. set sgraph::info($graph,A,y) {}
  724. set sgraph::info($graph,B,x) {}
  725. set sgraph::info($graph,B,y) {}
  726. set sgraph::info($graph,stack) {}
  727. set sgraph::info($graph,corner) A
  728. }
  729. ################################################################
  730. # Calculate the new zoom window
  731. ################################################################
  732. proc ::sgraph::CalculateZoom { graph scalex scaley } {
  733. #
  734. # Lower-left corner
  735. #
  736. set xmid $sgraph::info($graph,A,x)
  737. set ymid $sgraph::info($graph,A,y)
  738. #
  739. # Change to graph coordinates
  740. #
  741. set xmid [$graph axis invtransform x $xmid]
  742. set ymid [$graph axis invtransform y $ymid]
  743. #
  744. # Get the current zoom x-window coordinates and
  745. # calculate the width
  746. #
  747. set xmin [$graph axis invtransform x $sgraph::oldxA]
  748. set xmax [$graph axis invtransform x $sgraph::oldxB]
  749. set curwidth [expr { abs($xmax - $xmin) }]
  750. #
  751. # Get the current zoom y-window coordinates and
  752. # calculate the height
  753. #
  754. set ymax [$graph axis invtransform y $sgraph::oldyA]
  755. set ymin [$graph axis invtransform y $sgraph::oldyB]
  756. set curheight [expr { abs($ymax - $ymin) }]
  757. #
  758. # Calculate the size of the new zoom window.
  759. #
  760. set xhalf [expr { $curwidth * $scalex }]
  761. set yhalf [expr { $curheight * $scaley }]
  762. set mnx [expr { ($xmid - $xhalf) }]
  763. set mny [expr { ($ymid + $yhalf) }]
  764. set mxx [expr { ($xmid + $xhalf) }]
  765. set mxy [expr { ($ymid - $yhalf) }]
  766. #
  767. # Save a screen coordinates
  768. #
  769. set sgraph::info($graph,A,x) [$graph axis transform x $mnx]
  770. set sgraph::info($graph,A,y) [$graph axis transform y $mny]
  771. set sgraph::info($graph,B,x) [$graph axis transform x $mxx]
  772. set sgraph::info($graph,B,y) [$graph axis transform y $mxy]
  773. }
  774. ################################################################
  775. ################################################################
  776. proc ::sgraph::SetZoomPoint { graph x y isZoomOut } {
  777. if { ![info exists sgraph::info($graph,corner)] } {
  778. sgraph::InitVars $graph
  779. }
  780. sgraph::GetCoords $graph $x $y $sgraph::info($graph,corner)
  781. #
  782. # Is this a zoom-out request?
  783. #
  784. if { $isZoomOut } {
  785. #
  786. # Calculate the new zoom coordinate for the graph
  787. #
  788. sgraph::CalculateZoom $graph 1.2 1.2
  789. #
  790. # Process the zoom request and redraw the graph
  791. #
  792. sgraph::ProcessZoom $graph
  793. return
  794. }
  795. #
  796. # Is this the first corner of the zoom-in request?
  797. #
  798. if { $sgraph::info($graph,corner) == "A" } {
  799. if { ![$graph inside $x $y] } {
  800. return
  801. }
  802. #
  803. # First corner selected, start watching motion events
  804. #
  805. bind $graph <Motion> {
  806. sgraph::GetCoords %W %x %y B
  807. sgraph::Box %W
  808. }
  809. set sgraph::info($graph,corner) B
  810. } else {
  811. #
  812. # The ButtonPress-1 and ButtonRelease-1 have been done.
  813. # Check if this is a zoom rectangle or a single point.
  814. # If single point, calculate the size of the zoom-in
  815. # window.
  816. #
  817. set x1 $sgraph::info($graph,A,x)
  818. set y1 $sgraph::info($graph,A,y)
  819. set x2 $sgraph::info($graph,B,x)
  820. set y2 $sgraph::info($graph,B,y)
  821. if { ([expr { abs ($x1 - $x2) }] < 5) && \
  822. ([expr { abs ($y1 - $y2) }] < 5) } {
  823. sgraph::CalculateZoom $graph 0.4 0.4
  824. }
  825. #
  826. # Delete the modal binding
  827. #
  828. bind $graph <Motion> { }
  829. #
  830. # Process the zoom request
  831. #
  832. sgraph::ProcessZoom $graph
  833. #
  834. # Reset to the first corner of a zoom-in
  835. #
  836. set sgraph::info($graph,corner) A
  837. }
  838. }
  839. ################################################################
  840. # Save the graph to a PostScript file without popping up the
  841. # file dialog.
  842. ################################################################
  843. proc ::sgraph::Save { graph psfilename} {
  844. set filename $psfilename
  845. foreach { indx g } [array get sgraph::grph] {
  846. if { [string first $graph $g] > -1 } {
  847. #
  848. # If the .ps extention isn't part of the file name, add
  849. #
  850. if { [string first ".ps" $filename ] < 0 } {
  851. set sgraph::file_name [format {%s%s} $filename \
  852. ".ps"]
  853. } else {
  854. set sgraph::file_name $filename
  855. }
  856. sgraph::CreatePS $indx 1 1 $sgraph::file_name
  857. }
  858. }
  859. }
  860. ################################################################
  861. # Save the graph to a Metafile file without popping up the
  862. # file dialog.
  863. ################################################################
  864. proc ::sgraph::SaveMetafile { graph mffilename} {
  865. set filename $mffilename
  866. foreach { indx g } [array get sgraph::grph] {
  867. if { [string first $graph $g] > -1 } {
  868. #
  869. # If the .emf extention isn't part of the file name, add
  870. #
  871. if { [string first ".emf" $filename ] < 0 } {
  872. set sgraph::file_name [format {%s%s} $filename \
  873. ".emf"]
  874. } else {
  875. set sgraph::file_name $filename
  876. }
  877. sgraph::CreatePS $indx 1 0 $sgraph::file_name
  878. }
  879. }
  880. }
  881. ################################################################
  882. # Save the graph to a PostScript file or a metafile (Windows
  883. # only)
  884. ################################################################
  885. proc ::sgraph::SaveGraph { indx } {
  886. #
  887. # Check that the indx value is valid.
  888. #
  889. if { $indx < 0 || $indx >= [array size sgraph::grph] } {
  890. tk_messageBox \
  891. -message "Graph indx of $indx to sgraph::PrintTheGraph is out of range!"
  892. return
  893. }
  894. #
  895. # Check if have switched graphs -- if so, reset sgraph::active_mode
  896. # to let user know that no action is active on the graph just left.
  897. #
  898. if { $sgraph::curIndx != $indx } {
  899. sgraph::ResetActiveMode
  900. }
  901. #
  902. # Save the index to the currently active graph
  903. #
  904. set sgraph::curIndx $indx
  905. set sgraph::curGraph $sgraph::grph($indx)
  906. set sgraph::active_mode($sgraph::curIndx) " \"Save the Graph\""
  907. #
  908. # Turn off the actions for the zoom-in
  909. #
  910. sgraph::TurnOffActions
  911. set sgraph::dlg [Dialog .dlg -parent . -modal local \
  912. -title "Save Graph to File"]
  913. $sgraph::dlg add -name cancel -text Cancel \
  914. -command sgraph::PopDownDlg
  915. $sgraph::dlg add -name saveps -text "Save PostScript" \
  916. -command [list sgraph::SaveToFile $sgraph::curIndx 1 PostScript]
  917. if { $::tcl_platform(platform) == "windows" } {
  918. $sgraph::dlg add -name savemeta -text "Save Metafile" \
  919. -command [list sgraph::SaveToFile $sgraph::curIndx 0 Metafile]
  920. }
  921. $sgraph::dlg draw
  922. }
  923. ################################################################
  924. # Process the PostScript options
  925. ################################################################
  926. proc ::sgraph::UpdatePsOptions { wdgt item } {
  927. set sgraph::$item [$wdgt cget -value]
  928. }
  929. proc ::sgraph::PopDownDlg {} {
  930. destroy $sgraph::dlg
  931. set sgraph::active_mode($sgraph::curIndx) " \"Active Mode\""
  932. }
  933. ################################################################
  934. # Save the PostScript output of the graph to a file
  935. ################################################################
  936. proc ::sgraph::SaveToFile { indx saveps type } {
  937. set pstypelist {{{PostScript files} {.ps} }
  938. {{All Files} * }
  939. }
  940. set metatypelist {{{Metafile files} {.emf} }
  941. {{All Files} * }
  942. }
  943. if { $saveps } {
  944. set typelist $pstypelist
  945. set ext ".ps"
  946. } else {
  947. set typelist $metatypelist
  948. set ext ".emf"
  949. }
  950. #
  951. # If first time, set the default directory to the
  952. # current directory. Otherwise, you the last
  953. # directory selected.
  954. #
  955. if { [string length $sgraph::file_name] < 1 } {
  956. set dir "."
  957. } else {
  958. set dir [file dirname $sgraph::file_name]
  959. }
  960. #
  961. # Request a file name for the PostScript file
  962. #
  963. set rtrn [tk_getSaveFile -filetypes $typelist \
  964. -initialdir $dir -title "Save as $type File" \
  965. -initialfile "out$ext"]
  966. if { $rtrn == "" } {
  967. set sgraph::save_file 0
  968. return 0
  969. }
  970. #
  971. # If the .ps extention isn't part of the file name, add
  972. #
  973. if { [string first $ext $rtrn ] < 0 } {
  974. set sgraph::file_name [format {%s%s} $rtrn \
  975. $ext]
  976. } else {
  977. set sgraph::file_name $rtrn
  978. }
  979. sgraph::CreatePS $indx 1 $saveps $sgraph::file_name
  980. sgraph::PopDownDlg
  981. return 1
  982. }
  983. ################################################################
  984. # Update the PostScript image. Save to a file as PostScript or
  985. # Metafile and send to a printer.
  986. ################################################################
  987. proc ::sgraph::CreatePS {indx savetofile {saveps 1} {filename "none"} } {
  988. #
  989. # Is it going to be color or grayscale?
  990. #
  991. if { [string equal $sgraph::colormode "grayscale"] } {
  992. set clrmode gray
  993. } else {
  994. set clrmode color
  995. }
  996. #
  997. # Configure the postscript options
  998. $sgraph::grph($indx) postscript configure \
  999. -colormode $clrmode \
  1000. -landscape $sgraph::landscape \
  1001. -maxpect $sgraph::maxpect \
  1002. -decorations $sgraph::decorations
  1003. #
  1004. # Save to a file?
  1005. #
  1006. if { $savetofile } {
  1007. if { $saveps } {
  1008. #
  1009. # Save a postscript file
  1010. #
  1011. $sgraph::grph($indx) postscript output $filename
  1012. } else {
  1013. #
  1014. # Save a metafile
  1015. #
  1016. $sgraph::grph($indx) snap -format emf $filename
  1017. }
  1018. puts stdout "wrote file \"$filename\"."
  1019. #
  1020. # Return since not sending to printer
  1021. #
  1022. return
  1023. }
  1024. if { $::tcl_platform(platform) == "windows" } {
  1025. #
  1026. # Draw directly to the print device - this may not
  1027. # work on all printers but quality is much better than
  1028. # using print1
  1029. #
  1030. $sgraph::grph($indx) print2
  1031. } else {
  1032. #
  1033. # Generate a PostScript file and send this to the selected
  1034. # printer. The file that is written is "out.ps".
  1035. #
  1036. $sgraph::grph($indx) postscript output "out.ps"
  1037. set cmd {lp -d$sgraph::current_printer out.ps}
  1038. eval exec $cmd
  1039. }
  1040. }
  1041. ################################################################
  1042. # Generate the hardcopy of the graph and delete the print
  1043. # options dialog
  1044. ################################################################
  1045. proc ::sgraph::CreatePSdestroyDlg {} {
  1046. sgraph::CreatePS $sgraph::curIndx 0
  1047. sgraph::PopDownDlg
  1048. }
  1049. ################################################################
  1050. # Popup the print options dialog
  1051. ################################################################
  1052. proc ::sgraph::PopupPrintOptions {} {
  1053. #
  1054. # Create the dialog
  1055. #
  1056. set sgraph::dlg [Dialog .dlg -parent . -modal local \
  1057. -title "Set Printer Information" ]
  1058. $sgraph::dlg add -name cancel -text Cancel \
  1059. -command sgraph::PopDownDlg
  1060. $sgraph::dlg add -name print -text Print \
  1061. -command sgraph::CreatePSdestroyDlg
  1062. if { $::tcl_platform(platform) != "windows" } {
  1063. set tpfrme [$sgraph::dlg getframe]
  1064. grid $tpfrme -sticky news
  1065. # ---------------------------------
  1066. # | Printer: |princess |v|
  1067. # ---------------------------------
  1068. #
  1069. set ptrfrme [frame $tpfrme.prntfrme \
  1070. -borderwidth 2]
  1071. set ptrlbl [label $ptrfrme.lbl -text "Printer:"]
  1072. set ptrlstbx [ComboBox $ptrfrme.lb \
  1073. -textvariable sgraph::current_printer \
  1074. -values $sgraph::printer_list \
  1075. -font {courier 12 bold}]
  1076. pack $ptrlbl $ptrlstbx -side left -expand yes -fill both
  1077. grid $ptrfrme -sticky news
  1078. #
  1079. # -PostScript Options---------------
  1080. # | landscape | o yes | o no |
  1081. # | maxpect | o yes | o no |
  1082. # | decorations | o yes | o no |
  1083. # | colormode | o yes | o no |
  1084. # ----------------------------------
  1085. #
  1086. set lblfrme [TitleFrame $tpfrme.leftf \
  1087. -text "PostScript Options" ]
  1088. set opfrme [$lblfrme getframe]
  1089. foreach bool { landscape maxpect decorations } {
  1090. set wl $opfrme.$bool-label
  1091. label $wl -text "$bool" -font *courier*-r-*12* \
  1092. -anchor w
  1093. set wy $opfrme.$bool-yes
  1094. radiobutton $wy -text "yes" -variable sgraph::$bool \
  1095. -value 1 -anchor w \
  1096. -command [list sgraph::UpdatePsOptions $wy $bool]
  1097. set wn $opfrme.$bool-no
  1098. radiobutton $wn -text "no" -variable sgraph::$bool \
  1099. -value 0 -anchor w \
  1100. -command [list sgraph::UpdatePsOptions $wn $bool]
  1101. grid $wl $wy $wn -sticky news
  1102. }
  1103. set wl [label $opfrme.modes -text "colormode" \
  1104. -font *courier*-r-*12* -anchor w]
  1105. foreach m { color grayscale } {
  1106. radiobutton $opfrme.$m -text $m -variable sgraph::colormode \
  1107. -value $m -anchor w \
  1108. -command [list sgraph::UpdatePsOptions $opfrme.$m colormode]
  1109. }
  1110. grid $wl $opfrme.color $opfrme.grayscale -sticky news
  1111. grid $lblfrme -pady 10 -sticky news
  1112. grid columnconfigure $tpfrme 0 -weight 1
  1113. }
  1114. $sgraph::dlg draw
  1115. }
  1116. ################################################################
  1117. # Generate hardcopy of the graph
  1118. ################################################################
  1119. proc ::sgraph::PrintTheGraph { indx {do_popups 1} } {
  1120. #
  1121. # Check that the indx value is valid.
  1122. #
  1123. if { $indx < 0 || $indx >= [array size sgraph::grph] } {
  1124. tk_messageBox \
  1125. -message "Graph indx of $indx to sgraph::PrintTheGraph is out of range!"
  1126. return
  1127. }
  1128. #
  1129. # Check if have switched graphs -- if so, reset sgraph::active_mode
  1130. # to let user know that no action is active on the graph just left.
  1131. #
  1132. if { $sgraph::curIndx != $indx } {
  1133. sgraph::ResetActiveMode
  1134. }
  1135. #
  1136. # Save the index to the currently active graph
  1137. #
  1138. set sgraph::curIndx $indx
  1139. set sgraph::curGraph $sgraph::grph($indx)
  1140. set sgraph::active_mode($sgraph::curIndx) " \"Print the Graph\""
  1141. sgraph::TurnOffActions
  1142. # Check if user wants the popup to define the printer and
  1143. # PostScript settings or to print with the defaults.
  1144. if { $do_popups } {
  1145. #
  1146. # Create the dialog
  1147. #
  1148. sgraph::PopupPrintOptions
  1149. } else {
  1150. sgraph::CreatePS $indx 0
  1151. }
  1152. }
  1153. ################################################################
  1154. # If this is unix, get a list of available printers.
  1155. ################################################################
  1156. proc ::sgraph::InitializePrinter {} {
  1157. if { $::tcl_platform(platform) == "windows" } {
  1158. return
  1159. }
  1160. # Try 'lpstat -a' to get a printer list
  1161. if { [catch {exec lpstat -a} result] == 0 } {
  1162. # if it worked, then parse printer names
  1163. foreach line [split $result "\n"] {
  1164. lappend sgraph::printer_list [lindex $line 0]
  1165. }
  1166. # get default printer from last word of 'lpstat -d'
  1167. catch {exec lpstat -d} result
  1168. set sgraph::default_printer [lindex [split $result " "] end]
  1169. set sgraph::current_printer $sgraph::default_printer
  1170. }
  1171. }
  1172. ################################################################
  1173. # Exit the application
  1174. ################################################################
  1175. proc ::sgraph::exit {} {
  1176. exit
  1177. }
  1178. ################################################################
  1179. # Standalone Testing Code
  1180. ################################################################
  1181. if { $::argv0 == [info script] } {
  1182. set auto_path [linsert $auto_path 0 /sppdg/software/tools/public_domain/lib]
  1183. set auto_path [linsert $auto_path 0 /sppdg/software/tools/public_domain/hpux11/lib]
  1184. if { $::tcl_platform(platform) == "windows" } {
  1185. console show
  1186. } else {
  1187. package require Console
  1188. toplevel .console
  1189. pack [console .console.t] -expand yes -fill both
  1190. wm protocol .console WM_DELETE_WINDOW {sgraph::exit}
  1191. }
  1192. # Create some data for the graphs
  1193. blt::vector create ::xan
  1194. blt::vector create ::xa
  1195. blt::vector create ::xb
  1196. blt::vector create ::y1a
  1197. blt::vector create ::y2a
  1198. blt::vector create ::y1b
  1199. blt::vector create ::y2b
  1200. xan seq 0 3000
  1201. xb seq 0 4000
  1202. xa expr { 0.1 * xan }
  1203. y1a expr { 0.4 * sin(3.14159 * xan * 0.004) }
  1204. y2a expr { cos(3.14159 * xan * 0.005) }
  1205. y1b expr { sin(3.14159 * xb * 0.003) }
  1206. y2b expr { 2 * cos(3.14159 * xb * 0.006) }
  1207. # Create a notebook widget, then two graph windows
  1208. set noteBk [blt::tabset .t -relief sunken -borderwidth 1]
  1209. set ::grph1 [sgraph::sgraph $noteBk.graph1 -relief sunken -borderwidth 5 \
  1210. -title "Test 1"]
  1211. set ::grph2 [sgraph::sgraph $noteBk.graph2]
  1212. $noteBk insert end graph1 -text "Test 1" -window $::grph1 -fill both
  1213. $noteBk insert end graph2 -text "Test 2" -window $::grph2 -fill both
  1214. # Add data to graphs
  1215. ##$::grph1 configure -title "Test 1"
  1216. $::grph2 configure -title "Test 2"
  1217. $::grph1 element create s1 -symbol "" \
  1218. -linewidth 2 -color blue -xdata ::xa -ydata ::y1a
  1219. $::grph1 element create s2 -symbol "" \
  1220. -linewidth 2 -color green -xdata ::xa -ydata ::y2a
  1221. $::grph2 element create s1 -symbol "" \
  1222. -linewidth 2 -color red -xdata ::xb -ydata ::y1b
  1223. $::grph2 element create s2 -symbol "" \
  1224. -linewidth 2 -color black -xdata ::xb -ydata ::y2b
  1225. # Setup the X-Axis data in GHz
  1226. $::grph1 configure -relief sunken
  1227. # Hide the Legend
  1228. #$::grph1 legend configure -hide yes
  1229. # Show the Grid
  1230. $::grph1 grid configure -hide no -color black
  1231. # Don't display a symbol for each data point
  1232. $::grph1 element configure s1 -symbol "" -color red -label "1"
  1233. $::grph1 xaxis configure -title "Frequency in GHz" -titlefont {courier 16}
  1234. $::grph1 element configure s2 -symbol "" -color blue -label "2"
  1235. set units "Amplitude in Measurement Units(MU)"
  1236. $::grph1 yaxis configure -title $units -titlefont {courier 16}
  1237. $::grph1 axis configure y -stepsize 60 -subdivisions 1
  1238. ## set startF [expr { $startFreq * double(1) } ]
  1239. set startF 0.0
  1240. ## set stopF [expr { $stopFreq * double(1) } ]
  1241. set stopF 200.0
  1242. # $::grph1 axis configure x -min $startF -max $stopFreq
  1243. $::grph1 axis configure x -min $startF -max $stopF
  1244. set stepSize [ expr { ($stopF - $startF) / 10 } ]
  1245. ## $::grph1 axis configure x -stepsize $stepSize -subdivisions 1
  1246. $::grph1 axis configure x -stepsize $stepSize -subdivisions 1
  1247. $::grph1 axis configure y -min -1 -max 1
  1248. # $::grph1xs axis configure y -majorticks {60 120 180 240 300 360 420 480 540}
  1249. $::grph1 marker create text -text "Marker" -coords { 100 100 } -name normalMarker
  1250. set units "Amplitude in "
  1251. $::grph1 yaxis configure -title $units -titlefont {courier 16}
  1252. Blt_ZoomStack $::grph1
  1253. pack $noteBk -side top -expand yes -fill both
  1254. ## sgraph::Print $::grph1 0
  1255. ## sgraph::Print $::grph2 1
  1256. }