Skip to content

Instantly share code, notes, and snippets.

@devilstower
Created January 27, 2012 05:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devilstower/1687108 to your computer and use it in GitHub Desktop.
Save devilstower/1687108 to your computer and use it in GitHub Desktop.
TrendGrahics 1.3
DataSeries = class()
function DataSeries:init(name, length, min, max, symbol, symbolsize, thick, clr)
    self.name = name
    self.symbol = symbol
    self.symbolsize = symbolsize
    self.nextpt = 0
    self.length = length
    self.lineclr = clr
    self.linethick = thick
    self.points = {}
    self.min = min
    self.max = max
    print(name, thick)
end
function DataSeries:addValue(y)
    self.nextpt = self.nextpt + 1
    if self.nextpt > self.length then
        self.nextpt = 1
    end
    self.points[self.nextpt] = vec2(i, y)
end
function DataSeries:draw(frame)
    local ox, oy, w, h, x, y, p
    stroke(self.lineclr)
    strokeWidth(self.linethick)
    w = frame.x2 - frame.x1
    h = frame.y2 - frame.y1
    dx = w / (self.length + 1)
    dy = h / (self.max - self.min)
    pushMatrix()
    translate(frame.x1, frame.y1)
    clip(frame.x1, frame.y1, w, h)
    ox = 0
    x = 0
   -- print(dx,dy)
    for i = self.nextpt + 1, self.length do
        x = x + dx
        p = self.points[i]
        if p ~= nil then
            y = (p.y - self.min) * dy
            if ox > 0 then
                line(ox,oy,x,y)
            end
            ox = x
            oy = y
            if self.symbol == 1 then
                noFill()
                ellipse(x, y, self.symbolsize)
            end
        end
    end
    for i = 1, self.nextpt do
        x = x + dx
        p = self.points[i]
        if p ~= nil then
            y = (p.y - self.min) * dy
            if ox > 0 then
                line(ox,oy,x,y)
            end
            ox = x
            oy = y
            if self.symbol == 1 then
                noFill()
                ellipse(x, y, self.symbolsize)
            end
        end
    end
    popMatrix()
    noClip()
end
Frame = class()
-- Frame 
-- ver. 1.0
-- a simple rectangle for holding controls.
-- ====================
function Frame:init(x1, y1, x2, y2)
    self.x1 = x1
    self.x2 = x2
    self.y1 = y1
    self.y2 = y2
end
function Frame:inset(dx, dy)
    self.x1 = self.x1 + dx
    self.x2 = self.x2 - dx
    self.y1 = self.y1 + dy
    self.y2 = self.y2 - dy
end
function Frame:offset(dx, dy)
    self.x1 = self.x1 + dx
    self.x2 = self.x2 + dx
    self.y1 = self.y1 + dy
    self.y2 = self.y2 + dy
end
    
function Frame:draw()
    pushStyle()
    rectMode(CORNERS)
    rect(self.x1, self.y1, self.x2, self.y2)
    popStyle()
end
function Frame:gloss(baseclr)
    local i, t, r, g, b, y
    pushStyle()
    if baseclr == nil then baseclr = color(194, 194, 194, 255) end
    fill(baseclr)
    rectMode(CORNERS)
    rect(self.x1, self.y1, self.x2, self.y2)
    r = baseclr.r
    g = baseclr.g
    b = baseclr.b
    for i = 1 , self:height() / 2 do
        r = r - 1
        g = g - 1
        b = b - 1
        stroke(r, g, b, 255)
        y = (self.y1 + self.y2) / 2
        line(self.x1, y + i, self.x2, y + i)
        line(self.x1, y - i, self.x2, y - i)
    end
    popStyle()
end
function Frame:shade(base, step)
    pushStyle()
    strokeWidth(1)
    for y = self.y1, self.y2 do
        i = self.y2 - y
        stroke(base - i * step, base - i * step, base - i * step, 255)
        line(self.x1, y, self.x2, y)
    end
    popStyle()
end
function Frame:touched(touch)
    if touch.x >= self.x1 and touch.x <= self.x2 then
        if touch.y >= self.y1 and touch.y <= self.y2 then
            return true
        end
    end
    return false
end
function Frame:ptIn(x, y)
    if x >= self.x1 and x <= self.x2 then
        if y >= self.y1 and y <= self.y2 then
            return true
        end
    end
    return false
end
function Frame:width()
    return self.x2 - self.x1
