minecraft-server/Server/mods/OCSLua/lua/apis/graph
2020-03-30 18:33:48 +02:00

132 lines
4.4 KiB
Plaintext

local Graph = {
getColor = function(self, value, trace)
local colorIndex = math.ceil((value - self.min[trace]) / ((self.max[trace] - self.min[trace]) / #self.gradient[trace]))
if colorIndex == 0 then colorIndex = 1 end
if self.target.isColor() then
return self.gradient[trace][colorIndex]
else
return colors.white
end
end,
draw = function(self)
--get the updates first.
for i=1, #self.update do
self.history[i][#self.history[i] + 1] = self.update[i]()
end
if self.target.setTextScale then self.target.setTextScale(0.5) end
self.target.setBackgroundColor(colors.black)
self.target.setTextColor(colors.white)
self.target.clear()
local newMax, newMin = self.max[1], self.min[1]
--draw traces
for trace=1,#self.update do
if self.history[trace][#self.history[trace]] > self.max[trace] then
if self.sharedBounds and self.history[trace][#self.history[trace]] > newMax then
newMax = self.history[trace][#self.history[trace]]
else
self.max[trace] = self.history[trace][#self.history[trace]]
end
elseif self.history[trace][#self.history[trace]] < self.min[trace] then
if self.sharedBounds and self.history[trace][#self.history[trace]] < newMin then
newMin = self.history[trace][#self.history[trace]]
else
self.min[trace] = self.history[trace][#self.history[trace]]
end
end
local xLim, yLim = self.target.getSize()
if #self.history[trace] > xLim then table.remove(self.history[trace], 1) end
--we set up our value string for numeric value readout here, but draw it later so it doesn't interfere with the full-screen trace.
for i=1, #self.history[trace] do
self.target.setCursorPos(i, yLim - math.ceil((yLim - 1) * (self.history[trace][i] - self.min[trace]) / (self.max[trace] - self.min[trace])))
self.target.setBackgroundColor(self:getColor(self.history[trace][i], trace))
self.target.write(" ")
self.target.setBackgroundColor(colors.black)
end
end
--adjust min-max for next round.
if self.sharedBounds then
for i=1, #self.update do
self.max[i] = newMax
self.min[i] = newMin
end
end
--draw trace labels.
for trace = 1, #self.update do
local valueString, cStart, cEnd = ""
if self.valueText[trace] then
valueString = self.valueText[trace]..": "
cStart = #valueString + 1
valueString = valueString..tostring(self.history[trace][#self.history[trace]])
cEnd = #valueString
valueString = valueString.." / "..self.max[trace]
end
local xLim, yLim = self.target.getSize()
if trace + 1 <= yLim then
self.target.setCursorPos(2, trace + 1)
for i=1, #valueString do
if i >= cStart and i <= cEnd then
self.target.setTextColor(self:getColor(self.history[trace][#self.history[trace]], trace))
end
self.target.write(string.sub(valueString, i, i))
self.target.setTextColor(colors.white)
end
end
end
end,
tostring = function(self)
local valueString = ""
if self.valueText[1] then
valueString = self.valueText[1]..": "
end
valueString = valueString..tostring(self.history[1][#self.history[1]]).." / "..self.max[1]
return valueString
end,
}
local gmetatable = {
__index = Graph,
__tostring = function(g) return g:tostring() end,
}
function new(target, updateFunction, valueText, gradientTable, min, max, sharedBounds)
if not target then return nil, "Must specify output target!" end
if not updateFunction then return nil, "Must specify update function!" end
local g = {
min = type(min) == "table" and min or {},
max = type(max) == "table" and max or {},
target = target,
update = type(updateFunction) == "table" and updateFunction or {updateFunction},
history = {},
gradient = {},
valueText = type(valueText) == "table" and valueText or {valueText},
sharedBounds = shareBounds or false
}
for i=1, #g.update do
g.history[i] = {}
end
if type(min) ~= "table" then
local setMin = min or 0
for i=1, #g.update do
g.min[i] = setMin
end
end
if type(max) ~= "table" then
local setMax = max or 1
for i=1, #g.update do
g.max[i] = setMax
end
end
if gradientTable and type(gradientTable) == "table" and type(gradientTable[1]) == "table" then
g.gradient = gradientTable
elseif gradientTable and type(gradientTable) == "table" then
for i=1, #g.update do
g.gradient[i] = gradientTable
end
else
for i=1, #g.update do
g.gradient[i] = {colors.red, colors.orange, colors.yellow, colors.lime, colors.green}
end
end
setmetatable(g, gmetatable)
return g
end