Fingercomp 37 Posted July 6, 2017 Share Posted July 6, 2017 Suppose you are creating some monitoring program: tank monitor, energy monitor or whatever. It should print how much energy (or fluid) is stored, draw a progress bar and a few histograms with different update intervals (1 second, 30 seconds, 1 minute and 10 minutes). I don't think printing will cause any programs, so I'll skip it. But what about progress bars and histograms? Well, it isn't not rocket science, of course. But not a really easy thing either. Anyway, a few months ago I've written a small library that makes it easy to draw histograms and progress bars, called "charts". Install the library from OpenPrograms using oppm (oppm install charts), or from the Hel Repository using hpm (hpm install charts). I can't insert images directly because the editor is broken. So here's the link to the album. As you can see, progress bars and histograms have the precision up to 1/8 of character. API The library exports Container, Histogram, ProgressBar and sides. Container Contains child objects (histograms or progress bars) and provides some common options like width, height, top-left corner coordinates and so on. Container(), Container{...} — create a container object. When called as Container{...}, you can set object parameters on the fly: Container{x = 2, y = 3, payload=Histogram()}. Properties container.gpu — the proxy of the gpu to use when drawing. Uses the primary gpu by default. container.fg — default foreground color. Default: 0xFFFFFF. container.bg — default background color. Default: 0x000000. container.x, container.y — coordinates of the top-left corner of container. Default: 1, 1. container.payloadX, container.payloadY — coordinates of payload, relative to the top-left corner of container. Default: 1, 1. container.width, container.height — width and height of container. Default: 80, 25. container.payload — histogram or progress bar object. Methods container:draw() — draw the chart. Histogram Histogram(), Histogram{...} — constuct a histogram object. The second way of initialization works the same as Container{...}. Properties histogram.values — table that contains numeric values. Default: {}. histogram.align defines the alignment of the chart (one of sides.LEFT or sides.RIGHT, see sides below). Default: sides.LEFT. histogram.colorFunc — the function that returns a foreground color and a background color for each bin of histogram. Arguments passed to the function are: an index of bin (in histogram.values), a normalized value (from 0 to 1), a value itself, a histogram object, a container object. Default: function() end. histogram.min — the minimum value of chart. Default: 0. histogram.max — the maximum value of chart. Default: 1. histogram.level.y — the height of histogram level. If level is in range (0; 1), it's treated as the relative height (e.g., 0 is the bottom, 0.5 is the middle). If it's less than 0, it's treated as the absolute offset from the top (with -1 meaning the top, -2 — one character under the top, and so on). Otherwise it's treated as the absolute offset from the bottom (for example, 1 is one character above the bottom). Default: 0. histogram.level.value — the value that corresponds the chart. Values less than this will be drawn below the level, values greater than this will be drawn above the level. If set to nil, it defaults to histogram.min. Default: nil. Progress bar ProgressBar(), ProgressBar{...} — construct a progress bar object. Properties progressBar.direction — the direction of progress bar (sides.TOP, sides.BOTTOM, sides.LEFT, sides.RIGHT). Default: sides.RIGHT. progressBar.min — the minimum value of progress bar. Default: 0. progressBar.max — the maximum value of progress bar. Default: 1. progressBar.value — the current value of progress bar. Default: 0. progressBar.colorFunc — the function that returns a foreground color and a background color of progress bar. Arguments passed to the function are: a value, a normalized value (from 0 to 1), a progress bar object, a container object. Examples local charts = require("charts") local container = charts.Container() local payload = charts.Histogram { max = 80, align = charts.sides.RIGHT, colorFunc = function(index, norm, value, self, container) return 0x20ff20 end } container.payload = payload for i = 1, 400, 1 do table.insert(payload.values, math.random(0, 80)) container:draw() os.sleep(.05) end local charts = require("charts") local term = require("term") local event = require("event") local cleft = charts.Container { x = 1, y = 1, width = 50, height = 2, payload = charts.ProgressBar { direction = charts.sides.LEFT, value = 0, colorFunc = function(_, perc) if perc >= .9 then return 0x20afff elseif perc >= .75 then return 0x20ff20 elseif perc >= .5 then return 0xafff20 elseif perc >= .25 then return 0xffff20 elseif perc >= .1 then return 0xffaf20 else return 0xff2020 end end } } local cright = charts.Container { x = 1, y = 4, width = 50, height = 2, payload = charts.ProgressBar { direction = charts.sides.RIGHT, value = 0, colorFunc = cleft.payload.colorFunc } } local ctop = charts.Container { x = 55, y = 1, width = 2, height = 20, payload = charts.ProgressBar { direction = charts.sides.TOP, value = 0, colorFunc = cleft.payload.colorFunc } } local cbottom = charts.Container { x = 59, y = 1, width = 2, height = 20, payload = charts.ProgressBar { direction = charts.sides.BOTTOM, value = 0, colorFunc = cleft.payload.colorFunc } } for i = 0, 100, 1 do term.clear() cleft.gpu.set(5, 10, "Value: " .. ("%.2f"):format(i / 100) .. " [" .. ("%3d"):format(i) .. "%]") cleft.gpu.set(5, 11, "Max: " .. cleft.payload.min) cleft.gpu.set(5, 12, "Min: " .. cleft.payload.max) cleft.payload.value, cright.payload.value, ctop.payload.value, cbottom.payload.value = i / 100, i / 100, i / 100, i / 100 cleft:draw() ctop:draw() cright:draw() cbottom:draw() if event.pull(0.05, "interrupted") then term.clear() os.exit() end end event.pull("interrupted") term.clear() My EU monitor is available here. See the Hel Repository's package page for the up-to-date documentation and changelog. Quote Link to post Share on other sites