end
function Frame:height()
    return self.y2 - self.y1
end
function Frame:midx()
    return (self.x1 + self.x2) / 2
end
    
function Frame:midy()
    return (self.y1 + self.y2) / 2
end
IndicatorLight = class()
function IndicatorLight:init(x1, y1, x2, y2, flagmin, flagmax)
    self.frame = Frame(x1, y1, x2, y2)
    self.max = flagmax
    self.min = flagmin
end
function IndicatorLight:draw(val)
    pushStyle()
    noStroke()
    fill(167, 124, 80, 255)
    
    ellipse(self.frame:midx(), self.frame:midy(), self.frame:width())
    if val > self.max or val < self.min then
        fill(255, 26, 0, 255)
    else
        fill(50, 85, 53, 255)
    end
    ellipse(self.frame:midx(), self.frame:midy(), self.frame:width()-5)
    popStyle()
end
-- TrendGraph real time charting examples
function setup()
    local w
    displayMode(FULLSCREEN)
    supportedOrientations(PORTRAIT)
    textAlign(CENTER)
    w = WIDTH / 3
    g = TrendGraph(10, 270, WIDTH-10, 500, "Gravity")
    g:addSeries("X", 100, -1, 1, 0, 0, 2, color(255, 0, 0,255))
    g:addSeries("Y", 100, -1, 1, 0, 0, 2, color(0,128,0,255))
    g:addSeries("Z", 100, -1, 1, 0, 0, 2, color(0,0,255,255))
    gx = RoundGauge(50, 50, 250, 250, -1, 1, "Gravity X")
    gy = RoundGauge(WIDTH / 2 - 100, 50, WIDTH /2 + 100, 250, 
    -1, 1, "Gravity Y")
    gz = RoundGauge(WIDTH - 250, 50, WIDTH - 50, 250, 
    -1, 1, "Gravity Z")
    
    a = TrendGraph(10, 770, WIDTH-10, 1000, "Acceleration")
    a:addSeries("X", 100, -1, 1, 0, 0, 2, color(255, 0, 0,255))
    a:addSeries("Y", 100, -1, 1, 0, 0, 2, color(0,128,0,255))
    a:addSeries("Z", 100, -1, 1, 0, 0, 2, color(0,0,255,255))
    ax = RoundGauge(50, 550, 250, 750, -1, 1, "Acceleration X")
    ay = RoundGauge(WIDTH / 2 - 100, 550, WIDTH /2 + 100, 750, 
    -1, 1, "Acceleration Y")
    az = RoundGauge(WIDTH - 250, 550, WIDTH - 50, 750, 
    -1, 1, "Acceleration Z")
    ilx = IndicatorLight(135, 70, 165, 100, -0.9, 0.9)
    ily = IndicatorLight(WIDTH/2-15, 70, WIDTH/2+15, 100, -0.9, 0.9)
    ilz = IndicatorLight(WIDTH-165, 70, WIDTH-135, 100, -0.9, 0.9)
end
function draw()
    
    noSmooth()
    background(0, 0, 0)
    g:draw()
    gy:draw()
    gz:draw()
    a:draw()
    ax:draw()
    ay:draw()
    az:draw()
    g.series[1]:addValue(Gravity.x)
    g.series[2]:addValue(Gravity.y)
    g.series[3]:addValue(Gravity.z)
    
    stroke(255, 192, 0, 255)
    line(10, HEIGHT/2, WIDTH-10, HEIGHT/2)
    a.series[1]:addValue(UserAcceleration.x)
    a.series[2]:addValue(UserAcceleration.y)
    a.series[3]:addValue(UserAcceleration.z)
    
    gx.value = Gravity.x
    gx:draw()
    gy.value = Gravity.y
    gy:draw()
    gz.value = Gravity.z
    gz:draw()
    ax.value = UserAcceleration.x
    ax:draw()
    ay.value = UserAcceleration.y
    ay:draw()
    az.value = UserAcceleration.z
    az:draw()
    ilx:draw(Gravity.x)
    ily:draw(Gravity.y)
    ilz:draw(Gravity.z)
end
RoundGauge = class()
function RoundGauge:init(left, bottom, right, top, min, max, name)
    self.frame = Frame(left, bottom, right, top)
    self.min = min
    self.max = max
    self.name = name
    self.bezel = 10
    self.bezelColor = color(91, 90, 90, 255)
    self.faceColor = color(229, 229, 229, 255)
    self.value = min
    self.length = self.frame:width() / 2 - self.bezel
