Contents
Articles
Behaviors
Books
Director News
Director Web Sites
FAQ
Games
Mailing Lists
News Groups
Project Examples
Reviews
Software
Tools
Useful Web Sites
Utilities
Xtras

Don't miss these
Convert between bases-String to Integer
Script Database
Get browser versions
MP3 in Director
MediaPlayer Xtra
Scroll Text With Mouse
Update QT3 movies
Installer Vise
MediaMacros Devcon Presentation 2002 - Imaging Lingo
Pendulum Rotate-Alphamania
 

 

 

Behavior Graph Class

Added on 5/18/2004

 

Compatibilities:
D7 D8 D8_5 D9 Mac Parent PC Shockwave

This item has not yet been rated

Author: fluxus

A parent script for creating line graphs, bar graphs and pie charts with imaging lingo. Usefull for visualizing dynamic data e.g. from local or online databases. homepage: http://staff.dasdeck.de/valentin/lingo/graph/

Download PC Source
property pImg

property pXOffset
property pYOffset
property pW
property pH

property pLeftMarg
property pRightMarg
property pTopMarg
property pBottomMarg

property pMinY
property pMaxY

property pFont
property pFontsize
property pTextCol
property pshadeCol

----------------------------------------
-- PUBLIC METHODS
----------------------------------------

----------------------------------------
-- optional: bgCol=background-color of canvas, shadeCol=color of shades
----------------------------------------
on new (me, img, bgCol, shadeCol)
  if not ilk(bgCol)=#color then bgCol = rgb(255,255,255)
  
  pImg = img
  pImg.fill(pImg.rect, bgCol) -- clear
  
  -- defaults
  pXOffset = 0
  pYOffset = 0
  
  pW=pImg.width
  pH=pImg.height
  
  pMinY = 0
  pMaxY = 100
  
  pLeftMarg = 0
  pRightMarg = 0
  pTopMarg = 0
  pBottomMarg = 0
  
  pFont = "Courier New"
  pFontsize = 11
  pTextCol = rgb(0, 0, 0)
  
  if ilk(shadeCol)=#color then pshadeCol = shadeCol
  else pshadeCol = rgb(80,80,80)
  
  return me
end

----------------------------------------
-- set left and top coordinate of graph
----------------------------------------
on setOffset (me, x, y)
  pXOffset = x
  pYOffset = y
end

----------------------------------------
-- set width and height of graph
----------------------------------------
on setDimensions (me, w, h)
  pW = w
  pH = h
end

----------------------------------------
-- set left and right margin within graph
----------------------------------------
on setMarginsX (me, leftMarg, rightMarg)
  if leftMarg>0 then pLeftMarg = leftMarg
  if rightMarg>0 then pRightMarg = rightMarg
end

----------------------------------------
-- set top and bottom margin within graph
----------------------------------------
on setMarginsY (me, topMarg, bottomMarg)
  if topMarg>0 then pTopMarg = topMarg
  if bottomMarg>0 then pBottomMarg = bottomMarg
end

----------------------------------------
-- set visible range of values
----------------------------------------
on setRange (me, minY, maxY)
  pMinY = minY
  pMaxY = maxY
end

