- Fixed BaseElement Visual request issues - Added number animation - Added entries animation
224 lines
6.8 KiB
Lua
224 lines
6.8 KiB
Lua
local elementManager = require("elementManager")
|
|
local VisualElement = elementManager.getElement("VisualElement")
|
|
local tHex = require("libraries/colorHex")
|
|
---@configDescription A point based graph element
|
|
---@configDefault false
|
|
|
|
--- This is the base class for all graph elements. It is a point based graph.
|
|
--- @usage local graph = main:addGraph()
|
|
--- @usage :addSeries("input", " ", colors.green, colors.green, 10)
|
|
--- @usage :addSeries("output", " ", colors.red, colors.red, 10)
|
|
--- @usage
|
|
--- @usage basalt.schedule(function()
|
|
--- @usage while true do
|
|
--- @usage graph:addPoint("input", math.random(1,100))
|
|
--- @usage graph:addPoint("output", math.random(1,100))
|
|
--- @usage sleep(2)
|
|
--- @usage end
|
|
--- @usage end)
|
|
--- @class Graph : VisualElement
|
|
local Graph = setmetatable({}, VisualElement)
|
|
Graph.__index = Graph
|
|
|
|
---@property minValue number 0 The minimum value of the graph
|
|
Graph.defineProperty(Graph, "minValue", {default = 0, type = "number", canTriggerRender = true})
|
|
---@property maxValue number 100 The maximum value of the graph
|
|
Graph.defineProperty(Graph, "maxValue", {default = 100, type = "number", canTriggerRender = true})
|
|
---@property series table {} The series of the graph
|
|
Graph.defineProperty(Graph, "series", {default = {}, type = "table", canTriggerRender = true})
|
|
|
|
--- Creates a new Graph instance
|
|
--- @shortDescription Creates a new Graph instance
|
|
--- @return Graph self The newly created Graph instance
|
|
--- @private
|
|
function Graph.new()
|
|
local self = setmetatable({}, Graph):__init()
|
|
self.class = Graph
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Initializes the Graph instance
|
|
--- @param props table The properties to initialize the element with
|
|
--- @param basalt table The basalt instance
|
|
--- @return Graph self The initialized instance
|
|
--- @protected
|
|
function Graph:init(props, basalt)
|
|
VisualElement.init(self, props, basalt)
|
|
self.set("type", "Graph")
|
|
self.set("width", 20)
|
|
self.set("height", 10)
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Adds a series to the graph
|
|
--- @param name string The name of the series
|
|
--- @param symbol string The symbol of the series
|
|
--- @param bgCol number The background color of the series
|
|
--- @param fgCol number The foreground color of the series
|
|
--- @param pointCount number The number of points in the series
|
|
--- @return Graph self The graph instance
|
|
function Graph:addSeries(name, symbol, bgCol, fgCol, pointCount)
|
|
local series = self.get("series")
|
|
table.insert(series, {
|
|
name = name,
|
|
symbol = symbol or " ",
|
|
bgColor = bgCol or colors.white,
|
|
fgColor = fgCol or colors.black,
|
|
pointCount = pointCount or self.get("width"),
|
|
data = {},
|
|
visible = true
|
|
})
|
|
self:updateRender()
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Removes a series from the graph
|
|
--- @param name string The name of the series
|
|
--- @return Graph self The graph instance
|
|
function Graph:removeSeries(name)
|
|
local series = self.get("series")
|
|
for i, s in ipairs(series) do
|
|
if s.name == name then
|
|
table.remove(series, i)
|
|
break
|
|
end
|
|
end
|
|
self:updateRender()
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Gets a series from the graph
|
|
--- @param name string The name of the series
|
|
--- @return table? series The series
|
|
function Graph:getSeries(name)
|
|
local series = self.get("series")
|
|
for _, s in ipairs(series) do
|
|
if s.name == name then
|
|
return s
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
--- @shortDescription Changes the visibility of a series
|
|
--- @param name string The name of the series
|
|
--- @param visible boolean Whether the series should be visible
|
|
--- @return Graph self The graph instance
|
|
function Graph:changeSeriesVisibility(name, visible)
|
|
local series = self.get("series")
|
|
for _, s in ipairs(series) do
|
|
if s.name == name then
|
|
s.visible = visible
|
|
break
|
|
end
|
|
end
|
|
self:updateRender()
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Adds a point to a series
|
|
--- @param name string The name of the series
|
|
--- @param value number The value of the point
|
|
--- @return Graph self The graph instance
|
|
function Graph:addPoint(name, value)
|
|
local series = self.get("series")
|
|
|
|
for _, s in ipairs(series) do
|
|
if s.name == name then
|
|
table.insert(s.data, value)
|
|
while #s.data > s.pointCount do
|
|
table.remove(s.data, 1)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
self:updateRender()
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Focuses a series
|
|
--- @param name string The name of the series
|
|
--- @return Graph self The graph instance
|
|
function Graph:focusSeries(name)
|
|
local series = self.get("series")
|
|
for index, s in ipairs(series) do
|
|
if s.name == name then
|
|
table.remove(series, index)
|
|
table.insert(series, s)
|
|
break
|
|
end
|
|
end
|
|
self:updateRender()
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Sets the point count of a series
|
|
--- @param name string The name of the series
|
|
--- @param count number The number of points in the series
|
|
--- @return Graph self The graph instance
|
|
function Graph:setSeriesPointCount(name, count)
|
|
local series = self.get("series")
|
|
for _, s in ipairs(series) do
|
|
if s.name == name then
|
|
s.pointCount = count
|
|
while #s.data > count do
|
|
table.remove(s.data, 1)
|
|
end
|
|
break
|
|
end
|
|
end
|
|
self:updateRender()
|
|
return self
|
|
end
|
|
|
|
--- Clears all points from a series
|
|
--- @shortDescription Clears all points from a series
|
|
--- @param name? string The name of the series
|
|
--- @return Graph self The graph instance
|
|
function Graph:clear(seriesName)
|
|
local series = self.get("series")
|
|
if seriesName then
|
|
for _, s in ipairs(series) do
|
|
if s.name == seriesName then
|
|
s.data = {}
|
|
break
|
|
end
|
|
end
|
|
else
|
|
for _, s in ipairs(series) do
|
|
s.data = {}
|
|
end
|
|
end
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Renders the graph
|
|
--- @protected
|
|
function Graph:render()
|
|
VisualElement.render(self)
|
|
|
|
local width = self.get("width")
|
|
local height = self.get("height")
|
|
local minVal = self.get("minValue")
|
|
local maxVal = self.get("maxValue")
|
|
local series = self.get("series")
|
|
|
|
for _, s in pairs(series) do
|
|
if(s.visible)then
|
|
local dataCount = #s.data
|
|
local spacing = (width - 1) / math.max((dataCount - 1), 1)
|
|
|
|
for i, value in ipairs(s.data) do
|
|
local x = math.floor(((i-1) * spacing) + 1)
|
|
|
|
local normalizedValue = (value - minVal) / (maxVal - minVal)
|
|
local y = math.floor(height - (normalizedValue * (height-1)))
|
|
y = math.max(1, math.min(y, height))
|
|
|
|
self:blit(x, y, s.symbol, tHex[s.bgColor], tHex[s.fgColor])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return Graph |