From 9f2c4719edb0a809641c5e6a2d3345312b8fa70a Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Wed, 7 Dec 2016 20:20:09 +0100 Subject: [PATCH] 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 --- lib/wibox/widget/piechart.lua | 41 +++++++++++++++---- .../wibox/widget/defaults/piechart.lua | 8 ++-- .../wibox/widget/piechart/border_color.lua | 8 ++-- .../wibox/widget/piechart/border_width.lua | 8 ++-- .../examples/wibox/widget/piechart/label.lua | 16 ++++---- 5 files changed, 53 insertions(+), 28 deletions(-) diff --git a/lib/wibox/widget/piechart.lua b/lib/wibox/widget/piechart.lua index 33e0b7d1..0291eebe 100644 --- a/lib/wibox/widget/piechart.lua +++ b/lib/wibox/widget/piechart.lua @@ -51,18 +51,18 @@ end local function compute_sum(data) local ret = 0 - for _,v in pairs(data) do - ret = ret + v + for _, entry in ipairs(data) do + ret = ret + entry[2] end return ret end 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 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 -- 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 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 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 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. -- @property data -- @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 -- @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" } do piechart["set_"..prop] = function(self, value) self._private[prop] = value self:emit_signal("property::"..prop) + if prop == "data_list" then + self:emit_signal("property::data") + end self:emit_signal("widget::redraw_needed") end piechart["get_"..prop] = function(self) @@ -193,7 +202,23 @@ for _, prop in ipairs {"data", "border_color", "border_width", "colors", 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, { enable_properties = true, @@ -204,7 +229,7 @@ local function new(data) rawset(ret, "fit" , fit ) rawset(ret, "draw", draw) - ret:set_data(data) + ret:set_data_list(data_list) return ret end diff --git a/tests/examples/wibox/widget/defaults/piechart.lua b/tests/examples/wibox/widget/defaults/piechart.lua index a5d61369..408224a1 100644 --- a/tests/examples/wibox/widget/defaults/piechart.lua +++ b/tests/examples/wibox/widget/defaults/piechart.lua @@ -5,10 +5,10 @@ local beautiful = require( "beautiful" ) --DOC_HIDE parent:add( --DOC_HIDE wibox.widget { - data = { - ['L1'] = 100, - ['L2'] = 200, - ['L3'] = 300, + data_list = { + { 'L1', 100 }, + { 'L2', 200 }, + { 'L3', 300 }, }, border_width = 1, forced_height = 50, --DOC_HIDE diff --git a/tests/examples/wibox/widget/piechart/border_color.lua b/tests/examples/wibox/widget/piechart/border_color.lua index d69375d1..cf4022fa 100644 --- a/tests/examples/wibox/widget/piechart/border_color.lua +++ b/tests/examples/wibox/widget/piechart/border_color.lua @@ -8,10 +8,10 @@ parent:add(l) for _, v in ipairs {"#ff0000", "#00ff00", "#0000ff"} do l:add(wibox.widget { - data = { - ['L1'] = 100, - ['L2'] = 200, - ['L3'] = 300, + data_list = { + { 'L1', 100 }, + { 'L2', 200 }, + { 'L3', 300 }, }, border_width = 1, border_color = v, diff --git a/tests/examples/wibox/widget/piechart/border_width.lua b/tests/examples/wibox/widget/piechart/border_width.lua index 88a86b62..b876c595 100644 --- a/tests/examples/wibox/widget/piechart/border_width.lua +++ b/tests/examples/wibox/widget/piechart/border_width.lua @@ -8,10 +8,10 @@ parent:add(l) for _, v in ipairs {0,1,3,5} do l:add(wibox.widget { - data = { - ['L1'] = 100, - ['L2'] = 200, - ['L3'] = 300, + data_list = { + { 'L1', 100 }, + { 'L2', 200 }, + { 'L3', 300 }, }, border_width = v, forced_height = 50, diff --git a/tests/examples/wibox/widget/piechart/label.lua b/tests/examples/wibox/widget/piechart/label.lua index 1315eb22..d96d87c3 100644 --- a/tests/examples/wibox/widget/piechart/label.lua +++ b/tests/examples/wibox/widget/piechart/label.lua @@ -11,10 +11,10 @@ parent:add(wibox.widget { }, { { - data = { - ['L1'] = 100, - ['L2'] = 200, - ['L3'] = 300, + data_list = { + { 'L1', 100 }, + { 'L2', 200 }, + { 'L3', 300 }, }, border_width = 1, forced_height = 50, @@ -40,10 +40,10 @@ parent:add(wibox.widget { }, { { - data = { - ['L1'] = 100, - ['L2'] = 200, - ['L3'] = 300, + data_list = { + { 'L1', 100 }, + { 'L2', 200 }, + { 'L3', 300 }, }, border_width = 1, forced_height = 50,