You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
5.0 KiB
210 lines
5.0 KiB
-- This work is licensed under the Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
|
|
|
|
function antialias( cr, antialias )
|
|
require( "cairo" )
|
|
|
|
if antialias then
|
|
cairo_set_antialias( cr, CAIRO_ANTIALIAS_DEFAULT )
|
|
else
|
|
cairo_set_antialias( cr, CAIRO_ANTIALIAS_NONE )
|
|
end
|
|
end
|
|
|
|
function rgb_to_r_g_b( color, alpha )
|
|
local c = tonumber( "0x" .. color )
|
|
|
|
return ( ( c / 0x10000 ) % 0x100 ) / 255.0, ( ( c / 0x100 ) % 0x100 ) / 255.0, ( c % 0x100 ) / 255.0, alpha
|
|
end
|
|
|
|
function cairo_graph( cr, x, y, width, height, f )
|
|
require( "cairo" )
|
|
|
|
local function value_to_y( height, value )
|
|
if height ~= nil and value ~= nil then
|
|
return height * ( 1 - value )
|
|
end
|
|
|
|
return 0
|
|
end
|
|
|
|
if f.data ~= nil and #f.data > 0 then
|
|
local x2 = x + width
|
|
local nx = x2
|
|
|
|
cairo_move_to( cr, x2, y + value_to_y( height, f.data[1] ) )
|
|
|
|
-- Drawn from right to left
|
|
local curve_to = cairo_line_to
|
|
for i, v in pairs( f.data ) do
|
|
nx = nx - f.dx
|
|
|
|
if nx >= x then
|
|
curve_to( cr, nx, y + value_to_y( height, v ) )
|
|
else
|
|
break
|
|
end
|
|
end
|
|
|
|
antialias( cr, f.antialias )
|
|
cairo_set_source_rgba( cr, rgb_to_r_g_b( f.stroke_color, 1 ) )
|
|
cairo_set_line_width( cr, f.stroke_width )
|
|
|
|
if f.fill then
|
|
cairo_stroke_preserve( cr )
|
|
|
|
cairo_line_to( cr, nx, y + height )
|
|
cairo_line_to( cr, x2, y + height )
|
|
cairo_close_path( cr )
|
|
cairo_set_source_rgba( cr, rgb_to_r_g_b( f.fill_color, f.fill_alpha ) )
|
|
cairo_fill( cr )
|
|
else
|
|
cairo_stroke( cr )
|
|
end
|
|
end
|
|
end
|
|
------------------------------------------------------------------------------------------------------------------------
|
|
function draw_graph( cr, x, y, width, height, graph )
|
|
if conky_window == nil or graph == nil then
|
|
return
|
|
end
|
|
|
|
local function push( t, v, c )
|
|
while #t > c do
|
|
table.remove( t, #t )
|
|
end
|
|
|
|
table.insert( t, 1, v )
|
|
end
|
|
|
|
-- Find margins, sizes and positions
|
|
local x_outer = tonumber( x ) + conky_window.text_start_x
|
|
local y_outer = tonumber( y ) + conky_window.text_start_y
|
|
|
|
local w_outer = tonumber( width )
|
|
if w_outer == 0 then
|
|
w_outer = conky_window.text_width - x
|
|
end
|
|
local h_outer = tonumber( height )
|
|
if h_outer == 0 then
|
|
h_outer = conky_window.text_height - y
|
|
end
|
|
|
|
local x_inner = x_outer
|
|
local y_inner = y_inner
|
|
local w_inner = w_outer
|
|
local h_inner = h_outer
|
|
if graph.outline then
|
|
local o = graph.outline_width
|
|
x_inner = x_outer + o
|
|
y_inner = y_outer + o
|
|
|
|
local o2 = o * 2
|
|
w_inner = w_outer - o2
|
|
h_inner = h_outer - o2
|
|
end
|
|
|
|
require( "cairo" )
|
|
|
|
cairo_rectangle( cr, x_inner, y_inner, w_inner, h_inner )
|
|
cairo_clip( cr )
|
|
|
|
for i, f in pairs( graph.functions ) do
|
|
if f.data == nil then
|
|
f.data = {}
|
|
end
|
|
|
|
local pixels_per_value = w_inner / f.dx
|
|
|
|
local str = conky_parse( f.conky_variable )
|
|
local val = tonumber( str )
|
|
|
|
if val ~= nil then
|
|
if f.record_max then
|
|
if val > f.max_value then
|
|
f.max_value = val
|
|
else
|
|
for i, v in pairs( f.data ) do
|
|
if v > f.max_value then
|
|
f.max_value = v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
push( f.data, val / f.max_value, pixels_per_value )
|
|
end
|
|
|
|
cairo_graph( cr, x_inner, y_inner, w_inner, h_inner, f )
|
|
end
|
|
|
|
cairo_reset_clip( cr )
|
|
|
|
if graph.outline then
|
|
cairo_set_source_rgba( cr, rgb_to_r_g_b( graph.outline_color, graph.outline_alpha ) )
|
|
cairo_rectangle( cr, x_outer, y_outer, w_outer, h_outer )
|
|
antialias( cr, graph.outline_antialias )
|
|
cairo_set_line_width( cr, graph.outline_width )
|
|
cairo_stroke( cr )
|
|
end
|
|
end
|
|
|
|
function conky_load_graphs( file )
|
|
function json_decode_file( file )
|
|
local json = require( "json" )
|
|
|
|
local t = {}
|
|
for line in io.lines( file ) do
|
|
t[#t + 1] = line
|
|
end
|
|
local str = table.concat( t, "\n" )
|
|
|
|
return json.decode( str )
|
|
end
|
|
|
|
local lfs = require( "lfs" )
|
|
|
|
mod_time = lfs.attributes( file, "modification" )
|
|
graphs_file = file
|
|
graphs = json_decode_file( file )
|
|
end
|
|
|
|
function is_file_dirty( file )
|
|
local lfs = require( "lfs" )
|
|
|
|
local tmp = lfs.attributes( file, "modification" )
|
|
if tmp ~= mod_time then
|
|
mod_time = tmp
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function conky_draw_graphs()
|
|
if conky_window == nil then
|
|
return
|
|
end
|
|
|
|
if is_file_dirty( graphs_file ) then
|
|
print( "Reloading " .. graphs_file .. "..." )
|
|
conky_load_graphs( graphs_file )
|
|
end
|
|
|
|
if graphs == nil then
|
|
return
|
|
end
|
|
|
|
require( "cairo" )
|
|
|
|
local cs = cairo_xlib_surface_create( conky_window.display, conky_window.drawable, conky_window.visual,
|
|
conky_window.width, conky_window.height )
|
|
local cr = cairo_create( cs )
|
|
|
|
cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND )
|
|
|
|
for k, v in pairs( graphs ) do
|
|
draw_graph( cr, v.x, v.y, v.width, v.height, v )
|
|
end
|
|
|
|
cairo_destroy( cr )
|
|
end
|
|
|