----------------------------------------
-- add box arround rect specified by offset and dimensions
----------------------------------------
on addBox (me)
  canvasRect = rect(pXOffset, pYOffset, pXOffset+pW, pYOffset+pH)
  pImg.draw(canvasRect, [#shapeType:#rect, #lineSize:1, #color: rgb(0, 0, 0)])
end

----------------------------------------
-- add title on top of graph
----------------------------------------
on addTitle (me, str, props) -- optional propList props: font, fontsize, color, fontstyle, antialias
  if voidP(props) then props=[:]
  
  tm = new (#text)
  tm.bgcolor = rgb(255,255,255)
  
  if voidP(props["font"]) then tm.font = pFont
  else tm.font = props["font"]
  
  if voidP(props["fontsize"]) then tm.fontsize = pFontsize
  else tm.fontsize = props["fontsize"]
  
  if voidP(props["color"]) then tm.color = pTextCol
  else tm.color = props["color"]
  
  if voidP(props["fontstyle"]) then tm.fontstyle = [#plain]
  else tm.fontstyle = props["fontstyle"]
  
  if (props["antialias"]=1) then
    tm.antiAliasThreshold = 0
    tm.antiAlias = TRUE
  else
    tm.antiAlias = FALSE
  end if
  
  tm.text = str
  img = tm.image
  p = tm.charPosToLoc(length(str)+1)
  x = pXOffset + pW/2 - p[1]/2
  y = pYOffset/2 - p[2]/2
  pImg.copyPixels(img, img.rect.offset(x,y), img.rect, [#ink: 36])
  
  tm.erase()
end

----------------------------------------
-- add title of x-axis
----------------------------------------
on addAxisTitleX (me, str, props) -- optional proplist props: font, fontsize, color, fontstyle, antialias
  if voidP(props) then props=[:]
  
  tm = new (#text)
  tm.bgcolor = rgb(255,255,255)
  
  if voidP(props["font"]) then tm.font = pFont
  else tm.font = props["font"]
  
  if voidP(props["fontsize"]) then tm.fontsize = pFontsize
  else tm.fontsize = props["fontsize"]
  
  if voidP(props["color"]) then tm.color = pTextCol
  else tm.color = props["color"]
  
  if voidP(props["fontstyle"]) then tm.fontstyle = [#plain]
  else tm.fontstyle = props["fontstyle"]
  
  if (props["antialias"]=1) then
    tm.antiAliasThreshold = 0
    tm.antiAlias = TRUE
  else
    tm.antiAlias = FALSE
  end if
  
  tm.text = str
  img = tm.image
  p = tm.charPosToLoc(length(str)+1)
  x = pXOffset + pW/2 - p[1]/2
  y = pYOffset + pH + 25
  pImg.copyPixels(img, img.rect.offset(x,y), img.rect, [#ink: 36])
  
  tm.erase()
end

----------------------------------------
-- add title of y-axis
----------------------------------------
on addAxisTitleY (me, str, props) -- optional proplist props: font, fontsize, color, fontstyle, antialias
  if voidP(props) then props=[:]
  
  tm = new (#text)
  tm.bgcolor = rgb(255,255,255)
  
  if voidP(props["font"]) then tm.font = pFont
  else tm.font = props["font"]
  
  if voidP(props["fontsize"]) then tm.fontsize = pFontsize
  else tm.fontsize = props["fontsize"]
  
  if voidP(props["color"]) then tm.color = pTextCol
  else tm.color = props["color"]
  
  if voidP(props["fontstyle"]) then tm.fontstyle = [#plain]
  else tm.fontstyle = props["fontstyle"]
  
  if (props["antialias"]=1) then
    tm.antiAliasThreshold = 0
    tm.antiAlias = TRUE
  else
    tm.antiAlias = FALSE
  end if
  
  tm.text = str
  
  tm.antiAliasThreshold = 10
  tm.antiAlias = TRUE
  
  
  p = tm.charPosToLoc(length(str)+1)
  tm.width = p[1]+1
  
  img = rotateImg(tm.image, PI*3/2)
  
  x = 10 --pXOffset + pW/2 - p[1]/2
  y = pYOffset + pH/2 - p[1]/2
  pImg.copyPixels(img, img.rect.offset(x,y), img.rect, [#ink: 36])
  
  tm.erase()
end

----------------------------------------
-- create grid, specified by number of horizontal and vertical sections (affected by margins)
----------------------------------------
on addGrid (me, cntX, cntY)
  if cntX >0 then
    dx=(pW-pLeftMarg-pRightMarg)/cntX
    
    von = (pLeftMarg=0)
    bis = cntX-(pRightMarg=0)
    repeat with i = von to bis
      x=pXOffset+pLeftMarg+i*dx
      pImg.draw(point(x,pYOffset), point(x,pYOffset+pH), [#shapeType:#line, #lineSize:1, #color: rgb(180,180,180)])
    end repeat
  end if
  
  if cntY>0 then
    dy=(pH-pTopMarg-pBottomMarg)/cntY
    von = (pTopMarg=0)
    bis = cntY-(pBottomMarg=0)
    repeat with i = von to bis
      --repeat with i = 1 to cntY-1
      y=pYOffset+pTopMarg+i*dy
      pImg.draw(point(pXOffset+1,y), point(pXOffset+pW-1,y), [#shapeType:#line, #lineSize:1, #color: rgb(180,180,180)])
    end repeat
  end if
end

----------------------------------------
-- add labels to x-axis (affected by margins)
----------------------------------------
on addLabelsX (me, labels)
  tm = new (#text)
  tm.bgcolor = rgb(255,255,255)
  
  tm.font = pFont
  tm.fontsize = pFontsize
  tm.color = pTextCol
  
  cnt=count(labels)
  dx=(pW-pLeftMarg-pRightMarg)/(cnt-1)
  y=pYOffset+pH+4
  repeat with i = 1 to cnt
    str=labels[i]
    tm.text = str
    img = tm.image
    p = tm.charPosToLoc(length(str)+1)
    x=pXOffset+pLeftMarg+(i-1)*dx - p[1]/2
    pImg.copyPixels(img, img.rect.offset(x,y), img.rect, [#ink: 36])
  end repeat
  
  tm.erase()
end

----------------------------------------
-- add labels to y-axis (affected by margins)
----------------------------------------
on addLabelsY (me, labels)
  tm = new (#text)
  tm.bgcolor = rgb(255,255,255)
  
  tm.font = pFont
  tm.fontsize = pFontsize
  tm.color = pTextCol
  
  cnt=count(labels)
  dy=(pH-pTopMarg-pBottomMarg)/(cnt-1)
  x=pXOffset-5
    
  repeat with i = 1 to cnt
    str=labels[cnt+1-i]
    tm.text = str
    img = tm.image
    p = tm.charPosToLoc(length(str)+1)
    
    y=pYOffset+pTopMarg+(i-1)*dy - p[2]/2
    pImg.copyPixels(img, img.rect.offset(x-p[1],y), img.rect, [#ink: 36])
  end repeat
  
  tm.erase()
end

----------------------------------------
-- add line with specified color to line-graph
----------------------------------------
on drawLines (me, data, aColor, props) -- optional proplist props: strokewidth, shade, shadeoffset, blur
  if voidP(props) then props=[:]
  
  cnt=count(data)
  w = pW-pLeftMarg-pRightMarg
  h = pH - pTopMarg - pBottomMarg
  dx = w/(cnt-1)
  
  scaleY = float(h)/(pMaxY-pMinY)
  
  l=[]  
  repeat with i = 0 to cnt-1
    x=i*dx
    y=(h-data[i+1])*scaleY
    l.add([#vertex: point(x,y)])
  end repeat
  
  vm = new (#vectorShape)  
  vm.vertexList = l
  vm.backgroundcolor = rgb(255, 255, 255)
  
  if voidP(props["strokewidth"]) then sw = 1
  else sw = props["strokewidth"]
  vm.strokeWidth = sw
  
  -- add shade
  if (props["shade"]) then
    vm.strokeColor = pshadeCol
    
    if voidP(props["shadeoffset"]) then shadeOffset = 1
    else shadeOffset = props["shadeoffset"]
    
    blur = props["blur"]
    if blur then img=blur(vm.image,blur,1)
    pImg.copyPixels(img, vm.image.rect.offset(pXOffset+pLeftMarg+shadeOffset,pYOffset+pTopMarg-sw+shadeOffset), vm.image.rect, [#ink: 39])
  end if
  
  -- add line
  vm.strokeColor = aColor
  
  pImg.copyPixels(vm.image, vm.image.rect.offset(pXOffset+pLeftMarg,pYOffset+pTopMarg-sw), vm.image.rect, [#ink: 36])
  
  vm.erase()
end

----------------------------------------
-- add bars with specified values, color, width and offset to bar-graph
----------------------------------------
on drawBar (me, data, aColor, barWidth, horOffset, props) -- optional proplist props: linesize, shade, shadeoffset, blur
  if voidP(props) then props=[:]
  
  if voidP(barWidth) then barWidth=15
  if voidP(horOffset) then horOffset=0
  
  cnt = count(data)
  --w = pW-pLeftMarg-pRightMarg
  h = pH - pTopMarg - pBottomMarg
  
  scaleY = float(h)/(pMaxY-pMinY)
  
  dx = (pW-pLeftMarg-pRightMarg)/(cnt-1)
  y0 = pYOffset+pH-pBottomMarg
  
  if voidP(props["linesize"]) then ls = 1
  else ls = props["linesize"]
  
  if (props["shade"]) then
    if voidP(props["shadeoffset"]) then shadeOffset = 2
    else shadeOffset = props["shadeoffset"]
    blur = props["blur"]
  end if
  
  l=[]
  repeat with i = 0 to cnt-1
    x=pXOffset+pLeftMarg+i*dx+horOffset
    y=y0 - (data[i+1]-pMinY)*scaleY
    if y      
      -- add shade
      if (props["shade"]) then
        if voidP(props["shadeoffset"]) then shadeOffset = 2
        else shadeOffset = props["shadeoffset"]
        
        if blur then
          img=image(barWidth+10,y0-y,24)
          img.fill(5,shadeOffset,barWidth+5,y0-y, [#shapeType: #rect, #lineSize: 0, #color: pshadeCol, #bgColor: rgb(0, 0, 0)])
          img=blur(img,blur,1)
          pImg.copyPixels(img, rect(x+shadeOffset-5,y,x+barWidth+shadeOffset+5,y0),img.rect,[#ink: 39]) --+shadeOffset-5
        else
          pImg.fill(x+shadeOffset,y+shadeOffset,x+barWidth+shadeOffset,y0, [#shapeType: #rect, #lineSize: 0, #color: pshadeCol, #bgColor: rgb(0, 0, 0)])
        end if
      end if
      
      pImg.fill(x,y,x+barWidth,y0-(ls=0), [#shapeType: #rect, #lineSize: ls, #color: aColor, #bgColor: rgb(0, 0, 0)])
    else
      
      -- add shade
      if (props["shade"]) then
        if voidP(props["shadeoffset"]) then shadeOffset = 2
        else shadeOffset = props["shadeoffset"]
        
        if blur then
          img=image(barWidth+10,y-y0+shadeOffset+5,24)
          img.fill(5,0,barWidth+5,y-y0+shadeOffset+5, [#shapeType: #rect, #lineSize: 0, #color: pshadeCol, #bgColor: rgb(0, 0, 0)])
          img=blur(img,blur,1)
          pImg.copyPixels(img, rect(x+shadeOffset-5,y0,x+barWidth+shadeOffset+5,y+shadeOffset),img.rect,[#ink: 39])
        else
          pImg.fill(x+shadeOffset,y0,x+barWidth+shadeOffset,y+shadeOffset, [#shapeType: #rect, #lineSize: 0, #color: pshadeCol, #bgColor: rgb(0, 0, 0)])
        end if
      end if
      
      pImg.fill(x,y0-(ls>0),x+barWidth,y, [#shapeType: #rect, #lineSize: ls, #color: aColor, #bgColor: rgb(0, 0, 0)])
    end if
  end repeat
end

----------------------------------------
-- draw pie for specified values, labels and colors
----------------------------------------
on drawPie (me, data, aLabelList, aColorList, props) -- optional proplist props: linesize, shade, shadeoffset, blur
  
  -- normalize to 2*PI = 100%
  sum=0
  repeat with d in data
    sum=sum+d
  end repeat
  data = data * 2*PI/sum
  
  if voidP(props["linesize"]) then ls = 1
  else ls = props["linesize"]
  
  img=image(pW,pH,24)
  
  w=pW-pLeftMarg-pRightMarg
  h=pH-pTopMarg-pBottomMarg
  cx=w/2
  cy=h/2
  
  if (props["shade"]) then
    if voidP(props["shadeoffset"]) then shadeOffset = 2
    else shadeOffset = props["shadeoffset"]
    blur = props["blur"]
    if blur then
      sImg=image(w+2*blur,h+2*blur,24)
      sImg.fill(blur,blur,w+blur,h+blur,[#shapeType: #oval, #lineSize: 0, #color: pshadeCol])
      sImg=blur(sImg,blur,1)
      pImg.copyPixels(sImg,sImg.rect.offset(pXOffset+pLeftMarg+shadeOffset-blur,pYOffset+pTopMarg+shadeOffset-blur),sImg.rect)
    else
      pImg.fill(pXOffset+shadeOffset,pYOffset+shadeOffset,pXoffset+pW+shadeOffset,pYOffset+pH+shadeOffset,[#shapeType: #oval, #lineSize: 0, #color: pshadeCol])
    end if
  end if
  
  
  -- draw circle
  img.draw(0,0,w,h,[#shapeType: #oval, #lineSize: ls, #color: rgb(0,0,0)])
  
  
  -- paint arcs
  a = PI
  cnt = count(data)
  
  repeat with i = 1 to cnt
    img.draw(cx,cy,cx+cx*sin(a),cy+cy*cos(a),[#shapeType: #line, #lineSize: ls, #color: rgb(0,0,0)])
    img.floodfill(cx+cx*.9*sin(a+5),cy+cy*.9*cos(a+5),aColorList[i])
    a=a-data[i]
  end repeat
  
  pImg.copyPixels(img,img.rect.offset(pXOffset+pLeftMarg,pYOffset+pTopMarg),img.rect,[#ink:36])
  
  -- addLabels
  tm = new (#text)
  tm.bgcolor = rgb(255,255,255)
  
  tm.font = pFont
  tm.fontsize = pFontsize
  tm.color = pTextCol
  
  repeat with i = 1 to cnt
    x=325
    y=50+15*(i-1)
    
    y=250-10-15*(cnt-i)
    
    pImg.fill(x,y,x+10,y+10, [#shapeType: #rect, #lineSize: 1, #color: aColorList[i], #bgColor: rgb(0, 0, 0)])
    
    tm.text = aLabelList[i]
    img = tm.image
    p = tm.charPosToLoc(1)
    
    pImg.copyPixels(img, img.rect.offset(x+15,y+4-p[2]/2), img.rect, [#ink: 36])
  end repeat
  
  tm.erase()
  
end

----------------------------------------
-- PRIVATE UTILITIES
----------------------------------------

----------------------------------------
-- rotate image
----------------------------------------
on rotateImg img, deg --, tws
  --deg = (pi()/180) * deg
  
  p1 = point((img.rect.width/2.0), (img.rect.height)/2.0)
  laenge = sqrt(float(p1[1] * p1[1]) + float(p1[2] * p1[2]))
  
  rad = deg + atan(float(p1[2]),float(p1[1]))
  newP1 = point((cos(rad) * laenge),(sin(rad) * laenge))
  newP3 = newP1 * -1
  
  p2 = p1 * point(1, -1)
  
  rad = deg + atan(float(p2[2]),float(p2[1]))
  newP2 = point((cos(rad) * laenge),(sin(rad) * laenge))
  newP4 = newP2 * -1
  
  breite = max(abs(newP1[1]), abs(newP2[1]))
  hoehe = max(abs(newP1[2]), abs(newP2[2]))
  
  offs = point(breite, hoehe)
  newP1 = newP1 + offs
  newP2 = newP2 + offs
  newP3 = newP3 + offs
  newP4 = newP4 + offs
  
  temp = image(breite * 2, hoehe * 2, img.depth, 0)
  temp.copyPixels(img, [newP3, newP2, newP1, newP4], img.rect)
  --if tws then return temp.trimwhitespace()
  --else
  return temp
end

----------------------------------------
-- blur image
----------------------------------------
on blur (startImg, repetitions, doCrop)
  img = startImg
  repeat with i = 1 to repetitions
    img=_blur(img, doCrop)
  end repeat
  return img
end

----------------------------------------
  -- ACTION : apply a 5x5 convolution matrix and return the resulting image
  -- INPUTS : startImg : #image, the image on which to do the 5x5 blur
  --          doCrop {optional} : #boolean, choose if the new image is
  --          the same size as the original one (TRUE) or bigger
  --          (FALSE by default)
  -- RETURN : #image if everything's all right
  --          VOID if startImg is not an image
----------------------------------------
on _blur (startImg, doCrop)
  -- 1 - check input
  if (ilk(startImg) <> #image) then return VOID
  
  -- 2 - initialization
  buffer  = image( startImg.width+4, startImg.height+4, 24 )
  myRect  = rect( 0, 0, startImg.width, startImg.height )
  
  -- 3.1 - declaration of offset & blend lists
  offsetL = [[4,4],[4,0],[0,4],[0,0],[3,4],[3,0],[1,4],[4,3],[4,1],[0,3],[1,0],[0,1],[2,0],[2,4],[0,2],[4,2],[3,3],[1,1],[3,1],[1,3],[3,2],[1,2],[2,3],[2,1],[2,2]]
  blendLL = [0,0,0,0,3,3,3,3,3,3,3,3,10,10,10,10,16,16,16,16,26,26,26,26,26]
  
  -- 3.2 - blur
  repeat with j = 1 to 25 -- = offsetL.count
    myBlend = blendLL[j] * 1.8
    -- 1.8 = luminosity correction, from 1.5 to 5
    if not myBlend then next repeat
    
    destRect = myRect.offset(offsetL[j][1], offsetL[j][2])
    buffer.copyPixels(startImg, destRect, myRect, [#blendLevel : myBlend])
  end repeat
  
  -- 4 - return the result
  if doCrop then
    -- crop the results
    return buffer.duplicate().crop(myRect.offset(2, 2))
  else
    -- do not crop
    return buffer.duplicate()
  end if
  
end

 


Contact

MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA

Send e-mail