sequence-diagram_1.1


Information

Created with NetLogo version NetLogo 4.0.4
Running with NetLogoLite.jar version 404.


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:
<a href="http://en.wikipedia.org/wiki/Sequence_diagrams"> http://en.wikipedia.org/wiki/Sequence_diagrams </a>

Procedures

NetLogo Version: NetLogo 4.0.4

;;;; 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

   

                    


Download Link

View or download the complete model file (to download: right-click, save-link-as):
-- Download sequence-diagram_1.1 --