liquid_feedback_frontend

diff env/util/initiative_pie.lua @ 1045:701a5cf6b067

Imported LiquidFeedback Frontend 3.0 branch
author bsw
date Thu Jul 10 01:19:48 2014 +0200 (2014-07-10)
parents
children 6f3e01b266b3
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/env/util/initiative_pie.lua	Thu Jul 10 01:19:48 2014 +0200
     1.3 @@ -0,0 +1,137 @@
     1.4 +function util.initiative_pie(initiative, d, gap)
     1.5 +  if not initiative.issue.closed or not initiative.admitted then
     1.6 +    return
     1.7 +  end
     1.8 +  
     1.9 +  if initiative.issue.voter_count == 0 or initiative.positive_votes == nil or initiative.negative_votes == nil then
    1.10 +    return
    1.11 +  end
    1.12 +  
    1.13 +  local first_preference_votes = initiative.first_preference_votes
    1.14 +  if first_preference_votes == nil then
    1.15 +    first_preference_votes = 0
    1.16 +  end
    1.17 +    
    1.18 +  local d = d or 100
    1.19 +  local gap = gap or d / 20
    1.20 +  
    1.21 +  local r = d/2
    1.22 +  local r_circle = r - gap
    1.23 +  
    1.24 +  local function circle(p)
    1.25 +    return
    1.26 +      gap + 2 * r_circle * ( 1 + math.sin( 2 * math.pi * p ) ) / 2,
    1.27 +      gap + 2 * r_circle * ( 1 - math.cos( 2 * math.pi * p ) ) / 2
    1.28 +  end
    1.29 +  
    1.30 +  local function getpath(start, stop)
    1.31 +    local start_x, start_y = circle(start)
    1.32 +    local stop_x, stop_y = circle(stop)
    1.33 +    local large = stop - start > 0.5 and "1" or "0"
    1.34 +    return "M" .. r .. "," .. r .. " "
    1.35 +        .. "L" .. start_x .. ",".. start_y .. " " .. " "
    1.36 +        .. "A" .. r_circle .. "," .. r_circle .. " 0 " .. large .. ",1 " .. stop_x .. "," .. stop_y .. " "
    1.37 +        .. "z"
    1.38 +  end
    1.39 +  
    1.40 +  local function uniPie(color, content)
    1.41 +    ui.tag {
    1.42 +      tag = "svg",
    1.43 +      attr = {
    1.44 +        class = "initiative_pie",
    1.45 +        width = d .. "px",
    1.46 +        height = d .. "px",
    1.47 +      },
    1.48 +      content = function ()
    1.49 +        ui.tag { tag = "circle", attr = {
    1.50 +          cx=r, cy=r, r=r_circle, fill = color, stroke = "#fff", ["stroke-width"] = "2"
    1.51 +        }, content = function () ui.tag { tag = "title", content = content } end  }
    1.52 +      end
    1.53 +    }
    1.54 +  end
    1.55 +  
    1.56 +  local function piePiece(path, fill, content)
    1.57 +    ui.tag {
    1.58 +      tag = "path",
    1.59 +      attr = {
    1.60 +        d = path,
    1.61 +        fill = fill,
    1.62 +        stroke = "#fff",
    1.63 +        ["stroke-width"] = "2",
    1.64 +        ["stroke-linecap"] = "butt"
    1.65 +      }, 
    1.66 +      content = function ()
    1.67 +        ui.tag {
    1.68 +          tag = "title", 
    1.69 +          content = content
    1.70 +        }
    1.71 +      end  
    1.72 +    }
    1.73 +  end
    1.74 +  
    1.75 +  local function pie(args)
    1.76 +    local offset = args.offset or 0
    1.77 +    local list = {}
    1.78 +    local sum = 0
    1.79 +    for i, element in ipairs(args) do
    1.80 +      element.start = sum + offset
    1.81 +      list[#list+1] = element
    1.82 +      sum = sum + element.value
    1.83 +    end
    1.84 +    
    1.85 +    for i, element in ipairs(list) do
    1.86 +      if element.value == sum then
    1.87 +        uniPie(element.fill, _(element.label, { count = element.value } ))
    1.88 +        return
    1.89 +      end
    1.90 +    end
    1.91 +    ui.tag {
    1.92 +      tag = "svg",
    1.93 +      attr = {
    1.94 +        class = "initiative_pie",
    1.95 +        width = d .. "px",
    1.96 +        height = d .. "px"
    1.97 +      },
    1.98 +      content = function ()
    1.99 +        table.sort(list, function (a, b)
   1.100 +          return a.value < b.value
   1.101 +        end )
   1.102 +        for i, element in ipairs(list) do
   1.103 +          local path = getpath(element.start / sum, (element.start + element.value) / sum)
   1.104 +          local content = _(element.label, { count = element.value })
   1.105 +          piePiece(path, element.fill, content)
   1.106 +        end
   1.107 +      end
   1.108 +    }
   1.109 +  end
   1.110 +  
   1.111 +  local yes1 = first_preference_votes
   1.112 +  local yes = initiative.positive_votes - first_preference_votes
   1.113 +  local neutral = initiative.issue.voter_count - initiative.positive_votes - initiative.negative_votes
   1.114 +  local no = initiative.negative_votes
   1.115 +  
   1.116 +  local sum = yes1 + yes + neutral + no
   1.117 +  
   1.118 +  local q = initiative.issue.policy.direct_majority_num / initiative.issue.policy.direct_majority_den
   1.119 +      
   1.120 +  
   1.121 +  local maxrot = sum * 7 / 12 - no
   1.122 +  
   1.123 +  local offset = 0
   1.124 +  
   1.125 +  if maxrot > 0 then
   1.126 +    offset = math.min (
   1.127 +      maxrot, 
   1.128 +      no * ( 1 / ( 1 / q - 1 ) -1 ) / 2
   1.129 +    )
   1.130 +  end
   1.131 +    
   1.132 +  pie{
   1.133 +    { value = yes1,    fill = "#0a0", label = _"#{count} Yes, first choice" },
   1.134 +    { value = yes,     fill = "#6c6", label = _"#{count} Yes, alternative choice" },
   1.135 +    { value = neutral, fill = "#ccc", label = _"#{count} Neutral" },
   1.136 +    { value = no,      fill = "#c00", label = _"#{count} No" },
   1.137 +    offset = - offset
   1.138 +  }
   1.139 +    
   1.140 +end
   1.141 \ No newline at end of file

Impressum / About Us