end
function RoundGauge:draw()
    pushMatrix()
    pushStyle()
    
    stroke(self.bezelColor)
    fill(self.faceColor)
    strokeWidth(self.bezel)
    ellipse(self.frame:midx(), self.frame:midy(), 
    self.frame:width(), self.frame:height())
    strokeWidth(3)
    -- value line
    stroke(250, 13, 13, 255)
    v = (self.value - self.min) / (self.max - self.min) * 300
    v = math.rad(v - 60)
    x = (self.length-10) * math.cos(v) + self.frame:midx()
    y = (self.length-10) * math.sin(v) + self.frame:midy()
    
    line(self.frame:midx(), self.frame:midy(), x, y)
    strokeWidth(1)
    font("ArialMT")
    fontSize(10)
    fill(0, 0, 0, 255)
    
    stroke(8, 7, 7, 255)
    fill(163, 158, 49, 255)
    v = math.rad(240)
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    ellipse(x, y, 11)
    line(x-4,y-4,x+4,y+4)
    line(x+4,y+4,x-4,y-4)
    v = math.rad(300)
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    ellipse(x, y, 11)
    line(x-4,y-4,x+4,y+4)
    line(x+4,y+4,x-4,y-4)
    ellipse(self.frame:midx(), self.frame:midy(), 15)
    
    fill(0, 0, 0, 255)
    textAlign(CENTER)
    text(self.name, self.frame:midx(), self.frame:midy() - 30)
    
    textAlign(LEFT)
    v = math.rad(230)
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    text(self.min, x, y)
    v = math.rad(160)
    d = (self.max - self.min) / 4
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    text(self.min + d, x, y)
    textAlign(CENTER)
    v = math.rad(90)
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    text(self.min + d*2, x, y)
    textAlign(RIGHT)
    v = math.rad(20)
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    text(self.min + d*3, x, y)
    v = math.rad(-50)
    x = (self.length - 10) * math.cos(v) + self.frame:midx()
    y = (self.length - 10) * math.sin (v) + self.frame:midy()
    text(self.max, x, y)
    popStyle()
    popMatrix()
end
TrendGraph = class()
function TrendGraph:init(x1, y1, x2, y2, title)
    self.outer = Frame(x1, y1, x2, y2)
    self.inner = Frame(x1 + 20, y1 + 20, x2 - 10, y2 - 40)
    self.title = title
    self.series = {}
    self.xlabel = ""
    self.ylabel = ""
end
function TrendGraph:addSeries(name, len, min, max, sym, size, thick, clr)
    local i
    i = table.getn(self.series)
    self.series[i + 1] = DataSeries(name, len, min, max, sym, size, thick, clr)
end
function TrendGraph:draw(pts)
    local i, dx, dy, x, y, ox, oy
    pushMatrix()
    pushStyle()
    fill(218, 218, 218, 255)
    stroke(60, 60, 60, 255)
    self.outer:draw()
    self.outer:gloss()
    strokeWidth(1)
    fill(255, 255, 255, 255)
    self.inner:draw()
    textAlign(CENTER)
    fill(255, 255, 255, 255)
    text(self.title, self.outer:midx(), self.outer.y2 - 20)
    stroke(202, 202, 202, 255)
    line(self.inner.x1, self.inner.y1, self.inner.x2, self.inner.y1)
    line(self.inner.x1, self.inner.y2, self.inner.x2, self.inner.y2)
    line(self.inner.x1, self.inner:midy(), 
    self.inner.x2, self.inner:midy())
    stroke(224, 224, 224, 141)
    line(self.inner.x1, self.inner:midy() + self.inner:height()/4, 
    self.inner.x2, self.inner:midy() + self.inner:height()/4 )
    line(self.inner.x1, self.inner:midy() - self.inner:height()/4, 
    self.inner.x2, self.inner:midy() - self.inner:height()/4 )
    
    for s, series in ipairs(self.series) do
        series:draw(self.inner, series.min, series.max)
        textAlign(LEFT)
        fill(255, 255, 255, 255)
        text(series.min, self.outer.x1 + 12, self.inner.y1)
        text(series.max, self.outer.x1 + 12, self.inner.y2)
        fill(1, 1, 1, 255)
        text((series.max + series.min)/2, 
        self.outer.x1 + 12, self.inner:midy() +5)
    end
    popMatrix()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment