liquid_feedback_frontend

annotate env/util/initiative_pie.lua @ 1309:32cc544d5a5b

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

Impressum / About Us