How to create interactive chart with Rebol - event-handling

I have this code to create a candlestick chart in rebol. Now I'd like to use over feel http://www.rebol.com/how-to/feel.html#section-6 to show info on each candlestick but my box is drawn with draw dialect and it doesn't seem to accept event ?
plot: [
pen green line 5x404 5x440 pen gold fill-pen 0.255.0 box 3x424 7x418 line 10x396 10x422 pen gold fill-pen 0.255.0 box 8x418 12x402 line 15x397 15x436 pen gold fill-pen 255.0.0 box 13x401 17x435 line 20x429 20x447 pen gold fill-pen 255.0.0 box 18x434 22x446 line 25x441 25x464 pen gold fill-pen 255.0.0 box 23x446 27x463 line 30x445 30x493 pen gold fill-pen 255.0.0 box 28x461 32x482 line 35x470 35x504 pen gold fill-pen 255.0.0 box 33x481 37x492 line 40x466 40x498 pen gold fill-pen 0.255.0 box 38x491 42x477
]
grid: [1100 600]
step-grid: 5
max-n-points: (grid/1 / step-grid) - 1
x-axis-border: 20
Y-margin: 10
X0: 5
grid-color: coal
main: layout [
origin 20x0
space 1x1
panel1: box 1100x580 black effect reduce [
'line-pattern 4 4
'grid 30x30 0x0 (grid-color)
'draw plot
]
panel2: box 1100x0 black
panel3: box 1100x20 black
]
view main

