;;;; 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
@#$#@#$#@