liquid_feedback_frontend

view env/util/initiative_pie.lua @ 1057:6f3e01b266b3

Removed not needed check
author bsw
date Wed Jul 16 21:47:34 2014 +0200 (2014-07-16)
parents 701a5cf6b067
children 32cc544d5a5b
line source
1 function util.initiative_pie(initiative, d, gap)
2 if not initiative.issue.closed or not initiative.admitted then
3 return
4 end
6 if initiative.issue.voter_count == 0 or initiative.positive_votes == nil or initiative.negative_votes == nil then
7 return
8 end
10 local first_preference_votes = initiative.first_preference_votes
12 local d = d or 100
13 local gap = gap or d / 20
15 local r = d/2
16 local r_circle = r - gap
18 local function circle(p)
19 return
20 gap + 2 * r_circle * ( 1 + math.sin( 2 * math.pi * p ) ) / 2,
21 gap + 2 * r_circle * ( 1 - math.cos( 2 * math.pi * p ) ) / 2
22 end
24 local function getpath(start, stop)
25 local start_x, start_y = circle(start)
26 local stop_x, stop_y = circle(stop)
27 local large = stop - start > 0.5 and "1" or "0"
28 return "M" .. r .. "," .. r .. " "
29 .. "L" .. start_x .. ",".. start_y .. " " .. " "
30 .. "A" .. r_circle .. "," .. r_circle .. " 0 " .. large .. ",1 " .. stop_x .. "," .. stop_y .. " "
31 .. "z"
32 end
34 local function uniPie(color, content)
35 ui.tag {
36 tag = "svg",
37 attr = {
38 class = "initiative_pie",
39 width = d .. "px",
40 height = d .. "px",
41 },
42 content = function ()
43 ui.tag { tag = "circle", attr = {
44 cx=r, cy=r, r=r_circle, fill = color, stroke = "#fff", ["stroke-width"] = "2"
45 }, content = function () ui.tag { tag = "title", content = content } end }
46 end
47 }
48 end
50 local function piePiece(path, fill, content)
51 ui.tag {
52 tag = "path",
53 attr = {
54 d = path,
55 fill = fill,
56 stroke = "#fff",
57 ["stroke-width"] = "2",
58 ["stroke-linecap"] = "butt"
59 },
60 content = function ()
61 ui.tag {
62 tag = "title",
63 content = content
64 }
65 end
66 }
67 end
69 local function pie(args)
70 local offset = args.offset or 0
71 local list = {}
72 local sum = 0
73 for i, element in ipairs(args) do
74 element.start = sum + offset
75 list[#list+1] = element
76 sum = sum + element.value
77 end
79 for i, element in ipairs(list) do
80 if element.value == sum then
81 uniPie(element.fill, _(element.label, { count = element.value } ))
82 return
83 end
84 end
85 ui.tag {
86 tag = "svg",
87 attr = {
88 class = "initiative_pie",
89 width = d .. "px",
90 height = d .. "px"
91 },
92 content = function ()
93 table.sort(list, function (a, b)
94 return a.value < b.value
95 end )
96 for i, element in ipairs(list) do
97 local path = getpath(element.start / sum, (element.start + element.value) / sum)
98 local content = _(element.label, { count = element.value })
99 piePiece(path, element.fill, content)
100 end
101 end
102 }
103 end
105 local yes1 = first_preference_votes
106 local yes = initiative.positive_votes - first_preference_votes
107 local neutral = initiative.issue.voter_count - initiative.positive_votes - initiative.negative_votes
108 local no = initiative.negative_votes
110 local sum = yes1 + yes + neutral + no
112 local q = initiative.issue.policy.direct_majority_num / initiative.issue.policy.direct_majority_den
115 local maxrot = sum * 7 / 12 - no
117 local offset = 0
119 if maxrot > 0 then
120 offset = math.min (
121 maxrot,
122 no * ( 1 / ( 1 / q - 1 ) -1 ) / 2
123 )
124 end
126 pie{
127 { value = yes1, fill = "#0a0", label = _"#{count} Yes, first choice" },
128 { value = yes, fill = "#6c6", label = _"#{count} Yes, alternative choice" },
129 { value = neutral, fill = "#ccc", label = _"#{count} Neutral" },
130 { value = no, fill = "#c00", label = _"#{count} No" },
131 offset = - offset
132 }
134 end

Impressum / About Us