Here is a little expansion of my previous answer related to your chart viewer.
there are many ways you may adapt it, but it should give you some ideas into solving your problem.
rebol []
plot: []
data: reduce [ ]
refresh: func [/local clr delta prev-pos pos] [
clear plot
prev-pos: 0x300
foreach [clr delta] data [
pos: prev-pos + (delta * 0x1) + 7x0
append plot compose [
pen (clr) line (prev-pos) (pos) fill-pen (clr) pen none circle dot-size (pos)
]
prev-pos: pos
]
show panel1
]
add-data: func [i][loop i [append data reduce [(random white * .85) + (white * .15) (-20 + random 40)]] refresh]
grid: [800 600]
step-grid: 5
max-n-points: (grid/1 / step-grid) - 1
x-axis-border: 20
Y-margin: 10
X0: 5
grid-color: coal
dot-size: 3
viewer-size: 800x580
; open up console before vid window
main: layout [
origin 20x0
space 1x1
field 800
panel1: box viewer-size black rate 30 effect [
line-pattern 4 4
grid 30x30 0x0 grid-color
draw plot
] feel [
;probe first panel1
over: func [face over? offset /local d][
panel1/pane: either over? [info-pane][none]
if over? [
d: offset/x - face/offset/x - 1
d: (to-integer d / 7) * 2 + 1
either d: pick data d [
info-box/text: to-string d
][
panel1/pane: none
]
]
]
engage: func [face action event] [
switch action [
down [
drag-start: event/offset
]
up [
drag-end: event/offset
scroll-size: to-integer abs ((pick (drag-start - drag-end) 1) / 5)
]
time [
info-box/offset: event/offset - 20x20 ; the offset is the main-window origin
show main
]
]
]
]
panel2: box 800x0 black
panel3: box 800x20 black
]
insert-event-func [
either all [
event/type = 'key
none? system/view/focal-face
][
print ["shortcut: " event/key]
switch event/key [
; escape
#"^[" [quit]
; enter/return
#"^M" [print "resampling data" clear data add-data 100]
up [dot-size: dot-size + 1 show panel1]
down [dot-size: dot-size - 1 show panel1]
left [clear skip tail plot -12 clear skip tail data -2 show panel1]
right [add-data 2]
]
none
][
event
]
]
info-box: make face [
offset: 0x0
color: white * .2
size: 150x30
text: "0.0.0"
font: make font [valign: 'middle style: [bold italic]]
]
info-pane: reduce [info-box]
add-data 100
refresh
view/options main [all-over]
focus panel1
Note that as we move the mouse over the chart, we are only using the X component of the mouse to figure out what to display. Better systems are obvious, but this is sufficient to illustrate what needs to be done to receive all mouse move events and act on them.
Also note that the over feel receives Window offsets, so you must remove the face's offset to get the real face-relative coordinates.
PS: The red arrow above, is my mouse cursor.

Related

How to loop in NetLogo?

I have the following problem. I need to loop through the code. However, it doesn't work.
Contextualizing the problem: I have 3 files (in .asc) that represent data referring to 3 ages of the turtles (age 2, age 4 and age 8). I would like if the user puts the value 1 in num-user, it would only do the simulation with only one file (L_2) that would represent [ "2" ] ; if the user puts the value 2 in num-user, he would do the simulation with the files (L_2 and L_4) that would represent [ "2" "4" ] and finally, if the user puts the value 3 in num-use, it would simulate the files (L_2 , L_4 and L_8) that would represent [ "2" "4" "8" ]. The problem is that the loop is not working and gives various errors. Like:
Extension exception: ascii file ./L_8.asc not found or Can't find element 3 of the list [2 4 8], which is only of length 3 or go runs more than 3 simulations.
I was unable to attach the .ascii files here in the question. But if anyone can look at the code and identify the error I would be very grateful. I can't use BehaviouSpace to solve the situation, I need this loop in the code.
Thanks in advance!
extensions [ gis ]
globals [ num turtle-ages num-ages files random-seeds num-user repetitions ]
to setup
ca
set random-seeds 1
random-seed random-seeds
set num 0
set turtle-ages [ "2" "4" "8" ]
set num-ages item num turtle-ages
setup-asc
setup-turtles
reset-ticks
end
to setup-2
clear
random-seed random-seeds
set num-ages item num turtle-ages
setup-asc
setup-turtles
reset-ticks
end
to setup-turtles
ask n-of 5 patches [ sprout 1 ]
end
to clear
set files 0
clear-ticks
clear-turtles
end
to setup-asc
let number1 num-ages
set files gis:load-dataset ( word "./L_" number1 ".asc" ) ;; this loads a one raster file. There are 3 files in the folder with the names: (L_2.asc ; L_4.asc and L_8.asc
end
to go
move
tick
let n count turtles
if n = 0 or ticks = 10
[
set random-seeds random-seeds + 1
set repetitions 1
if random-seeds = repetitions + 1
[
set random-seeds 1
set num num + 1
;; if the user puts the value 1 in num-user, it would only do the simulation with only one file (L_2) that would represent [ "2" ]
;;; if the user puts the value 2 in num-user, he would do the simulation with the files (L_2 and L_4) that would represent [ "2" "4" ]
;;;; and finally, if the user puts the value 3 in num-use, it would simulate the files (L_2 , L_4 and L_8) that would represent [ "2" "4" "8" ]
set num-user 1 ;;
if num = num-user [ stop ]
]
setup-2
]
end
to move
ask turtles [
right random 360
fd 1
if ticks = 5 [ die ]
]
end
Whenever possible, I'd suggest paring down your code to a MRE to a) make sure that users here can run your code (without your files, for example, this is not really viable) and b) to see if reframing your question / goals in simpler terms would help get things working- at least that's what works for me!
I think that you might find foreach useful here as a way to loop through your desired simulations instead of manually tracking the number of iterations. For this example, assuming num-user is a numeric input widget on the interface, the setup below will determine which of the ages to process:
globals [ ages-to-run ]
to base-setup
ca
; Determine how many simulations to run, based on user input into
; 'num-user' numerical input widget on the interface
ifelse num-user < 1 or num-user > 3 [
print "Incorrect number of simulations indicated"
] [
let possible-sims [ "2" "4" "8" ]
set ages-to-run sublist possible-sims 0 num-user
]
reset-ticks
end
After running the above, the ages-to-run variable will contain ["2"], ["2" "4"], or ["2" "4" "8"]. Next, you can iterate over those desired ages to run your simulations (a little more detail in comments):
to run-simulations
if ages-to-run = 0 [
print "Simulation setup not complete"
]
foreach ages-to-run [
; This is the loop proper where each "age" is iterated.
; All of your simulation calls (manual variable resetting,
; etc) should all go within this loop.
current-age ->
print word "Running simulations for age: " current-age
let file-to-load ( word "./L_" current-age ".asc" )
print file-to-load
clear-turtles
ask n-of 5 patches [
sprout 1 [
pd
set color runresult current-age + 55
]
]
repeat 20 [
ask turtles [
rt random 60 - 30
fd 1
]
tick
]
print ( word "Simulations complete for age: " current-age "\n" )
]
end
Running that code above with 3 entered into num-user will run a simulation for each age (different colors indicate different runs):
So to run simulations proper, all your per-age code should go within that foreach loop indicated above- and be careful, as you were in your question, to not reset global variables.

Storing a value

A classroom is simulated where appliances (e.g lights Fans and ACs) turn on when a student sits next to it. Each appliance has its own wattage rating. When an appliance is turned on its color changes to green and the on-time is noted and the duration on-time is stored. But if a student sits next to a appliance (e.g light) that is already on. The duration-on-time should not be stored as it would be a repetition.
globals[
simulation-timer
to appliance-on
ask students [ ask lights in-radius 4
[ifelse not already-on?
[ set color green
set light-on-time ticks
set light-on-duration light-on-duration + (time - ticks)
show (word "light on duration = " light-on-duration)
set already-on? true] [
set light-on-duration light-on-duration]]]
In this code the light-on-duration is not adding for all of the lights. Only individual light-on-duration is shown. How should I fix this? Thank you!
I think you have a logic problem rather than a coding problem. You can't add to duration when the light turns on because it hasn't yet built up any duration. Here is a complete model that turns lights on and off and stores duration. I am using ticks as the time, and each tick it adds 5 students and removes 5 students. But what's important is the logic of turning the lights on and off.
globals [light-radius]
breed [students student]
students-own
[ desk
]
breed [lights light]
lights-own
[ on?
turned-on
duration-on
]
to setup
clear-all
set light-radius 3
ask patches [ set pcolor white ]
ask patches with [pxcor mod 3 = 0 and pycor mod 3 = 0]
[ sprout-lights 1
[ set size 0
set on? false
set pcolor gray
]
]
reset-ticks
ask n-of 30 patches
[ sprout-students 1
[ set color blue
]
ask lights in-radius light-radius [switch-light-on]
]
end
to go
repeat 5 [student-arrive]
repeat 5 [student-leave]
ask lights with [any? students in-radius light-radius]
[ switch-light-on
]
tick
end
to student-arrive
ask one-of patches with [not any? students-here]
[ sprout-students 1
[ set color blue
ask lights in-radius light-radius with [not on?]
[ switch-light-on
]
]
]
end
to switch-light-on
set pcolor yellow
set on? true
set turned-on ticks
end
to student-leave
ask one-of students
[ die
]
ask lights with [ on? and not any? students in-radius light-radius ]
[ switch-light-off
]
end
to switch-light-off
set pcolor gray
set on? false
type "previous duration: " print duration-on
let how-long ticks + 1 - turned-on
set duration-on duration-on + how-long
type "new duration: " print duration-on
end
Note that you can't actually see the light turtles, I am making the patch turn yellow for on and grey for off. Every third patch has a light.

Creating the game Snake on Netogo

I have to create the game snake on Netlogo, with specific instructions on how the snake has to move, as below:
"The snake moves by adding a square to its head and simultaneously deleting a square from the tip of its tail."
I believe that I have successfully managed to fulfill this condition, however, when taking a sharp turn everything falls apart, due to lines 105-110. The issue is that I can't seem to figure out how to specify which body segment has to become the tail in the next step.
ask heads [
if (count heads-here + count mice-here = 2) [
if heading = 0 [
hatch-heads 1 [
setxy xcor (ycor + 1)
;;and so on for all 4 directions
ask heads [
if heading = 0 [
hatch-heads 1 [
setxy xcor (ycor + 1)
;; and so on for all 4 directions
ask bodies [if (
count bodies-on neighbors4) + (
count heads-on neighbors4) + (
count tails-on neighbors4) < 2 [
set breed tails
set shape "square"]]
;; the above segment is where I believe the problem lies
I am hoping for the last "body" segment on the snake to turn into the breed "tail".

How do I make turtle face in an organized manner like the "cro" command but in turtle context?

I am trying to make a turret that will fire 8 bullets in 8 directions. In the command I have, they all spawn with heading 0 how do I make them face the right direction. Each turtle should face in a multiple of 45. Just like it would with the cro command in observer context.
to fire-tacks
ask ttacks with [alive?] [
set attackSpeed attackSpeed + .5
if any? turtles with [is-bloon?] in-radius 5 and attackSpeed >= 12
[set attackSpeed 0
hatch-btacks 8 [set alive? false set is-turret? false
set size 1 set damage 1 set color black set is-dart? true set bullet-
speed 4
]]]
end
You could use range and foreach to do this (check the links for more detail on how they work). range can generate a sequence of the headings you would like, and foreach can iterate over that sequence to sprout new turtles with each heading. Have a look at this simplified example:
breed [ turrets turret ]
breed [ btacks btack ]
to setup
ca
create-turrets 1 [
setxy random-xcor random-ycor
]
reset-ticks
end
to go
ask turrets [
foreach ( range 0 360 45 ) [
new_heading ->
hatch-btacks 1 [
set heading new_heading
fd 1
]
]
]
end

Controlling lives of turtles in NetLogo

For a project, I'm developping a simulation in NetLogo dealing with rabies diseases in dogs and humans. I have some turtles-humans with dogs that can be vaccinated or not. At the beginning I create a dog with rabie and, in according to the fase (1 or 2) of the disease, it can spread the disease to other dogs with a probability. At the end the dog can die either for paralysis (if a probability is higher than 75%) or for other complications. Here's the code:
http://pastebin.com/esR75G3T
In the end you can see that a dog not dying for paralysis will die after some days (between 4 or 6). In other words when the days_infected are equal to end-life.
To check if everything is ok at the beginning I tried to set that NONE of the dog is vaccinated so everyone is supposed to get the disease. In fact when the dog is in phase 2 it will bite anyone. The problem is that if I delete the last line of the code, everything works and some dogs die of paralysis and the other remain alive. If I enable also the last line to let the other dogs die too, nothing works...no dog is infected. why?
This is not a problem with your code: this is a problem with the dynamics of your model. What's happening is that your initial sick dog dies before actually infecting another dog. This is why removing the if (days_infected = end-life) [die] "fixes" the problem.
When I tried your model with a huge population (e.g., 5000 people) so that encounters are more frequent, the infection does spread. You could also increase the probability of infection, or increase the duration of the "furious" phase, I guess.
Another unrelated suggestion, if I may: you should have distinct persons and dogs breeds. Trying to cram everything inside regular turtles makes your code much more complicated than it should be. The way I would approach this would be to create a link from the person to her dog, and then use tie so that the dog is automatically moved when you move the person.
Edit:
OK, here is a version of your code slightly modified to use breeds:
globals [
total_dogs_infected
total_dogs
dead_humans
dead_dogs
]
breed [ persons person ]
persons-own [
sick?
]
breed [ dogs dog ]
dogs-own [
sick?
vaccinated?
rabies_phase
days_infected
end-incubator
end-furious
end-life
]
to setup
clear-all
initialize-globals
setup-turtles
reset-ticks
end
to initialize-globals
set dead_humans 0
set dead_dogs 0
set total_dogs_infected 0
end
to setup-turtles
set-default-shape persons "person"
set-default-shape dogs "wolf"
create-persons people [
setxy random-xcor random-ycor
set size 1.5
set sick? false
ifelse random 100 < 43 [
set color green
hatch-dogs 1 [
set color brown
set heading 115 fd 1
create-link-from myself [ tie ]
set days_infected 0
set vaccinated? (random 100 > %_not_vaccinated)
if not vaccinated? [ set color orange ]
]
]
[
set color blue ;umano sano senza cane
]
]
set total_dogs count dogs
ask one-of dogs [ get_sick ]
end
to get_sick
set sick? true
set color white
set rabies_phase 1
set end-incubator 14 + random 57
set end-furious (end-incubator + random 5)
set end-life (end-furious + 4 + random 2)
set total_dogs_infected total_dogs_infected + 1
end
to go
move
infect
get-older-sick-dog
tick
end
to move
ask persons [
rt random 180
lt random 180
fd 1
]
end
to infect
ask dogs with [ sick? ] [
if (rabies_phase = 1 and (random 100) <= 2) or rabies_phase = 2 [
ask other dogs-here with [ not sick? and not vaccinated? ] [ get_sick ]
]
]
end
to get-older-sick-dog
ask dogs with [ sick? ] [
set days_infected days_infected + 1
;the incubator phase ends after at least 14 days + random(57) and then we have phase 2 (furious)
if (days_infected = end-incubator) [ set rabies_phase 2 ]
;when the main furious phase finishes we have 75% of probability that a secondary furious phase continues for other 4 - 6 days until death ;or we have a probability of 25% that the disease end in paralysis with a fast death
if (days_infected = end-furious and (random 100 > 75)) [
set dead_dogs dead_dogs + 1
die
]
if (days_infected = end-life) [
die
]
]
end
; These last reporters are not used,
; they just illustrate how to get the
; dog from the owner or vice-versa:
to-report my-dog ; person reporter
report one-of out-link-neighbors
end
to-report has-dog? ; person reporter
report any? out-link-neighbors
end
to-report my-owner ; dog reporter
report one-of in-link-neighbors
end
Not only does it simplify some expressions (e.g., ask dogs with [ sick? ] instead of ask turtles with [ has_dog? and sick_dog? ]), it opens up all sorts of possibilities: a dog could run away from its owner, the owner could die without the dog dying, an owner could have two dogs, etc.