Last active
November 22, 2020 12:52
-
-
Save michalskop/7e55931562cb3e5a9344 to your computer and use it in GitHub Desktop.
Hemicycle chart (general)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# calculates optimal numbers of representives for hemicycle chart | |
import math | |
import csv | |
import numpy as np | |
import timeit | |
start = timeit.default_timer() | |
#benchmark: | |
#n0 = 200 : 4:23s, 5:52s, 6:132s, 7:285s, 8:579s, 9:1167s , 10:2342s, 11: 4632s | |
#n0=751 : 7:217s, 8:570s, 9:1331, 10:2816s, 11: 5686s, 12: 10905s, 13:21918s,14:44362s | |
# number of representatives | |
n0=751 | |
optim = {} | |
# loss function 1 (gaps between rows) | |
def loss1(g): | |
return (g-1.2)*(g-1.2) #looks best | |
# loss function 2 (spaces in rows) | |
def loss2(w,s,n): | |
n0 = sum(n) | |
l2 = 0 | |
i = 0 | |
ln = len(n) | |
for item in n: | |
if s[i] > 0: | |
#l2 = l2 + item*(s[i] - 0.1*w)*(s[i] - 0.1*w)/n0 | |
l2 = l2 + (s[i] - 0.1*w)*(s[i] - 0.1*w)/ln | |
else: | |
l2 = l2 + 10 | |
i = i + 1 | |
return l2 | |
# loss function | |
def lossf(w,g,s,n): | |
l1 = loss1(g) | |
l2 = loss2(w,s,n) | |
l = l1 + l2 + (l1 - l2)*(l1 - l2) | |
return l | |
# spaces in rows | |
def ss(w,g,n): | |
s = [0]*len(n) | |
i = 0 | |
for item in n: | |
s[i] = (math.pi/w + math.pi*i*g-n[i])/(n[i] - 1) | |
i = i + 1 | |
return s | |
# max n in row for grid search | |
def nmax(k,n): | |
return math.floor(n-((k-1)*k/2))/k | |
# nrow for grid search | |
def nrow(n): | |
return {'max':round(math.sqrt(n)*3/4),'min':round(max(math.sqrt(n)/4,1))} | |
# grid search | |
def grid(n): | |
out = [] | |
for k in np.arange (0.01,1,0.01): #(0.01,1,0.005): | |
for kk in np.arange (1.15,1.25,0.01): #(1,1.35,0.01) | |
g = kk | |
w = k | |
s = ss(w,g,n) | |
l1 = loss1(g) | |
l2 = loss2(w,s,n) | |
l = l1 + l2 + (l1-l2)*(l1-l2) | |
try: | |
if l < mmin: | |
out = [w,g] | |
mmin = l | |
except: | |
out = [w,g] | |
mmin = l | |
#print(out,mmin) | |
return {'w':out[0],'g':out[1],'loss':mmin} | |
#outwriter.writerow(row) | |
# recursion | |
def go(level,n,nrows,n0): | |
# print(n,level) | |
global optim | |
# print('optim:',optim) | |
global ll | |
while level < (nrows-1): | |
#conservative (slow): | |
# jmin = max(level+2,n[level-1]+1) | |
# jmax = int(nmax(nrows-level,n0-sum(n[0:level]))+1) | |
#faster (aritmetic series): | |
if level > 0: | |
if (nrows>1): | |
q = 2*(n0-nrows*n[0])/(nrows-1)/nrows | |
jmin = math.floor(n[0] + level*q - 0.5) #better with -1, but slower | |
jmax = math.ceil(n[0] + level*q + 0.5) #better with +1, but slower | |
else: | |
jmin = max(level+2+round(sqrt(level)),n[level-1]+1) | |
jmax = int(nmax(nrows-level,n0-sum(n[0:level]))+1) | |
else: | |
jmin = max(level+2,n[level-1]+1) | |
jmax = int(nmax(nrows-level,n0-sum(n[0:level]))+1) | |
for j in range(jmin,jmax): | |
n[level] = j | |
go(level+1,n,nrows,n0) | |
return False | |
n[level] = n0-sum(n) | |
# print("calculating:",level,k,n) | |
opt = grid(n) | |
# print(opt,ll) | |
try: | |
if ll > opt['loss']: | |
optim = opt.copy() | |
optim['n'] = n.copy() | |
ll = optim['loss'] | |
except: | |
optim = opt.copy() | |
optim['n'] = n.copy() | |
ll = optim['loss'] | |
# print('optim2:',optim) | |
n[level] = 0 | |
return True | |
# for each reasonable number of rows: | |
nr = nrow(n0) | |
for k in range(nr['min'],nr['max']+1): | |
n = [0]*k | |
optim = {} | |
ll = 100000000 | |
go(0,n,k,n0) | |
print("final optim:",optim) | |
print("time:",timeit.default_timer() - start) | |
#example of results: | |
#n = 200: | |
#final optim: {'n': [44, 48, 52, 56], 'loss': 6.0494609377272378e-05, 'w': 0.069999999999999993, 'g': 1.2000000000000002} | |
#time: 23.457229251012905 | |
#final optim: {'n': [34, 37, 40, 43, 46], 'loss': 0.003021820005212728, 'w': 0.089999999999999997, 'g': 1.1900000000000002} | |
#time: 51.52483937999932 | |
#final optim: {'n': [24, 28, 31, 35, 39, 43], 'loss': 0.0009935459225664401, 'w': 0.13, 'g': 1.2300000000000002} | |
#time: 131.58585535301245 | |
#final optim: {'n': [18, 21, 25, 29, 32, 36, 39], 'loss': 0.000796945129917957, 'w': 0.17000000000000001, 'g': 1.1900000000000002} | |
#time: 284.771323367022 | |
#final optim: {'n': [12, 16, 19, 23, 27, 31, 34, 38], 'loss': 0.00031275649495655434, 'w': 0.25, 'g': 1.2000000000000002} | |
#time: 579.2367971060157 | |
#final optim: {'n': [8, 11, 15, 19, 22, 26, 29, 33, 37], 'loss': 0.00043985954926300044, 'w': 0.39000000000000001, 'g': 1.2000000000000002} | |
#time: 1167.0518377900007 | |
#final optim: {'n': [4, 8, 11, 15, 18, 22, 25, 29, 32, 36], 'loss': 0.00064177079858304589, 'w': 0.72999999999999998, 'g': 1.2000000000000002} | |
#time: 2341.9838014570123 | |
#final optim: {'n': [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 35], 'loss': 0.0087001372112743003, 'w': 0.98999999999999999, 'g': 1.1400000000000001} | |
#time: 4631.68083341801 | |
#n = 751 (Euro Parliament) | |
#final optim: {'n': [98, 101, 104, 107, 110, 113, 118], 'loss': 0.0062929076050250469, 'w': 0.029999999999999999, 'g': 1.1899999999999999} | |
#time: 217.3275479080039 | |
#final optim: {'n': [85, 88, 90, 93, 95, 98, 100, 102], 'loss': 0.068194024500854655, 'w': 0.029999999999999999, 'g': 1.1599999999999999} | |
#time: 570.2674658489996 | |
#final optim: {'n': [71, 74, 77, 80, 83, 87, 90, 93, 96], 'loss': 0.014035298736485213, 'w': 0.040000000000000001, 'g': 1.1799999999999999} | |
#time: 1331.067573258013 | |
#final optim: {'n': [60, 63, 67, 70, 73, 77, 80, 83, 87, 91], 'loss': 0.0032756194901112823, 'w': 0.050000000000000003, 'g': 1.1899999999999999} | |
#time: 2816.806992516009 | |
#final optim: {'n': [51, 54, 58, 61, 65, 68, 72, 75, 79, 82, 86], 'loss': 0.0013354982259395371, 'w': 0.060000000000000005, 'g': 1.1899999999999999} | |
#time: 5686.576568382996 | |
#final optim: {'n': [44, 47, 51, 54, 57, 61, 64, 68, 71, 74, 78, 82], 'loss': 0.0016497989012379932, 'w': 0.069999999999999993, 'g': 1.1899999999999999} | |
#time: 10905.816249452997 | |
#final optim: {'n': [34, 38, 42, 46, 50, 54, 58, 62, 66, 70, 73, 77, 81], 'loss': 0.0025690587369525267, 'w': 0.089999999999999997, 'g': 1.25} | |
#time: 21918.771677729994 | |
#final optim: {'n': [31, 34, 38, 41, 45, 48, 52, 55, 59, 62, 66, 69, 73, 78], 'loss': 0.00099189844185821208, 'w': 0.099999999999999992, 'g': 1.1899999999999999} | |
#time: 44362.27788667599 | |
# ... | |
# n = 81 (CZ Senate) | |
#final optim: {'n': [39, 42], 'loss': 0.00015113520955957024, 'w': 0.080000000000000002, 'g': 1.2} | |
#time: 2.056351581995841 | |
#final optim: {'n': [23, 27, 31], 'loss': 0.00074731223308436374, 'w': 0.13, 'g': 1.2} | |
#time: 3.672953786997823 | |
#final optim: {'n': [15, 18, 22, 26], 'loss': 0.0017986444368775138, 'w': 0.20000000000000001, 'g': 1.1899999999999999} | |
#time: 5.949895355995977 | |
#final optim: {'n': [9, 13, 16, 20, 23], 'loss': 0.0004283781313137963, 'w': 0.34000000000000002, 'g': 1.2} | |
#time: 10.962005101988325 | |
#final optim: {'n': [5, 8, 12, 15, 19, 22], 'loss': 0.0011676166427925727, 'w': 0.62, 'g': 1.1899999999999999} | |
#time: 21.31037131600897 | |
#final optim: {'n': [3, 6, 9, 12, 14, 17, 20], 'loss': 0.017012374030482232, 'w': 0.98999999999999999, 'g': 1.1499999999999999} | |
#time: 41.0609374709893 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="600" height="300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"><![CDATA[ | |
.axis path, .axis line { fill: none; stroke: rgb(0, 0, 0); shape-rendering: crispedges; } | |
path, line { stroke: rgb(187, 187, 187); stroke-width: 1px; } | |
text.shadow { stroke: rgb(128, 128, 128); stroke-width: 1px; opacity: 0.9; } | |
.half { fill: rgb(136, 136, 136); opacity: 0.5; }]]></style></defs><g transform="translate(0,0)"><path d="M-199.8257942412914,-223.76249005549806A300,300 0 0,1 223.7624900554981,-199.82579424129133L0,0Z" transform="translate(300,300)" class="half"></path><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="27.16848405695871" y="288.7790621748258" transform="rotate(-87.64488258746817,27.16848405695871,288.7790621748258)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="54.13155551558449" y="288.77979175868575" transform="rotate(-87.38711950302829,54.13155551558449,288.77979175868575)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="81.10082621416824" y="288.78080653474404" transform="rotate(-87.06599868564834,81.10082621416824,288.78080653474404)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="108.07889957036923" y="288.7822770923823" transform="rotate(-86.65488712423621,108.07889957036923,288.7822770923823)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="135.07007339694954" y="288.7845236149999" transform="rotate(-86.1097921291605,135.07007339694954,288.7845236149999)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="162.08198532902924" y="288.7882060854911" transform="rotate(-85.35246380821499,162.08198532902924,288.7882060854911)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="189.12963582860576" y="288.7948705025289" transform="rotate(-84.22898915028358,189.12963582860576,288.7948705025289)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="29.105538213530995" y="265.6614486200492" transform="rotate(-82.77572244371993,29.105538213530995,265.6614486200492)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="216.2470603535514" y="288.8088805128348" transform="rotate(-82.38918460146385,216.2470603535514,288.8088805128348)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="56.31572744185806" y="265.4289084063911" transform="rotate(-81.92542453408902,56.31572744185806,265.4289084063911)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="83.60439118231363" y="265.13369720556034" transform="rotate(-80.84699877953062,83.60439118231363,265.13369720556034)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="110.83594092680124" y="265.69978349479703" transform="rotate(-79.72249615429729,110.83594092680124,265.69978349479703)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="243.5314081226261" y="288.8468993690087" transform="rotate(-78.82732299494896,243.5314081226261,288.8468993690087)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="138.35649391472555" y="265.3727774678659" transform="rotate(-77.90885954543094,138.35649391472555,265.3727774678659)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="32.997839182709434" y="242.79168193040354" transform="rotate(-77.90656229997168,32.997839182709434,242.79168193040354)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="60.712526495556645" y="242.39192686762644" transform="rotate(-76.46372956514975,60.712526495556645,242.39192686762644)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="165.8142566175601" y="266.2173215024999" transform="rotate(-75.86885671841335,165.8142566175601,266.2173215024999)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="88.65489111475833" y="241.89695759759306" transform="rotate(-74.62799887341288,88.65489111475833,241.89695759759306)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="38.817293333442244" y="220.33483022182685" transform="rotate(-73.03740215622344,38.817293333442244,220.33483022182685)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="116.3588383516763" y="243.11880938476475" transform="rotate(-72.79010518435842,116.3588383516763,243.11880938476475)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="193.90153271075897" y="265.9279026558893" transform="rotate(-72.19627641452877,193.90153271075897,265.9279026558893)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="67.28203021160748" y="219.87802047045085" transform="rotate(-71.00203459621048,67.28203021160748,219.87802047045085)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="144.94887675579946" y="242.66923356048835" transform="rotate(-69.70792696170136,144.94887675579946,242.66923356048835)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="96.19288259240692" y="219.3440796956712" transform="rotate(-68.4089989672951,96.19288259240692,219.3440796956712)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="46.52189733681505" y="198.45298129572615" transform="rotate(-68.16824201247525,46.52189733681505,198.45298129572615)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="173.21441925733944" y="244.56986731650565" transform="rotate(-66.38524962861169,173.21441925733944,244.56986731650565)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="222.86113207202754" y="265.51244993351224" transform="rotate(-65.91134768117112,222.86113207202754,265.51244993351224)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="124.56683898193612" y="221.36952173258408" transform="rotate(-65.8577142144195,124.56683898193612,221.36952173258408)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="75.96458819902224" y="198.0916130765924" transform="rotate(-65.54033962727121,75.96458819902224,198.0916130765924)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="56.05604133531842" y="177.30407273076023" transform="rotate(-63.299081868727,56.05604133531842,177.30407273076023)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="106.12964489601866" y="197.74050656302452" transform="rotate(-62.18999906117742,106.12964489601866,197.74050656302452)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="154.71239330984747" y="221.13822889334995" transform="rotate(-61.50699437797175,154.71239330984747,221.13822889334995)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="red" text-anchor="middle" class="shadow" x="203.33566463573143" y="244.55814895643442" transform="rotate(-60.16356367877398,203.33566463573143,244.55814895643442)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="86.68136376006599" y="177.2305229346511" transform="rotate(-60.07864465833197,86.68136376006599,177.2305229346511)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="135.33992980631302" y="200.76992703236334" transform="rotate(-58.92532324448061,135.33992980631302,200.76992703236334)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="67.35091032055088" y="157.04075192986681" transform="rotate(-58.42992172497878,67.35091032055088,157.04075192986681)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="184.08019399082426" y="224.43756443603345" transform="rotate(-56.901642538809995,184.08019399082426,224.43756443603345)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="252.11023951586665" y="268.0678161869442" transform="rotate(-56.30523071067785,252.11023951586665,268.0678161869442)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="118.34822423211652" y="177.34050812715245" transform="rotate(-55.970999155059644,118.34822423211652,177.34050812715245)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="99.33504971903939" y="157.48416651156217" transform="rotate(-54.6169496893927,99.33504971903939,157.48416651156217)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="80.32498082231353" y="137.80927435041966" transform="rotate(-53.56076158123054,80.32498082231353,137.80927435041966)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="167.44735836431587" y="201.22011948158664" transform="rotate(-53.3060617942422,167.44735836431587,201.22011948158664)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="148.52059243162716" y="181.62122158052443" transform="rotate(-51.992932274541715,148.52059243162716,181.62122158052443)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="132.70481025678762" y="158.3841884713671" transform="rotate(-49.75199924894193,132.70481025678762,158.3841884713671)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="235.81146359421777" y="245.04885943966917" transform="rotate(-49.433510760878335,235.81146359421777,245.04885943966917)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="113.81075196102566" y="139.0318386113392" transform="rotate(-49.1552547204534,113.81075196102566,139.0318386113392)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="pink" text-anchor="middle" class="shadow" x="94.88460932413274" y="119.74844786981521" transform="rotate(-48.69160143748232,94.88460932413274,119.74844786981521)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="217.01747198185316" y="225.62465043934145" transform="rotate(-48.1308509430192,217.01747198185316,225.62465043934145)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="198.11457101529703" y="206.3707179661911" transform="rotate(-47.41803544900833,198.11457101529703,206.3707179661911)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="182.89331410262906" y="183.32227411384545" transform="rotate(-45.105129210512644,182.89331410262906,183.32227411384545)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="163.9161062327935" y="164.2033875440623" transform="rotate(-45.06054130460282,163.9161062327935,164.2033875440623)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="110.9247081581648" y="102.98863090577976" transform="rotate(-43.82244129373407,110.9247081581648,102.98863090577976)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="129.97703265816313" y="122.0410843974337" transform="rotate(-43.69355975151413,129.97703265816313,122.0410843974337)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="149.03042869595225" y="141.09465985561516" transform="rotate(-43.532999342824155,149.03042869595225,141.09465985561516)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="128.3295040010553" y="87.65079152271187" transform="rotate(-38.953281149985855,128.3295040010553,87.65079152271187)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="147.68710371106175" y="106.66617810057221" transform="rotate(-38.23186478257486,147.68710371106175,106.66617810057221)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="181.30136621110123" y="148.77109921049708" transform="rotate(-38.12815033466393,181.30136621110123,148.77109921049708)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="214.93392857772568" y="190.86317493007226" transform="rotate(-37.93442835920669,214.93392857772568,190.86317493007226)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="167.13293014027707" y="125.67541672781167" transform="rotate(-37.31399943670641,167.13293014027707,125.67541672781167)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="200.73435703472498" y="167.81074277188532" transform="rotate(-36.904196626783076,200.73435703472498,167.81074277188532)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="234.34574152439092" y="209.9593929242443" transform="rotate(-36.098138207264384,234.34574152439092,209.9593929242443)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="146.9733734961243" y="73.84563431519257" transform="rotate(-34.084121006237595,146.9733734961243,73.84563431519257)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="267.9939922669997" y="252.1595464978271" transform="rotate(-33.78313842640671,267.9939922669997,252.1595464978271)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="254.03430240115262" y="229.09900777105452" transform="rotate(-32.95567384058556,254.03430240115262,229.09900777105452)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="166.78015956904324" y="93.04672222524496" transform="rotate(-32.770169813635604,166.78015956904324,93.04672222524496)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="200.4221743595498" y="135.549999276155" transform="rotate(-31.195759364725035,200.4221743595498,135.549999276155)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="186.79925160700702" y="112.30794063307579" transform="rotate(-31.09499953058868,186.79925160700702,112.30794063307579)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="166.72174997056237" y="61.67280137058424" transform="rotate(-29.21496086248939,166.72174997056237,61.67280137058424)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="220.6055989125678" y="155.0027701099153" transform="rotate(-28.703264043053494,220.6055989125678,155.0027701099153)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="234.07851905826845" y="178.33882523988" transform="rotate(-28.450821269404997,234.07851905826845,178.33882523988)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="187.08283732734012" y="81.30637997389886" transform="rotate(-27.30847484469635,187.08283732734012,81.30637997389886)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="207.797924250557" y="101.1495642106245" transform="rotate(-24.87599962447095,207.797924250557,101.1495642106245)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="187.43209470319724" y="51.22015307797844" transform="rotate(-24.345800718741145,187.43209470319724,51.22015307797844)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="220.99895641064924" y="124.73339961890642" transform="rotate(-24.263368394786156,220.99895641064924,124.73339961890642)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="254.55902526549244" y="198.25074745370102" transform="rotate(-24.065425471509585,254.55902526549244,198.25074745370102)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="208.41079084372623" y="71.55175239828822" transform="rotate(-21.846779875757065,208.41079084372623,71.55175239828822)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="242.1006294908202" y="145.16030710934984" transform="rotate(-20.502331459323912,242.1006294908202,145.16030710934984)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="208.9549257324583" y="42.56313397442079" transform="rotate(-19.476640574992928,208.9549257324583,42.56313397442079)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="255.0250359112618" y="169.14001490608297" transform="rotate(-18.96721417960333,255.0250359112618,169.14001490608297)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="229.88179770659204" y="92.33161941867172" transform="rotate(-18.65699971835322,229.88179770659204,92.33161941867172)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="242.73084962237576" y="116.47945479489908" transform="rotate(-17.330977424847248,242.73084962237576,116.47945479489908)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="276.0328072227509" y="218.97303087751686" transform="rotate(-16.477836920292773,276.0328072227509,218.97303087751686)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="230.57036458176725" y="63.87141047332739" transform="rotate(-16.38508490681781,230.57036458176725,63.87141047332739)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="231.13489677887264" y="35.76422820557042" transform="rotate(-14.607480431244696,231.13489677887264,35.76422820557042)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="252.79094900458807" y="85.95789178238027" transform="rotate(-12.43799981223546,252.79094900458807,85.95789178238027)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="264.77982850294114" y="138.484653609795" transform="rotate(-12.301398875594359,264.77982850294114,138.484653609795)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="276.7691003853941" y="191.01322152825702" transform="rotate(-12.032712735754785,276.7691003853941,191.01322152825702)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="288.7598193301797" y="243.54867706768744" transform="rotate(-11.26104614213557,288.7598193301797,243.54867706768744)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="253.36035198237636" y="58.33509088211281" transform="rotate(-10.92338993787854,253.36035198237636,58.33509088211281)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="265.30010183286015" y="110.9088495869184" transform="rotate(-10.398586454908354,265.30010183286015,110.9088495869184)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="253.81191849470645" y="30.872508531152334" transform="rotate(-9.73832028749645,253.81191849470645,30.872508531152334)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="277.20091795347366" y="163.51818820297245" transform="rotate(-9.483607089801666,277.20091795347366,163.51818820297245)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="276.2557418115246" y="82.10339885806019" transform="rotate(-6.21899990611773,276.2557418115246,82.10339885806019)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="276.5738223978474" y="54.99306281430114" transform="rotate(-5.4616949689392555,276.5738223978474,54.99306281430114)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="276.8223139478551" y="27.923282130347616" transform="rotate(-4.869160143748232,276.8223139478551,27.923282130347616)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="288.17935685466415" y="135.11234128819478" transform="rotate(-4.100466291864777,288.17935685466415,135.11234128819478)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="orange" text-anchor="middle" class="shadow" x="288.37671746317295" y="108.10303441580547" transform="rotate(-3.4661954849694325,288.37671746317295,108.10303441580547)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="300" y="188.5648503453569" transform="rotate(-1.4210854715202004e-14,300,188.5648503453569)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="300" y="80.81350729086722" transform="rotate(0,300,80.81350729086722)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="300" y="161.62701458173444" transform="rotate(0,300,161.62701458173444)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="300" y="26.937835763622445" transform="rotate(0,300,26.937835763622445)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="300" y="215.50268610897928" transform="rotate(0,300,215.50268610897928)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="300" y="53.875671527244805" transform="rotate(0,300,53.875671527244805)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="311.62328253682716" y="108.10303441580547" transform="rotate(3.466195484969461,311.62328253682716,108.10303441580547)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="311.8206431453359" y="135.11234128819478" transform="rotate(4.100466291864777,311.8206431453359,135.11234128819478)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="323.17768605214496" y="27.923282130347616" transform="rotate(4.869160143748232,323.17768605214496,27.923282130347616)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="323.4261776021526" y="54.99306281430114" transform="rotate(5.4616949689392555,323.4261776021526,54.99306281430114)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="323.7442581884754" y="82.10339885806019" transform="rotate(6.218999906117745,323.7442581884754,82.10339885806019)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="322.79908204652634" y="163.51818820297245" transform="rotate(9.48360708980168,322.79908204652634,163.51818820297245)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="346.18808150529355" y="30.872508531152334" transform="rotate(9.738320287496464,346.18808150529355,30.872508531152334)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="yellow" text-anchor="middle" class="shadow" x="334.69989816713985" y="110.9088495869184" transform="rotate(10.398586454908354,334.69989816713985,110.9088495869184)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="346.6396480176237" y="58.33509088211281" transform="rotate(10.92338993787854,346.6396480176237,58.33509088211281)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="311.2401806698203" y="243.54867706768744" transform="rotate(11.261046142135555,311.2401806698203,243.54867706768744)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="323.23089961460585" y="191.01322152825702" transform="rotate(12.0327127357548,323.23089961460585,191.01322152825702)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="335.2201714970589" y="138.48465360979506" transform="rotate(12.301398875594359,335.2201714970589,138.48465360979506)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="347.2090509954119" y="85.9578917823803" transform="rotate(12.437999812235475,347.2090509954119,85.9578917823803)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="368.8651032211274" y="35.76422820557042" transform="rotate(14.607480431244696,368.8651032211274,35.76422820557042)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="369.42963541823275" y="63.87141047332739" transform="rotate(16.38508490681781,369.42963541823275,63.87141047332739)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="323.9671927772492" y="218.97303087751686" transform="rotate(16.477836920292773,323.9671927772492,218.97303087751686)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="357.2691503776243" y="116.47945479489908" transform="rotate(17.330977424847248,357.2691503776243,116.47945479489908)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="370.118202293408" y="92.33161941867172" transform="rotate(18.656999718353234,370.118202293408,92.33161941867172)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="344.97496408873826" y="169.14001490608297" transform="rotate(18.967214179603346,344.97496408873826,169.14001490608297)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="391.04507426754174" y="42.56313397442079" transform="rotate(19.476640574992928,391.04507426754174,42.56313397442079)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="357.89937050917973" y="145.16030710934987" transform="rotate(20.502331459323926,357.89937050917973,145.16030710934987)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="391.5892091562738" y="71.55175239828822" transform="rotate(21.846779875757065,391.5892091562738,71.55175239828822)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="345.44097473450756" y="198.25074745370102" transform="rotate(24.06542547150957,345.44097473450756,198.25074745370102)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="379.00104358935084" y="124.73339961890645" transform="rotate(24.26336839478614,379.00104358935084,124.73339961890645)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="412.56790529680285" y="51.22015307797852" transform="rotate(24.34580071874116,412.56790529680285,51.22015307797852)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="392.20207574944305" y="101.1495642106245" transform="rotate(24.875999624470964,392.20207574944305,101.1495642106245)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="412.91716267265986" y="81.30637997389886" transform="rotate(27.30847484469635,412.91716267265986,81.30637997389886)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="365.9214809417316" y="178.33882523988007" transform="rotate(28.45082126940501,365.9214809417316,178.33882523988007)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="379.3944010874322" y="155.0027701099153" transform="rotate(28.7032640430535,379.3944010874322,155.0027701099153)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="433.2782500294376" y="61.67280137058424" transform="rotate(29.214960862489384,433.2782500294376,61.67280137058424)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="413.2007483929931" y="112.30794063307587" transform="rotate(31.0949995305887,413.2007483929931,112.30794063307587)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="399.57782564045016" y="135.549999276155" transform="rotate(31.195759364725042,399.57782564045016,135.549999276155)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="433.2198404309568" y="93.04672222524496" transform="rotate(32.770169813635604,433.2198404309568,93.04672222524496)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="345.9656975988474" y="229.09900777105446" transform="rotate(32.95567384058554,345.9656975988474,229.09900777105446)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="332.0060077330002" y="252.15954649782708" transform="rotate(33.78313842640669,332.0060077330002,252.15954649782708)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="453.0266265038758" y="73.8456343151926" transform="rotate(34.08412100623762,453.0266265038758,73.8456343151926)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="365.654258475609" y="209.9593929242443" transform="rotate(36.09813820726438,365.654258475609,209.9593929242443)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="399.26564296527505" y="167.81074277188532" transform="rotate(36.904196626783076,399.26564296527505,167.81074277188532)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="432.867069859723" y="125.67541672781175" transform="rotate(37.313999436706446,432.867069859723,125.67541672781175)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="385.0660714222743" y="190.86317493007226" transform="rotate(37.934428359206684,385.0660714222743,190.86317493007226)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="418.69863378889886" y="148.7710992104971" transform="rotate(38.12815033466394,418.69863378889886,148.7710992104971)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="452.3128962889383" y="106.66617810057221" transform="rotate(38.23186478257487,452.3128962889383,106.66617810057221)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="471.6704959989447" y="87.65079152271198" transform="rotate(38.953281149985855,471.6704959989447,87.65079152271198)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="450.9695713040478" y="141.09465985561522" transform="rotate(43.532999342824176,450.9695713040478,141.09465985561522)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="470.022967341837" y="122.0410843974337" transform="rotate(43.693559751514144,470.022967341837,122.0410843974337)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="489.0752918418352" y="102.98863090577981" transform="rotate(43.82244129373408,489.0752918418352,102.98863090577981)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="436.0838937672065" y="164.2033875440623" transform="rotate(45.060541304602836,436.0838937672065,164.2033875440623)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="417.106685897371" y="183.32227411384545" transform="rotate(45.10512921051264,417.106685897371,183.32227411384545)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="401.885428984703" y="206.37071796619114" transform="rotate(47.41803544900836,401.885428984703,206.37071796619114)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="382.9825280181468" y="225.62465043934142" transform="rotate(48.13085094301916,382.9825280181468,225.62465043934142)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="505.11539067586733" y="119.74844786981527" transform="rotate(48.69160143748231,505.11539067586733,119.74844786981527)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="486.1892480389744" y="139.03183861133925" transform="rotate(49.155254720453414,486.1892480389744,139.03183861133925)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="364.18853640578214" y="245.04885943966914" transform="rotate(49.43351076087831,364.18853640578214,245.04885943966914)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="467.2951897432125" y="158.38418847136714" transform="rotate(49.75199924894192,467.2951897432125,158.38418847136714)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="aqua" text-anchor="middle" class="shadow" x="451.47940756837284" y="181.62122158052443" transform="rotate(51.99293227454173,451.47940756837284,181.62122158052443)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="432.5526416356842" y="201.22011948158666" transform="rotate(53.30606179424222,432.5526416356842,201.22011948158666)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="519.6750191776864" y="137.80927435041966" transform="rotate(53.56076158123054,519.6750191776864,137.80927435041966)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="500.6649502809606" y="157.48416651156214" transform="rotate(54.616949689392676,500.6649502809606,157.48416651156214)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="481.6517757678835" y="177.34050812715253" transform="rotate(55.97099915505966,481.6517757678835,177.34050812715253)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="347.8897604841333" y="268.0678161869441" transform="rotate(56.30523071067782,347.8897604841333,268.0678161869441)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="415.9198060091758" y="224.43756443603354" transform="rotate(56.90164253881002,415.9198060091758,224.43756443603354)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="532.649089679449" y="157.04075192986681" transform="rotate(58.42992172497877,532.649089679449,157.04075192986681)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="464.66007019368703" y="200.76992703236334" transform="rotate(58.92532324448062,464.66007019368703,200.76992703236334)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="513.318636239934" y="177.2305229346511" transform="rotate(60.078644658331946,513.318636239934,177.2305229346511)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="396.66433536426854" y="244.55814895643442" transform="rotate(60.16356367877396,396.66433536426854,244.55814895643442)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="445.28760669015253" y="221.13822889335" transform="rotate(61.506994377971786,445.28760669015253,221.13822889335)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="493.8703551039813" y="197.74050656302452" transform="rotate(62.1899990611774,493.8703551039813,197.74050656302452)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="543.9439586646816" y="177.30407273076025" transform="rotate(63.299081868727,543.9439586646816,177.30407273076025)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="524.0354118009778" y="198.0916130765925" transform="rotate(65.54033962727121,524.0354118009778,198.0916130765925)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="475.43316101806397" y="221.36952173258413" transform="rotate(65.85771421441952,475.43316101806397,221.36952173258413)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="377.13886792797246" y="265.51244993351224" transform="rotate(65.9113476811711,377.13886792797246,265.51244993351224)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="426.78558074266056" y="244.56986731650568" transform="rotate(66.38524962861169,426.78558074266056,244.56986731650568)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="553.4781026631848" y="198.45298129572615" transform="rotate(68.16824201247523,553.4781026631848,198.45298129572615)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="503.80711740759307" y="219.34407969567127" transform="rotate(68.40899896729513,503.80711740759307,219.34407969567127)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="455.05112324420054" y="242.66923356048835" transform="rotate(69.70792696170136,455.05112324420054,242.66923356048835)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="532.7179697883926" y="219.87802047045085" transform="rotate(71.00203459621048,532.7179697883926,219.87802047045085)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="406.098467289241" y="265.9279026558893" transform="rotate(72.19627641452875,406.098467289241,265.9279026558893)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="483.6411616483237" y="243.11880938476475" transform="rotate(72.79010518435842,483.6411616483237,243.11880938476475)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="561.1827066665578" y="220.33483022182693" transform="rotate(73.03740215622346,561.1827066665578,220.33483022182693)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="511.34510888524176" y="241.89695759759311" transform="rotate(74.62799887341288,511.34510888524176,241.89695759759311)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="purple" text-anchor="middle" class="shadow" x="434.18574338243997" y="266.2173215024999" transform="rotate(75.86885671841337,434.18574338243997,266.2173215024999)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="539.2874735044434" y="242.39192686762647" transform="rotate(76.46372956514975,539.2874735044434,242.39192686762647)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="567.0021608172906" y="242.79168193040366" transform="rotate(77.9065622999717,567.0021608172906,242.79168193040366)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="461.6435060852745" y="265.3727774678659" transform="rotate(77.90885954543093,461.6435060852745,265.3727774678659)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="356.46859187737385" y="288.8468993690087" transform="rotate(78.82732299494894,356.46859187737385,288.8468993690087)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="489.1640590731987" y="265.69978349479703" transform="rotate(79.72249615429732,489.1640590731987,265.69978349479703)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="516.3956088176865" y="265.13369720556034" transform="rotate(80.84699877953062,516.3956088176865,265.13369720556034)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="543.684272558142" y="265.4289084063911" transform="rotate(81.92542453408902,543.684272558142,265.4289084063911)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="383.7529396464486" y="288.8088805128348" transform="rotate(82.38918460146385,383.7529396464486,288.8088805128348)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="570.8944617864689" y="265.66144862004916" transform="rotate(82.77572244371993,570.8944617864689,265.66144862004916)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="410.8703641713942" y="288.79487050252885" transform="rotate(84.22898915028355,410.8703641713942,288.79487050252885)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="437.91801467097076" y="288.7882060854912" transform="rotate(85.35246380821503,437.91801467097076,288.7882060854912)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="464.9299266030505" y="288.7845236149999" transform="rotate(86.1097921291605,464.9299266030505,288.7845236149999)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="491.9211004296307" y="288.78227709238223" transform="rotate(86.65488712423621,491.9211004296307,288.78227709238223)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="518.8991737858317" y="288.78080653474416" transform="rotate(87.06599868564835,518.8991737858317,288.78080653474416)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="545.8684444844155" y="288.77979175868563" transform="rotate(87.38711950302829,545.8684444844155,288.77979175868563)"></text><text font-family="FontAwesome" font-size="25.81542594013814" fill="blue" text-anchor="middle" class="shadow" x="572.8315159430413" y="288.7790621748258" transform="rotate(87.64488258746816,572.8315159430413,288.7790621748258)"></text></g></svg> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<!--<script src="d3.v3.js"></script>--> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"> <!-- note: http://stackoverflow.com/questions/20032426/fontawesome-doesnt-display-in-firefox --> | |
<link href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/united/bootstrap.min.css" rel="stylesheet"> | |
<style> | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
path, line { | |
stroke:#bbb; | |
stroke-width:1 | |
} | |
/*http://www.d3noob.org/2013/01/adding-drop-shadow-to-allow-text-to.html*/ | |
text.shadow { | |
stroke: gray; | |
stroke-width: 1px; | |
opacity: 0.9; | |
} | |
.half { | |
fill: #888; | |
opacity:0.5; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="navbar navbar-default"> | |
<div class="container"> | |
<div class="navbar-header"> | |
<span class="navbar-brand">Hemicycle - for parliaments/councils of any size, with draggable majority arc</span> | |
</div> | |
</div> | |
</div> | |
<div id="chart"></div> | |
<div class="alert alert-info"> | |
The <strong>algorithm.py</strong> calculates optimal number of representatives in each row for several numbers of rows (+ size of icons and gap between the rows). These numbers are used as parameters for the chart. | |
<br/><em>It may be slow for big parliaments, but it is needed just once for any number (e.g., 200 representatives took about 1 hour, due to the grid search - further optimization possible, my trial using steepest descent algorithm did not converge many times).</em> | |
</div> | |
<div class="col-lg-4"> | |
<div class="bs-component"> | |
<div class="list-group"> | |
<a href="#" class="list-group-item active">Legend</a> | |
<a href="#" class="list-group-item"> | |
<div id="legend"></div> | |
</a> | |
</div> | |
</div> | |
<div class="alert alert-info"> | |
The legend is also created as a svg picture. | |
</div> | |
</div> | |
<script> | |
// 2:1! | |
var margin = {top: 0, right: 0, bottom: 0, left: 0}, | |
width = 600 - margin.left - margin.right, | |
height = 300 - margin.top - margin.bottom; | |
var svg = d3.select("#chart").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
/*examples of parliaments*/ | |
/*Plasy 2010*/ | |
/*var groups = [ | |
{'name':'KSČM','n':2,'color':'red'}, | |
{'name':'ČSSD','n':4,'color':'orange'}, | |
{'name':'KDU-ČSL','n':2,'color':'yellow'}, | |
{'name':'TOP 09','n':2,'color':'violet'}, | |
{'name':'ODS','n':5,'color':'blue'} | |
];*/ | |
/*Czech Republic 2013*/ | |
var groups = [ | |
{'name':'KSČM','n':33,'color':'red'}, | |
{'name':'Úsvit','n':14,'color':'pink'}, | |
{'name':'ČSSD','n':50,'color':'orange'}, | |
{'name':'KDU-ČSL','n':14,'color':'yellow'}, | |
{'name':'ANO','n':47,'color':'aqua'}, | |
{'name':'TOP 09','n':26,'color':'purple'}, | |
{'name':'ODS','n':16,'color':'blue'} | |
]; | |
/*Czech Republic Senate 2013*/ | |
/*var groups = [ | |
{'name':'KSČM','n':2,'color':'red'}, | |
{'name':'ČSSD','n':46,'color':'orange'}, | |
{'name':'SPOZ','n':1,'color':'pink'}, | |
{'name':'Severočeši','n':2,'color':'darkred'}, | |
{'name':'Piráti','n':1,'color':'black'}, | |
{'name':'Zelení','n':1,'color':'green'}, | |
{'name':'KDU-ČSL','n':5,'color':'yellow'}, | |
{'name':'Nezávislí kand.','n':1,'color':'gray'}, | |
{'name':'Nestraníci','n':1,'color':'aqua'}, | |
{'name':'TOP 09 + STAN','n':4,'color':'purple'}, | |
{'name':'Ostravak','n':1,'color':'brown'}, | |
{'name':'ODS','n':15,'color':'blue'}, | |
{'name':'Neobsazeno','n':1,'color':'white'} | |
];*/ | |
/*European Parliament 2014*/ | |
/*var groups = [ | |
{'name':'GUE-NGL','n':52,'color':'darkred'}, | |
{'name':'Greens-EFA','n':50,'color':'green'}, | |
{'name':'S&D','n':191,'color':'red'}, | |
{'name':'ALDE','n':67,'color':'yellow'}, | |
{'name':'EPP','n':221,'color':'blue'}, | |
{'name':'ECR','n':70,'color':'darkblue'}, | |
{'name':'EFDD','n':48,'color':'aqua'}, | |
{'name':'Non-inscrits','n':52,'color':'gray'} | |
];*/ | |
/*Plasy*/ | |
/*var h = { | |
'n': [6,9], | |
'g': 1.19, | |
'w': 0.52, | |
}*/ | |
/*CZ*/ | |
/*var h = { | |
'n': [33,37,40,43,47], | |
'g': 1.17, | |
'w': 0.09, | |
} | |
var h = { | |
'n': [24,28,31,35,39,43], | |
'g': 1.23, | |
'w': 0.13, | |
} | |
var h = { | |
'n': [18,21,25,29,32,36,39], | |
'g': 1.19, | |
'w': 0.17, | |
}*/ | |
var h = { | |
'n': [8,11,15,19,22,26,29,33,37], | |
'g': 1.20, | |
'w': 0.39, | |
} | |
/*var h = { | |
'n': [4,8,11,15,18,22,25,29,32,36], | |
'g': 1.20, | |
'w': 0.73, | |
}*/ | |
/*CZ Senate*/ | |
/*var h = { | |
'n': [9,13,16,20,23], | |
'g': 1.2, | |
'w': 0.34, | |
}*/ | |
/*EP*/ | |
/*var h = { | |
'n': [85,88,90,93,95,98,100,102], | |
'g': 1.16, | |
'w': 0.03, | |
} | |
var h = { | |
'n': [31,34,38,41,45,48,52,55,59,62,66,69,73,78], | |
'g': 1.19, | |
'w': 0.1, | |
}*/ | |
//max radius (for scales) | |
rmax = 1 + h['n'].length *h['g']*h['w']; | |
var | |
xScale = d3.scale.linear() | |
.domain([-1*rmax, rmax]) | |
.range([0, width]), | |
yScale = d3.scale.linear() | |
.domain([0, rmax]) | |
.range([height,0]) | |
x0Scale = d3.scale.linear() | |
.domain([0, 2*rmax]) | |
.range([0, width]); | |
//generate data: 1 representative ~ 1 datum | |
data = []; | |
s = []; | |
for (i in h['n']) { | |
s.push((Math.PI/h['w'] + Math.PI*i*h['g']-h['n'][i])/(h['n'][i] - 1)); | |
ninrow = h['n'][i]; | |
radwidth = Math.PI/(h['n'][i]+(h['n'][i]-1)*s[i]); | |
radspace = radwidth*s[i]; | |
r = 1 + i*h['g']*h['w']; | |
for (j=0;j<ninrow;j++) { | |
x = Math.cos(radwidth*(0.5+j)+j*radspace)*r; | |
y = Math.sin(radwidth*(0.5+j)+j*radspace)*r; | |
rot = -1*(radwidth*(0.5+j)+j*radspace)/Math.PI*180+90; | |
data.push({'x':x,'y':y,'rot':rot}); | |
} | |
} | |
//sort data by rotation (representatives from 1 parl. groups together) | |
data.sort(function(x,y) { | |
if (x['rot'] < y['rot']) return -1; | |
if (x['rot'] > y['rot']) return 1; | |
return 0 | |
}); | |
//add colors and names to data - may be used later | |
i = 0; | |
for (gkey in groups) { | |
group = groups[gkey]; | |
for (j=0;j<group['n'];j++) { | |
data[i]['color'] = group['color']; | |
data[i]['name'] = group['name']; | |
i++; | |
} | |
} | |
/* MAJORITY ARC */ | |
var angle = [{'startangle':0,'endangle':Math.PI/2}]; | |
var arci = d3.svg.arc() | |
.startAngle(function(d){return d.startangle}) | |
.endAngle(function(d){return d.endangle}) | |
.outerRadius(x0Scale(rmax)) | |
.innerRadius(0); | |
var position = [xScale(0),yScale(0)]; | |
//http://stackoverflow.com/questions/8538651/d3-update-data-and-update-graph | |
var arc = svg.selectAll('.half') | |
.data(angle) | |
.enter() | |
.append("path") | |
.attr("d",arci) | |
.attr("transform", "translate(" + position + ")") | |
.attr("class","half"); | |
//http://stackoverflow.com/questions/15303342/how-to-apply-drag-behavior-to-a-d3-svg-arc | |
var drag = d3.behavior.drag() | |
.on("drag", function(d,i) { | |
alpha1 = Math.atan((d3.event.x - xScale(0))/(-d3.event.y + yScale(0))); | |
x2 = d3.event.dx + d3.event.x; | |
y2 = d3.event.dy + d3.event.y; | |
alpha2 = Math.atan((x2 - xScale(0))/(-y2 + yScale(0))); | |
alpha = alpha2-alpha1; | |
angle[0]['startangle'] += alpha; | |
angle[0]['endangle'] += alpha; | |
/*angle[0]['startangle'] = Math.min(0,angle[0]['startangle']); | |
angle[0]['startangle'] = Math.max(Math.PI/2,angle[0]['startangle']); | |
angle[0]['endangle'] = Math.min(Math.PI/2,angle[0]['endangle']); | |
angle[0]['endangle'] = Math.max(Math.PI,angle[0]['endangle']);*/ | |
arc.attr("d",arci); // redraw the arc | |
/*position[0] += d3.event.dx; | |
position[1] += d3.event.dy; | |
d3.select(this) | |
.attr("transform", function(d,i){ | |
return "translate(" + position + ")" | |
})*/ | |
}); | |
arc.call(drag); | |
// creating HEMICYCLE | |
var icons = svg.selectAll(".icon") | |
.data(data) | |
.enter().append("text") | |
.attr('font-family', 'FontAwesome') | |
.attr('font-size',x0Scale(h['w']*1.15)) //the icon is about 1.15times higher then wide | |
.attr('fill', function(d) {return d.color;}) | |
.attr('text-anchor',"middle") | |
.attr('class', 'shadow') | |
.attr('x',function(d) {return xScale(d.x);}) | |
.attr('y',function(d) {return yScale(d.y);}) | |
.attr("transform",function(d) {return "rotate("+d.rot+","+xScale(d.x)+","+yScale(d.y)+")"}) | |
.text('\uf007'); | |
//custom text | |
svg.append("text") | |
.attr('font-family', 'sans-serif') | |
.attr('font-size',x0Scale(h['w']*1)) //adjust as needed | |
.attr('font-weight','bold') | |
.attr('text-anchor',"middle") | |
.attr('fill', '#444') | |
.attr('x',xScale(0)) | |
.attr('y',yScale(0)) | |
.text("CZ 2013"); | |
/* LEGEND */ | |
heightleg = x0Scale(groups.length * h['w']*1.15*h['g']); | |
var svgleg = d3.select("#legend").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", heightleg + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
//sorting for legend | |
groups.sort(function(x,y) { | |
if (x.n > y.n) return -1; | |
if (x.n < y.n) return 1; | |
return 0; | |
}); | |
//creating legend | |
var iconsleg = svgleg.selectAll(".iconleg") | |
.data(groups) | |
.enter().append("text") | |
.attr('font-family', 'FontAwesome') | |
.attr('font-size',x0Scale(h['w']*1.15)) | |
.attr('fill', function(d) {return d.color;}) | |
.attr('text-anchor',"middle") | |
.attr('class', 'shadow') | |
.attr('x',x0Scale(h['w']*1.15)) | |
.attr('y',function(d,i) {return (i+1)*x0Scale(h['w']*1.15);}) | |
.text('\uf007'); | |
var textleg = svgleg.selectAll(".textleg") | |
.data(groups) | |
.enter().append("text") | |
.attr('font-family', 'sans-serif') | |
.attr('font-size',x0Scale(h['w']*0.9)) | |
//.attr('fill', function(d) {return d.color;}) | |
//.attr('text-anchor',"middle") | |
//.attr('class', 'shadow') | |
.attr('x',x0Scale(2*h['w']*1.15)) | |
.attr('y',function(d,i) {return (i+1)*x0Scale(h['w']*1.15);}) | |
.text(function(d){return d.name + ' (' + d.n + ')'}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment