1 --[[ GRAPH widget v1.0 by wlourf (31.10.2010)
2 this widget draws some graphs with some effects
3 http://u-scripts.blogspot.com/2010/10/graph-widget.html
5 To call the script in a conky, use, before TEXT
6 lua_load /path/to/the/script/graph.lua
7 lua_draw_hook_pre main_graph
8 and add one line (blank or not) after TEXT
12 3 parameters are mandatory
13 name - the name of the conky variable to display,
14 for example for {$cpu cpu0}, just write name="cpu"
15 arg - the argument of the above variable,
16 for example for {$cpu cpu1}, just write arg="cpu1"
17 arg can be a numerical value if name=""
18 max - the maximum value the above variable can reach,
19 for example for {$cpu cpu1}, just write max=100 or less or more
22 x,y - coordinates of the bottom-left corner of the graph,
23 relative to the top-left corner of the conky window
24 default = bottom-left corner of the conky window
25 width - width of the graph, default = 100 pixels
26 height - height of the graph, default = 20 pixels
27 nb_values - number of values to display in the graph, default=width
28 i.e. 1 pixel for 1 value
29 autoscale - if set to true, calculate the max valeu of the y axis and
30 doesn't use the max parameter above, default=false
31 skew_x - skew graph around x axis, défaut = 0
32 skew_y - skew graph around y axis, défaut = 0
33 angle - angle of rotation of the graph in degress, default = 0
34 i.e. a horizontal graph)
35 inverse - if set to true, graph are draw from right to left, default=false
36 background - if set to false, background is not drawn, default=true
37 foreground - if set to false, foreground is not drawn, default=true
38 foreground = plain graph
39 bg_bd_size - size of the border of the background, default=0=no border
40 fg_bd_size - size of the border of the foreground, default=0=no border
43 Colours tables below are defined into braces :
44 {position in the gradient (0 to 1), colour in hexadecimal, alpha (0 to 1)}
45 example for a single colour table :
46 {{0,0xFFAA00,1}} position parameter doesn't matter
47 example for a two-colours table :
48 {{0,0xFFAA00,1},{1,0x00AA00,1}} or {{0.5,0xFFAA00,1},{1,0x00AA00,1}}
49 example for a three-colours table :
50 {{0,0xFFAA00,1},{0.5,0xFF0000,1},{1,0x00AA00,1}}
52 bg_colour - colour table for background,
53 default = {{0,0x000000,.5},{1,0xFFFFFF,.5}}
54 fg_colour - colour table for foreground,
55 default = {{0,0x00FFFF,1},{1,0x0000FF,1}}
56 bg_bd_colour- colour table for background border,
57 default = {{1,0xFFFFFF,1}}
58 fg_bd_colour- colour table for foreground border,
59 default = {{1,0xFFFF00,1}}
61 bg_orientation, bg_bd_orientation, fg_orientation, fg_bd_orientation,
62 - "orientation" defines the starting point of the gradient,
64 there are 8 available starting points :
65 "nw","nn","ne","ee","se","ss","sw","ww"
66 (n for north, w for west ...)
67 theses 8 points are the 4 corners + the 4 middles of graph
68 so a gradient "nn" will go from "nn" to "ss"
69 a gradient "nw" will go from "nw" to "se"
72 v1.0 (31 Oct. 2010) original release
74 -- This program is free software; you can redistribute it and/or modify
75 -- it under the terms of the GNU General Public License as published by
76 -- the Free Software Foundation version 3 (GPLv3)
78 -- This program is distributed in the hope that it will be useful,
79 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
80 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 -- GNU General Public License for more details.
83 -- You should have received a copy of the GNU General Public License
84 -- along with this program; if not, write to the Free Software
85 -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
86 -- MA 02110-1301, USA.
92 function set_settings()
105 bg_colour = {{0,0x007AF6,0},{1,0x000000,0}},
106 --fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFFA209,1},{1,0xFFFF00,1}},
107 fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFF3300,1},{1,0xFFFFFF,1}},
108 --fg_colour = { {0,0xFF0000,1},{0.5,0xFFA209,1},{1,0xFFFF00,1}},
109 fg_colour = { {0,0x00CCFF,0.7},{0.5,0x0000FF,0.7},{1,0x000000,0.1}},
112 bg_bd_orientation="nn",
126 bg_colour = {{0,0x007AF6,0},{1,0x000000,0}},
127 fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFFA209,0.8},{1,0xFFFF00,0.6}},
128 fg_colour = { {0,0xFF0000,0.65},{0.5,0xFFA209,0.5},{1,0xFFFF00,0.3}},
131 DrawMe="${if_up wlan0}1${else}0$endif",
145 bg_colour = {{0,0x007AF6,0},{1,0x000000,0}},
146 fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFFA209,0.8},{1,0xFFFF00,0.6}},
147 fg_colour = { {0,0xFF0000,0.65},{0.5,0xFFA209,0.5},{1,0xFFFF00,0.3}},
149 DrawMe="${if_up wlan0}1${else}0$endif",
163 bg_colour = {{0,0x007AF6,0},{1,0x000000,0}},
164 fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFFA209,0.8},{1,0xFFFF00,0.6}},
165 fg_colour = { {0,0xFF0000,0.65},{0.5,0xFFA209,0.5},{1,0xFFFF00,0.3}},
168 DrawMe="${if_up gprs0}1${else}0$endif",
182 bg_colour = {{0,0x007AF6,0},{1,0x000000,0}},
183 fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFFA209,0.8},{1,0xFFFF00,0.6}},
184 fg_colour = { {0,0xFF0000,0.65},{0.5,0xFFA209,0.5},{1,0xFFFF00,0.3}},
186 DrawMe="${if_up gprs0}1${else}0$endif",
200 bg_colour = {{0,0x667AF6,0},{1,0x000000,0}},
201 fg_bd_colour = { {0,0xdd0000,0.7},{0.5,0xdddd00,0.7},{1,0xFFFF00,0.7}},
202 fg_colour = { {0,0x000000,0.7},{0.5,0xdd0000,0.7},{1,0xff0000,0.7}},
206 name="to_bytes ${diskio",
216 bg_colour = {{0,0x667AF6,0},{1,0x000000,0}},
217 fg_bd_colour = { {0,0x111111,0.3},{0.5,0xcc6600,0.6},{1,0xcc6600,0.8}},
218 fg_colour = { {1,0x111111,0.3},{0.5,0xcc6600,0.6},{0,0xcc6600,0.8}},
224 name="battery_rate", --displays when discharging
234 bg_colour = {{0,0x667AF6,0},{1,0x000000,0}},
235 fg_bd_colour = { {0,0xFF0000,1},{0.5,0xFF0000,1},{1,0xFF0000,1}},
236 fg_colour = { {1,0xFF0000,0.3},{0.5,0xFF0000,0.6},{0,0xFF0000,0.8}},
240 DrawMe="${if_match ${battery_rate} > 0}1${else}0$endif",
243 name="battery_rate", --displays when charging
253 bg_colour = {{0,0x667AF6,0},{1,0x000000,0}},
254 fg_bd_colour = { {0,0x00FF00,1},{0.5,0x00FF00,1},{1,0x00FF00,1}},
255 fg_colour = { {1,0x00FF00,0.3},{0.5,0x00FF00,0.6},{0,0x00FF00,0.8}},
259 DrawMe="${if_match ${battery_rate} < 0}1${else}0$endif",
264 function check_settings(t)
265 --tables are check only when conky start
266 if t.name==nil and t.arg==nil then
267 print ("No input values ... use parameters 'name'" ..
268 " with 'arg' or only parameter 'arg' ")
272 print ("No maximum value defined, use 'max'")
273 print ("for name=" .. t.name .. " with arg=" .. t.arg)
276 if t.name==nil then t.name="" end
277 if t.arg==nil then t.arg="" end
281 function conky_main_graph()
282 if conky_window == nil then return end
283 local w=conky_window.width
284 local h=conky_window.height
285 local cs=cairo_xlib_surface_create(conky_window.display,
286 conky_window.drawable, conky_window.visual, w, h)
288 updates=tonumber(conky_parse('${updates}'))
289 --start drawing after "updates_gap" updates
290 --prevent segmentation error for cpu
295 for i in pairs(graph_settings) do
296 if graph_settings[i].width==nil then graph_settings[i].width=100 end
297 if graph_settings[i].nb_values==nil then
298 graph_settings[i].nb_values= graph_settings[i].width
300 --create an empty table to store values
301 graph_settings[i]["values"]={}
303 graph_settings[i].beg = graph_settings[i].nb_values
304 --graph_settings[i].beg = 0
305 for j=1, graph_settings[i].nb_values do
306 graph_settings[i].values[j]=0
308 graph_settings[i].flag_init=true
309 flagOK=flagOK + check_settings(graph_settings[i])
313 --abort script if error in one of the tables
314 print ("ERROR : Check the graph_setting table")
318 if updates > updates_gap then
319 for i in pairs(graph_settings) do
320 if (graph_settings[i].DrawMe==nil or conky_parse(graph_settings[i].DrawMe) == "1") then
321 --print(graph_settings[i].DrawMe.."= '"..conky_parse(graph_settings[i].DrawMe).."'")
323 --cancel fetch value from conky if interface down or whatever
324 local nb_values=graph_settings[i].nb_values
325 graph_settings[i].automax=0
326 for j =1, nb_values do
327 if graph_settings[i].values[j+1]==nil then
328 graph_settings[i].values[j+1]=0
330 graph_settings[i].values[j]=graph_settings[i].values[j+1]
333 if graph_settings[i].name=="" then
334 value=graph_settings[i].arg
336 value=tonumber(conky_parse('${' ..
337 graph_settings[i].name .. " " ..
338 graph_settings[i].arg ..'}'))
339 value=math.abs(value)
341 graph_settings[i].values[nb_values]=value
343 graph_settings[i].automax=math.max(graph_settings[i].automax,
344 graph_settings[i].values[j])
345 if graph_settings[i].automax == 0 then graph_settings[i].automax = 1 end --should stop weird glitches at beginning when no values reported yet for upspeed or diskio
347 draw_graph(graph_settings[i])
352 cairo_surface_destroy(cs)
357 function draw_graph(t)
359 local function rgb_to_r_g_b(colour)
360 return ((colour[2] / 0x10000) % 0x100) / 255., ((colour[2] / 0x100) % 0x100) / 255., (colour[2] % 0x100) / 255., colour[3]
363 local function linear_orientation(o,w,h)
364 --set gradient for bg and bg border
386 local function linear_orientation_inv(o,w,h)
387 --set gradient for fg and fg border
408 if t.DrawMe~=nil and conky_parse(t.DrawMe) ~= "1" then
409 --print(t.DrawMe.."= '"..conky_parse(t.DrawMe).."'")
413 end --cancel drawing for same reason as earlier
415 if t.height==nil then t.height=20 end
416 --checked in previous part : width and nb_values
417 if t.background==nil then t.background=true end
418 if t.bg_bd_size==nil then t.bg_bd_size=0 end
419 if t.x==nil then t.x=t.bg_bd_size end
420 if t.y==nil then t.y=conky_window.height -t.bg_bd_size end
421 if t.bg_colour==nil then t.bg_colour={{0,0x000000,.5},{1,0xFFFFFF,.5}} end
422 if t.bg_bd_colour==nil then t.bg_bd_colour={{1,0xFFFFFF,1}} end
423 if t.foreground==nil then t.foreground=true end
424 if t.fg_colour==nil then t.fg_colour={{0,0x00FFFF,1},{1,0x0000FF,1}} end
425 if t.fg_bd_size==nil then t.fg_bd_size=0 end
426 if t.fg_bd_colour==nil then t.fg_bd_colour={{1,0xFFFF00,1}} end
427 if t.autoscale==nil then t.autoscale=false end
428 if t.inverse==nil then t.inverse=false end
429 if t.angle==nil then t.angle=0 end
430 if t.bg_bd_orientation==nil then t.bg_bd_orientation="nn" end
431 if t.bg_orientation==nil then t.bg_orientation="nn" end
432 if t.fg_bd_orientation==nil then t.fg_bd_orientation="nn" end
433 if t.fg_orientation==nil then t.fg_orientation="nn" end
434 --check colours tables
435 for i=1, #t.fg_colour do
436 if #t.fg_colour[i]~=3 then
437 print ("error in fg_colour table")
438 t.fg_colour[i]={1,0x0000FF,1}
441 for i=1, #t.fg_bd_colour do
442 if #t.fg_bd_colour[i]~=3 then
443 print ("error in fg_bd_colour table")
444 t.fg_bd_colour[i]={1,0x00FF00,1}
447 for i=1, #t.bg_colour do
448 if #t.bg_colour[i]~=3 then
449 print ("error in background color table")
450 t.bg_colour[i]={1,0xFFFFFF,0.5}
453 for i=1, #t.bg_bd_colour do
454 if #t.bg_bd_colour[i]~=3 then
455 print ("error in background border color table")
456 t.bg_bd_colour[i]={1,0xFFFFFF,1}
459 --calculate skew parameters if needed
461 if t.skew_x == nil then
464 t.skew_x = math.pi*t.skew_x/180
466 if t.skew_y == nil then
469 t.skew_y = math.pi*t.skew_y/180
473 cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND)
474 cairo_set_line_join(cr,CAIRO_LINE_JOIN_ROUND)
475 local matrix0 = cairo_matrix_t:create()
476 tolua.takeownership(matrix0)
478 cairo_matrix_init (matrix0, 1,t.skew_y,t.skew_x,1,0,0)
479 cairo_transform(cr,matrix0)
480 local ratio=t.width/t.nb_values
481 cairo_translate(cr,t.x,t.y)
482 cairo_rotate(cr,t.angle*math.pi/180)
486 local pts=linear_orientation(t.bg_orientation,t.width,t.height)
487 local pat = cairo_pattern_create_linear (pts[1],pts[2],pts[3],pts[4])
488 for i=1, #t.bg_colour do
489 --print ("i",i,t.colour[i][1], rgb_to_r_g_b(t.colour[i]))
490 cairo_pattern_add_color_stop_rgba (pat, t.bg_colour[i][1], rgb_to_r_g_b(t.bg_colour[i]))
492 cairo_set_source (cr, pat)
493 cairo_rectangle(cr,0,0,t.width,t.height)
495 cairo_pattern_destroy(pat)
502 local scale_x = t.width/(t.nb_values-1)
503 local scale_y = t.height/t.max
504 --define first point of the graph
505 if updates-updates_gap <t.nb_values then
507 --next line prevent segmentation error when conky window is redraw
508 --quicly when another window "fly" over it
509 if t.beg<0 then t.beg=0 end
513 if t.inverse then cairo_scale(cr,-1,1)
514 cairo_translate(cr,-t.width,0) end
517 local pts_fg=linear_orientation_inv(t.fg_orientation,t.width,t.height)
518 local pat = cairo_pattern_create_linear (pts_fg[1],pts_fg[2],pts_fg[3],pts_fg[4])
519 for i=1,#t.fg_colour,1 do
520 cairo_pattern_add_color_stop_rgba (pat, 1-t.fg_colour[i][1], rgb_to_r_g_b(t.fg_colour[i]))
522 cairo_set_source (cr, pat)
523 cairo_move_to(cr,t.beg*scale_x,0)
524 cairo_line_to(cr,t.beg*scale_x,t.values[t.beg+1]*scale_y)
525 for i=t.beg, t.nb_values-1 do
526 cairo_line_to(cr,i*scale_x,t.values[i+1]*scale_y)
528 cairo_line_to(cr,(t.nb_values-1)*scale_x,0)
531 cairo_pattern_destroy(pat)
534 if t.fg_bd_size>0 then
535 local pts=linear_orientation_inv(t.fg_bd_orientation,t.width,t.height)
536 local pat = cairo_pattern_create_linear (pts[1],pts[2],pts[3],pts[4])
537 for i=1,#t.fg_bd_colour,1 do
538 cairo_pattern_add_color_stop_rgba (pat, 1-t.fg_bd_colour[i][1], rgb_to_r_g_b(t.fg_bd_colour[i]))
540 cairo_set_source (cr, pat)
541 cairo_move_to(cr,t.beg*scale_x,t.values[t.beg+1]*scale_y)
542 for i=t.beg, t.nb_values-1 do
543 cairo_line_to(cr,i*scale_x,t.values[i+1]*scale_y)
545 cairo_set_line_width(cr,t.fg_bd_size)
547 cairo_pattern_destroy(pat)
551 if t.bg_bd_size>0 then
552 local pts=linear_orientation(t.bg_bd_orientation,t.width,t.height)
553 local pat = cairo_pattern_create_linear (pts[1],pts[2],pts[3],pts[4])
554 for i=1, #t.bg_bd_colour do
555 --print ("i",i,t.colour[i][1], rgb_to_r_g_b(t.colour[i]))
556 cairo_pattern_add_color_stop_rgba (pat, t.bg_bd_colour[i][1], rgb_to_r_g_b(t.bg_bd_colour[i]))
558 cairo_set_source (cr, pat)
559 cairo_rectangle(cr,0,0,t.width,t.height)
560 cairo_set_line_width(cr,t.bg_bd_size)
562 cairo_pattern_destroy(pat)