;;;; SUMMARY ;; A Model to input and dispay Sequence Diagrams ;;;; COPYRIGHT and LICENCE ;; Copyright (C) 2006/2009 James P. Steiner ;; This model is made available under a Creative Commons by-at-nc 2.5 license. ;; For more information visit CreativeCommons.org ;; ;; For more information about Sequence Diagrams, see: ;; http://en.wikipedia.org/wiki/Sequence_diagrams globals [ events-read old-scroll display-patches maxe mine maxt mint margin ] breed [ events event ] breed [ lines line ] events-own [ timestamp talker listener data row column1 column2 ] to startup setup end to setup ca clear-output input-data define-display-constants prepare-events-for-display output-diagram-headings display-events set old-scroll 9999 end to input-data let filename "sequence-diagram.dat" ; user-file if filename = "" or filename = false [ stop ] carefully [ ifelse file-exists? filename [ file-close-all file-open filename file-parse-file file-close ] [ stop ] ] [ stop ] end to file-parse-file let line# 0 ;carefully ;[ while [ not file-at-end? ] [ set line# line# + 1 file-parse-line file-read-line line# ] ;] ;[ report-error line# "unknown error reading file" ; file-close-all ; stop ;] set events-read line# output-print (word events-read " events read.") end to file-parse-line [ input line# ] let delim "->" let d-pos position delim input ifelse d-pos = false [ report-error line# (word delim " not found." ) ] [ ;; talker is digits up to the delimiter let talker' get-number-from input set input substring input (d-pos + 2) length input ;; get next number let listener' get-number-from input let data-pos position (word listener') input + length (word listener') let data' "" if data-pos != false [ set data' substring input data-pos (length input) ] create-events 1 [ set talker talker' set listener listener' set data data' set timestamp line# hide-turtle ] ] end to report-error [ line# text ] output-print (word line# " :: ERROR :: " text ) end to-report get-number-from [ string ] ;; reports the integer found at the beginning of string ;; e.g. "34hello" reports 34 let c "" let p 0 let result 0 let index 0 let digits "0123456789" set c (item index string) set p position c digits while [ p != false ] [ set result result * 10 + p set index index + 1 ifelse index < length string [ set c (item index string) set p position c digits ] [ set p false ] ] report result end to-report sign [ number ] report ifelse-value (number < 0) [ -1 ] [ ifelse-value (number > 0) [ 1 ] [ 0 ] ] end to define-display-constants ;; calculate max and min process numbers found in the data set mine min [ talker ] of events set mine min (list mine (min [ listener ] of events) ) set maxe max [ talker ] of events set maxe min (list maxe (max [ listener ] of events) ) ;; calculate max and min timestamps present in the data set maxt max [ timestamp ] of events set mint min [ timestamp ] of events set margin 5 end to prepare-events-for-display ;; precalculate some of the display characteristics ask events [ set column1 2 * (talker - mine) set row max-pycor - margin - ( 2 * ( timestamp - mint ) ) set column2 column1 + 2 * (listener - talker ) set heading 90 * sign (column2 - column1) set size .001 + 2 * abs (listener - talker ) ;; extra .001 added to prevent clipping of shape when size = 2 set shape "ray" set color blue set xcor column1 ] end to output-diagram-headings no-display clear-patches ask patches [ set pcolor white ] ask lines [ die ] set scroll 0 let heading-patches patches with [ pycor = max-pycor - margin + 2 and pxcor >= 0 and pxcor mod 2 = 0 and pxcor < max-pxcor - margin ] ask heading-patches [ ;; draw process number headings set plabel-color black set plabel mine + int (pxcor * .5 ) ;; draw vertical lines sprout 1 [ set breed lines set shape "line" set xcor pxcor - 1 set ycor min-pycor - .49 set heading 0 set size world-height set color gray ] ] ask patch (min-pxcor + margin + 5 ) (max-pycor - margin + 4) [ set plabel "PROCESS NUMBER" set plabel-color black ] ask patch ( min-pxcor + 2 + margin ) ( max-pycor - margin ) [ set plabel "TIMESTAMP" set plabel-color black ] end to display-events let slider scroll ask events with [ hidden? = false ] [ hide-turtle ] ask patches with [ pxcor = min-pxcor + margin - 2 and pycor < max-pycor - margin and pycor > min-pxcor + margin and pycor mod 2 = 0 ] [ if slider > events-read - 1 [ set slider events-read - 1] let ptimestamp int ((max-pycor - pycor - margin ) * .5) + slider ask patches with [ pycor = [pycor] of myself ] [ set pcolor white ] ask patch max-pxcor pycor [ set plabel "" ] set plabel "" if any? events with [ timestamp = ptimestamp ] [ set plabel ptimestamp set plabel-color black ask events with [ timestamp = ptimestamp ] [ set ycor [pycor] of myself ask patch column1 pycor [ set pcolor red ] ask patch column2 pycor [ set pcolor green ] ask patch max-pxcor pycor [ set plabel [data] of myself set plabel-color black ] show-turtle ] ] ] ask patch ( min-pxcor + margin - 2 ) ( min-pxcor + margin - 2 ) [ ifelse (word [plabel] of patch-at 0 -2) < (word events-read ) [ set plabel "VVV" set plabel-color black ] [ set plabel "" ] ] display end to monitor-slider every .1 [ if scroll != old-scroll [ display-events set old-scroll scroll display ] ] end @#$#@#$#@ GRAPHICS-WINDOW 10 90 508 609 -1 -1 8.0 1 10 1 1 1 0 1 1 1 -5 55 -5 55 1 1 1 ticks CC-WINDOW 5 623 566 718 Command Center 0 BUTTON 10 10 75 43 Reload setup NIL 1 T OBSERVER NIL NIL NIL NIL OUTPUT 85 10 245 43 12 SLIDER 85 50 505 81 Scroll Scroll 0 min (list 100 events-read) 0 1 1 NIL HORIZONTAL BUTTON 10 50 75 83 Active monitor-slider T 1 T OBSERVER NIL NIL NIL NIL TEXTBOX 255 10 557 45 Click Active to enable scrolling through the data.\nMove the slider \"Scroll\" to scroll the data display. 11 0.0 0 @#$#@#$#@ WHAT IS IT? ----------- This reads in a process communication log file and displays the results graphically as a sequence diagram. HOW IT WORKS ------------ Each entry in the log is used to create an "event" turtle that contains the information for that process communication. The display shows only the events that will fit in the window. A slider can be used to "move" the windows to show different areas of the data. EXTENDING THE MODEL ------------------- A routine could easily be added to generate an ASCII version of the full chart. Since each event / message record is a turtle, one can use the WITH clause to write queries against the events Examples: | events with [ talker = 3 and timestamp > 30 and timestamp < 50 ] | events with [ listener = 5 ] Add an event query feature to display subsets of the event data. SHORTCOMINGS ------------ It does not vertically connect events. It will not yet gracefully handle event sets with more than 25 processes (extra processes will wrap on the display, or perhaps cause a runtime error) FOR MORE INFORMATION -------------------- For more information about Sequence Diagrams, see: http://en.wikipedia.org/wiki/Sequence_diagrams @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 line true 0 Line -7500403 true 150 0 150 300 line half true 0 Line -7500403 true 150 0 150 150 link true 0 Line -7500403 true 150 0 150 300 link direction true 0 Line -7500403 true 150 150 30 225 Line -7500403 true 150 150 270 225 ray true 6 Line -13840069 true 150 150 150 -150 Polygon -13840069 true true 120 15 150 -45 180 15 @#$#@#$#@ NetLogo 4.0.4 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ default 0.0 -0.2 0 0.0 1.0 0.0 1 1.0 0.0 0.2 0 0.0 1.0 link direction true 0 Line -7500403 true 150 150 90 180 Line -7500403 true 150 150 210 180 @#$#@#$#@