Make the piechart deterministic (#1258)

Previously, the API to set the data that should be displayed was
:set_data(t) where t is a table. This table has the labels to use as its
keys and the numbers as its values. With this API, it was not possible
to influence the order in which the "pie pieces" were drawn.

This commit adds and uses a new API called :set_data_list(t). Here, t is
a table with integer keys and tables as values, thus one can iterate
over this with ipairs() and the order is well-defined. The tables used
as values contain the label as their first entry and the number as their
second entry.

Fixes: https://github.com/awesomeWM/awesome/issues/1249
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-12-07 20:20:09 +01:00 committed by Daniel Hahler
parent 26c0a3c2c5
commit 9f2c4719ed
5 changed files with 53 additions and 28 deletions

View File

@ -51,18 +51,18 @@ end
local function compute_sum(data) local function compute_sum(data)
local ret = 0 local ret = 0
for _,v in pairs(data) do for _, entry in ipairs(data) do
ret = ret + v ret = ret + entry[2]
end end
return ret return ret
end end
local function draw(self, _, cr, width, height) local function draw(self, _, cr, width, height)
if not self._private.data then return end if not self._private.data_list then return end
local radius = (height > width and width or height) / 4 local radius = (height > width and width or height) / 4
local sum, start, count = compute_sum(self._private.data),0,0 local sum, start, count = compute_sum(self._private.data_list),0,0
local has_label = self._private.display_labels ~= false local has_label = self._private.display_labels ~= false
-- Labels need to be drawn later so the original source is kept -- Labels need to be drawn later so the original source is kept
@ -81,7 +81,8 @@ local function draw(self, _, cr, width, height)
local colors = self:get_colors() local colors = self:get_colors()
local col_count = colors and #colors or 0 local col_count = colors and #colors or 0
for k,v in pairs(self._private.data) do for _, entry in ipairs(self._private.data_list) do
local k, v = entry[1], entry[2]
local end_angle = start + 2*math.pi*(v/sum) local end_angle = start + 2*math.pi*(v/sum)
local col = colors and color(colors[math.fmod(count,col_count)+1]) or nil local col = colors and color(colors[math.fmod(count,col_count)+1]) or nil
@ -135,6 +136,11 @@ local function fit(_, _, width, height)
return width, height return width, height
end end
--- The pie chart data list.
-- @property data_list
-- @tparam table data_list Sorted table where each entry has a label as its
-- first value and a number as its second value.
--- The pie chart data. --- The pie chart data.
-- @property data -- @property data
-- @tparam table data Labels as keys and number as value. -- @tparam table data Labels as keys and number as value.
@ -180,12 +186,15 @@ end
-- @tparam table colors A table of colors, one for each elements -- @tparam table colors A table of colors, one for each elements
-- @see gears.color -- @see gears.color
for _, prop in ipairs {"data", "border_color", "border_width", "colors", for _, prop in ipairs {"data_list", "border_color", "border_width", "colors",
"display_labels" "display_labels"
} do } do
piechart["set_"..prop] = function(self, value) piechart["set_"..prop] = function(self, value)
self._private[prop] = value self._private[prop] = value
self:emit_signal("property::"..prop) self:emit_signal("property::"..prop)
if prop == "data_list" then
self:emit_signal("property::data")
end
self:emit_signal("widget::redraw_needed") self:emit_signal("widget::redraw_needed")
end end
piechart["get_"..prop] = function(self) piechart["get_"..prop] = function(self)
@ -193,7 +202,23 @@ for _, prop in ipairs {"data", "border_color", "border_width", "colors",
end end
end end
local function new(data) function piechart:set_data(value)
local list = {}
for k, v in pairs(value) do
table.insert(list, { k, v })
end
self:set_data_list(list)
end
function piechart:get_data()
local list = {}
for _, entry in ipairs(self:get_data_list()) do
list[entry[1]] = entry[2]
end
return list
end
local function new(data_list)
local ret = base.make_widget(nil, nil, { local ret = base.make_widget(nil, nil, {
enable_properties = true, enable_properties = true,
@ -204,7 +229,7 @@ local function new(data)
rawset(ret, "fit" , fit ) rawset(ret, "fit" , fit )
rawset(ret, "draw", draw) rawset(ret, "draw", draw)
ret:set_data(data) ret:set_data_list(data_list)
return ret return ret
end end

View File

@ -5,10 +5,10 @@ local beautiful = require( "beautiful" ) --DOC_HIDE
parent:add( --DOC_HIDE parent:add( --DOC_HIDE
wibox.widget { wibox.widget {
data = { data_list = {
['L1'] = 100, { 'L1', 100 },
['L2'] = 200, { 'L2', 200 },
['L3'] = 300, { 'L3', 300 },
}, },
border_width = 1, border_width = 1,
forced_height = 50, --DOC_HIDE forced_height = 50, --DOC_HIDE

View File

@ -8,10 +8,10 @@ parent:add(l)
for _, v in ipairs {"#ff0000", "#00ff00", "#0000ff"} do for _, v in ipairs {"#ff0000", "#00ff00", "#0000ff"} do
l:add(wibox.widget { l:add(wibox.widget {
data = { data_list = {
['L1'] = 100, { 'L1', 100 },
['L2'] = 200, { 'L2', 200 },
['L3'] = 300, { 'L3', 300 },
}, },
border_width = 1, border_width = 1,
border_color = v, border_color = v,

View File

@ -8,10 +8,10 @@ parent:add(l)
for _, v in ipairs {0,1,3,5} do for _, v in ipairs {0,1,3,5} do
l:add(wibox.widget { l:add(wibox.widget {
data = { data_list = {
['L1'] = 100, { 'L1', 100 },
['L2'] = 200, { 'L2', 200 },
['L3'] = 300, { 'L3', 300 },
}, },
border_width = v, border_width = v,
forced_height = 50, forced_height = 50,

View File

@ -11,10 +11,10 @@ parent:add(wibox.widget {
}, },
{ {
{ {
data = { data_list = {
['L1'] = 100, { 'L1', 100 },
['L2'] = 200, { 'L2', 200 },
['L3'] = 300, { 'L3', 300 },
}, },
border_width = 1, border_width = 1,
forced_height = 50, forced_height = 50,
@ -40,10 +40,10 @@ parent:add(wibox.widget {
}, },
{ {
{ {
data = { data_list = {
['L1'] = 100, { 'L1', 100 },
['L2'] = 200, { 'L2', 200 },
['L3'] = 300, { 'L3', 300 },
}, },
border_width = 1, border_width = 1,
forced_height = 50, forced_height = 50,