[REBOL] Re: REBOL dynamic graph code problems and REBOL mindset
From: moliad::gmail::com at: 21-Feb-2008 17:19
hi john,
I love helping out on these simple (for me hehe) graphic problems, helping
others see just how rebol's internal graph engine really is.
so I put a little bit of time during break and thought I'd give you a push
in the right direction... :-)
here is a full application which has (If I understood your post correctly)
everything working. look at it, and feel free to ask anything that you are
not shure on why or how.
Note, there are MANY other ways to do this, faster and/or with less code,
but for your learning experience, I added (IMHO)just enough
REBOL-specificities to help you 'get it, without going all the way and
loosing you. one thing of note is the use of the 'any and 'all functions.
although not specifically needing here, this was a good case of showing how
to use them, and how they actually can be simpler than a slew of nested if
conditions ( 'either, within rebol, as you must know)
one comment I will add, is that series manipulation in rebol is very
different from other language. every series is mutable, and most series
operation are "in-place" meaning, they dont returns a new series, they
actualy modifiy the one you specify.
for blocks this gets a little confusing, and is probably the biggest thing
to get in rebol. once you 'get it, you'll see doors unfolding on how to use
rebol. the biggest thing to remember is that when you assign a block, you
are not assigning a copy of that block, but the same block over and over, so
to make sure copy it if that is really what you want (even when its an empty
block, shown in the plot-curve function below).
another big one is that the various series function (append, insert, find,
etc) have dual natures for block series. Many operations could logically
act on or with the block itself, OR its content. this is another thing
which must be 'gotten' or else you WILL pull your hair out... hell even
after almost a decade, it still bites you sometimes. hehe.
so, to solve the issue, REBOL implements a refinement which is named
consistantly over all functions which has a duality in meaning (with blocks
or others). the refinement is called '/ONLY . if you look at the code, you
will see that I use in some instances, and in others I dont'
for appending data, the difference is not trivial.
this example will illustrate better than words can:
a: [1 2 3]
b: [4 5 6]
append a b
== [1 2 3 4 5 6]
append/only a b
== [1 2 3 [4 5 6]]
so often, you'll use a master block like so:
c: []
append c a
append c b
== [[1 2 3][4 5 6]]
or using another (very practical) function
c: reduce [a b]
== [[1 2 3] [4 5 6]]
hope this helps you get started in a better position to tackle your actual
project :-D
-MAx
now, the script:
;-------------------------------------------------------------------------------------------------------
rebol [
title: "selective curve plot example"
author: "Maxim Olivier-Adlhoch"
date: 2008-02-21
]
; GLOBAL STORAGE OF CURVES
curves: []
visible-curves: []
curves-fx: []
graph-size: 1000x500
random/seed to-string now/precise
plot-curve: func [color /local data x plot][
data: copy []
i: 250
loop graph-size/x [append data i: i + ((random 9) - 5)]
plot: copy compose [pen (color) line]
x: 10
foreach y data [append plot as-pair x y x: x + 1 ]
return plot
]
toggle-curve: func [curve /local c][
; since this is a simple test.
; in a more complete script, you might want to have a proper
; data storage model.
;
; something like a block(list) of objects, which define each curve
; and its state... (color, points, visibility, scale, etc)
; you'd then iterate over this list and rebuild the list
any [
all [
c: find/only visible-curves curve
remove c
]
append/only visible-curves curve
]
refresh-graph
]
refresh-graph: has [curve] [
clear curves-fx
foreach curve visible-curves [
append curves-fx curve
]
show the_box
]
; pre-generate 3 curves
; we use the /only refinement to let append know that
; it should adds the block containing the curve data
; into the curves list, instead it its content.
append/only curves red-curve: plot-curve red 5
append/only curves green-curve: plot-curve green 5
append/only curves blue-curve: plot-curve blue 5
append/only visible-curves red-curve
append/only visible-curves green-curve
append/only visible-curves blue-curve
graph_view: layout [
the_box: box snow 1000x500 effect reduce ['draw curves-fx]
return
rstate: toggle on red [toggle-curve red-curve]
gstate: toggle on green [toggle-curve green-curve]
bstate: toggle on blue [toggle-curve blue-curve]
]
; we want the view to show the curves on startup
refresh-graph
view graph_view
;-------------------------------------------------------------------------------------------------------
On Thu, Feb 21, 2008 at 4:15 AM, John Shea <johnmacshea-gmail.com> wrote: