93 lines
3.2 KiB
Lua
93 lines
3.2 KiB
Lua
local elementManager = require("elementManager")
|
|
local VisualElement = elementManager.getElement("VisualElement")
|
|
local Graph = elementManager.getElement("Graph")
|
|
local tHex = require("libraries/colorHex")
|
|
--- @configDescription A line chart element based on the graph element
|
|
---@configDefault false
|
|
|
|
--- The Line Chart element visualizes data series as connected line graphs. It plots points on a coordinate system and connects them with lines.
|
|
--- @usage local chart = main:addLineChart()
|
|
--- @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 chart:addPoint("input", math.random(1,100))
|
|
--- @usage chart:addPoint("output", math.random(1,100))
|
|
--- @usage sleep(2)
|
|
--- @usage end
|
|
--- @usage end)
|
|
--- @class LineChart : Graph
|
|
local LineChart = setmetatable({}, Graph)
|
|
LineChart.__index = LineChart
|
|
|
|
--- Creates a new LineChart instance
|
|
--- @shortDescription Creates a new LineChart instance
|
|
--- @return LineChart self The newly created LineChart instance
|
|
--- @private
|
|
function LineChart.new()
|
|
local self = setmetatable({}, LineChart):__init()
|
|
self.class = LineChart
|
|
return self
|
|
end
|
|
|
|
--- @shortDescription Initializes the LineChart instance
|
|
--- @param props table The properties to initialize the element with
|
|
--- @param basalt table The basalt instance
|
|
--- @return LineChart self The initialized instance
|
|
--- @protected
|
|
function LineChart:init(props, basalt)
|
|
Graph.init(self, props, basalt)
|
|
self.set("type", "LineChart")
|
|
return self
|
|
end
|
|
|
|
local function drawLine(self, x1, y1, x2, y2, symbol, bgColor, fgColor)
|
|
local dx = x2 - x1
|
|
local dy = y2 - y1
|
|
local steps = math.max(math.abs(dx), math.abs(dy))
|
|
|
|
for i = 0, steps do
|
|
local t = steps == 0 and 0 or i / steps
|
|
local x = math.floor(x1 + dx * t)
|
|
local y = math.floor(y1 + dy * t)
|
|
if x >= 1 and x <= self.get("width") and y >= 1 and y <= self.get("height") then
|
|
self:blit(x, y, symbol, tHex[bgColor], tHex[fgColor])
|
|
end
|
|
end
|
|
end
|
|
|
|
--- @shortDescription Renders the LineChart
|
|
--- @protected
|
|
function LineChart: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 lastX, lastY
|
|
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))
|
|
|
|
if lastX then
|
|
drawLine(self, lastX, lastY, x, y, s.symbol, s.bgColor, s.fgColor)
|
|
end
|
|
lastX, lastY = x, y
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return LineChart
|