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/
----------------------------------------
-- 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)
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)
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
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
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
----------------------------------------
-- 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
-- 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
-- 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