View in color | License | Download script | History |
30-Apr 18:08 UTC
[0.066] 20.17k
[0.066] 20.17k
graph-fx.rREBOL [
Title: "Graph functions"
Date: 21-Aug-2001/12:22:03+2:00
Version: 0.1.0
File: %graph-fx.r
Author: "Oldes"
Purpose: "Some functions for making graphs with 3D columns"
Comment: {This is not final version at all, there is still a lot of things to do!}
Email: %oldes--bigfoot--com
library: [
level: 'advanced
platform: none
type: 'tool
domain: 'GUI
tested-under: none
support: none
license: none
see-also: none
]
]
data: [
["1. row" 12 32 23]
["2. row" 3 12 11]
]
graph-size: 640x480
col-size: 10x10
col-color: 255.110.30
col-colors: [
255.210.30
255.110.30
200.210.30
200.110.30
180.110.50
80.255.100
200.210.100
255.190.50
100.210.100
50.255.150
]
zero-point: depth: rows: cols: 0
up-to: func[num limit][((to-integer num / limit) + 1) * limit ]
GetLimits: func[
"Returns minumum and maximum value from the table"
data "Block of rows with columns"
/local max min
][
if not block? data/1 [data: repend/only copy [] data]
max: min: either integer? data/1/1 [data/1/1][0]
foreach row data [
foreach col next row [
if number? col [
either col > max [max: col][if col < min [min: col]]
]
]
]
reduce [min max]
]
CountBlock: func[data [block!] /local counted][
counted: 0
foreach val next data [if number? val [counted: counted + val]]
counted
]
CountColumns: func[
"Counts all the columns values in rows"
data "Block of rows with columns"
/local counted
][
if not block? data/1 [data: append/only copy [] data]
counted: make block! length? data/1
foreach row data [
append counted CountBlock next row
]
counted
]
get-scale: func[
"Counts columns scale koeficient"
data "table data"
height "available height of the graph"
/counted-columns "If the columns will be counted"
/local max-value
][
probe max-value: last (GetLimits either counted-columns [CountColumns data][data])
probe up-to max-value 25
either max-value = 0 [1][height / up-to max-value 25]
]
MultiplyColumns: func[
"Multiplies all values in the table"
data "Block of rows with columns"
m
/local new-data new-row onerow?
][
onerow? false
if not block? data/1 [data: repend/only copy [] data onerow?: true]
new-data: make block! length? data
foreach row data [
new-row: make block! length? row
foreach col row [
insert tail new-row either number? col [to-integer (col * m)][ col ]
]
insert/only tail new-data new-row
]
either onerow? [new-data/1][new-data]
]
GetColumn: func[
"Returns draw parameters for 2d/3d column"
position "bottom (back if 3D) column position"
height width
/D3 "3-Dimensional"
/noedge
/local urb ulf drf drb urf ulb "Corner positions" b w2
][
w2: width / 2
urb: to-pair reduce [position/x + width position/y - height]
ulf: to-pair reduce [position/x - w2 position/y - height + w2]
drf: to-pair reduce [position/x + w2 position/y + w2]
drb: to-pair reduce [position/x + width position/y]
urf: to-pair reduce [drf/x ulf/y]
ulb: to-pair reduce [position/x urb/y]
compose either d3 [
[
pen (col-color - 100)
fill-pen (col-color) box (ulf) (drf)
fill-pen (col-color - 20) polygon (drf) (drb) (urb) (urf)
fill-pen (col-color + 20) polygon (ulf) (ulb) (urb) (urf)
line (ulf) (ulb) (urb) (urf)
line (drf) (drb) (urb)
]
][
either noedge [
[fill-pen (col-color) polygon (position)(drb)(urb)(ulb)]
][
[pen (col-color - 100) fill-pen (col-color) box (position) (urb)]
]
]
]
GetColumns: func[data /spacing sp /reversed-cols /local col-id c w pos columns][
columns: make block! []
position: make pair! zero-point
if not spacing [sp: 0]
if not block? data/1 [data: repend/only copy [] data]
w: col-size/x
depth: col-size/y
pos: make pair! position
r: 0
col-id: 1
foreach row data [
c: 0
col-color: col-colors/:col-id
col-id: either col-id = (length? col-colors) [1][col-id + 1]
if reversed-cols [row: head reverse row]
foreach col next row [
position/x: pos/x + (c * (sp + w))
position/y: pos/y + (r * (sp +( depth / 2)))
if number? col [
insert tail columns GetColumn/d3 position col w
]
c: c + 1
]
r: r + 1
pos/x: pos/x - (sp + w / 2)
]
columns
]
GetColumnsCounted: func[data /d3 /spacing sp /local col-id c y r w pos columns][
columns: make block! [draw]
position: make pair! zero-point
append/only columns copy []
corner: position
if not spacing [sp: 2]
if not block? data/1 [data: repend/only copy [] data]
w: col-size/x
pos: position
c: 0
while [c < (length? data/1 )][
c: c + 1
y: 0
r: 0
col-id: 1
foreach row data [
r: r + 1
col-color: col-colors/:col-id
col-id: either col-id = (length? col-colors) [1][col-id + 1]
position/y: pos/y - y - (r * sp)
insert tail columns/2 either d3 [
GetColumn/d3 position data/:r/:c w
][ GetColumn position data/:r/:c w ]
y: y + data/:r/:c
]
position/x: pos/x + (c * (sp + w))
]
insert head columns/2 (Get3Dgrid corner )
make face [
color: 242.242.242
size: graph-size
edge: make object! [color: 230.230.230 size: 0x0]
effect: columns
]
]
draw3Daxes: func[/local depth][
depth: (graph-size/y - zero-point/y)
c1: to-pair reduce [zero-point/x 0]
c2: to-pair reduce [cols * col-size/x + c1/x 0]
c3: to-pair reduce [c2/x zero-point/y]
c4: to-pair reduce [zero-point/x - depth zero-point/y + depth]
c5: to-pair reduce [c2/x - depth zero-point/y + depth]
make block! compose[
line (zero-point) (c1 ) ;y axis
line (zero-point) (c3 )
line (zero-point) (c4)
line (c1) (c2) (c3) (c5) (c4)
]
]
draw3Dguide: func[
/local draw-data i p1 p2 d2 d4 col-id
][
draw-data: copy []
i: 0
p1: zero-point
d2: col-size/y / 2
d4: d2 / 2
p1/x: p1/x - d4 + 2
p1/y: min graph-size/y p1/y + d4 + 1
p2: to-pair reduce [graph-size/x + 15 p1/y]
p3: to-pair reduce [p2/x size/y - (rows * 12) ]
p4: to-pair reduce [p2/x + (rows * 2) p3/y ]
col-id: 1
insert tail draw-data [font guideText]
foreach row data [
i: i + 1
col-color: col-colors/:col-id - 100
insert tail draw-data compose [
pen (col-color) line (p1) (p2) (p3) (p4)
line (p4 - 0x1) (p4 - 2x1)
fill-pen (col-colors/:col-id + 20)
box (p4 + 0x3) (p4 + 10x-7)
pen: 0.0.0
text (row/1) (p4 + 12x-8)
]
p1/x: max 0 zero-point/x - (i * d2) - d4 + 2
p1/y: min graph-size/y zero-point/y + (i * d2) + d4 + 1
p2/x: p2/x + 2
p2/y: p1/y
p3: p3 + 2x12
p4/y: p3/y
col-id: either col-id = (length? col-colors) [1][col-id + 1]
]
draw-data
]
draw3DhorizontalGrid: func[
/local draw-data p1
][
draw-data: copy []
p1: make pair! zero-point
for y 0 60 10 [
p1/y: p1/y - 20
p2: to-pair reduce [p1/x - depth p1/y + depth]
p3: to-pair reduce [p1/x + (cols * col-size/x) p1/y]
insert tail draw-data compose [
line (p2) (p1) (p3)
]
]
draw-data
]
draw3DBottomGrid: func[
data
/local colors column draw-data draw-position col-id
][
;column: [depth 60 width 10]
colors: [175.190.195 170.185.205]
col-id: 1
draw-data: copy []
draw-position: make pair! zero-point
foreach column-width data [
insert tail draw-data Get3DbottomColumn
draw-position ;position
column-width ;column width
depth ;column depth
colors/:col-id + 20 ;fill color
draw-position/x: draw-position/x + column-width
col-id: either col-id = (length? colors) [1][col-id + 1]
]
draw-data
]
draw3DWallGrid: func[
data
/local colors
][
colors: [175.190.195 170.185.205]
col-id: 1
draw-data: copy []
draw-pos: make pair! zero-point
foreach column-width data [
col-color: colors/:col-id
insert tail draw-data GetColumn/noedge draw-pos zero-point/y column-width
draw-pos/x: draw-pos/x + column-width
col-id: either col-id = (length? colors) [1][col-id + 1]
]
draw-data
]
Get3DbottomColumn: func[
pos width depth color /edge
/local d2 c1 c2 c3
][
d2: depth / 2
c1: to-pair reduce [(pos/x + width) pos/y]
c2: to-pair reduce [(pos/x + width - d2) pos/y + d2]
c3: to-pair reduce [(pos/x - d2) c2/y]
compose either edge [
[pen (color) line (pos) (c1) (c2) (c3)]
][ [fill-pen (color) polygon (pos) (c1) (c2) (c3)]]
]
graph: func[
table
facets [block!] ;[size 320x240 column 10x10]
/local graph-face
][
size: facets/size if none? size [size: 320x240]
graph-size: size
column: facets/column if none? column [column: 5x10]
col-size: column
rows: length? table
cols: -1 + length? table/1
;first i need to find the zero-point of the graph
zero-point: 0x0
zero-point/x: rows * (col-size/y / 2 ) + 10
zero-point/y: size/y - zero-point/x
;-----
depth: 2 * zero-point/x
guideText: make object! [
name: "arial"
style: none
size: 11
color: 0.0.0
offset: 2x2
space: 0x0
align: 'center
valign: 'center
shadow: none
]
probe sc: get-scale table (zero-point/y - 10)
data: MultiplyColumns table sc
data: sort/compare data func[a b][(CountBlock a) > (CountBlock b)]
week-grid: multiplyColumns week-grid col-size/x
eff: make block! [draw] append/only eff copy []
append eff/draw draw3DBottomGrid week-grid
append eff/draw draw3DWallGrid week-grid
append eff/draw draw3Daxes
append eff/draw draw3DhorizontalGrid
append eff/draw draw3Dguide
append eff/draw GetColumns data
graph-face: make face compose [
size: (size + 180x1)
edge: none
color: white
]
graph-face/effect: eff
graph-face
] Notes
|