| OLD | NEW |
| 1 // - DATA ASSUMPTIONS - | 1 // - DATA ASSUMPTIONS - |
| 2 // | 2 // |
| 3 // MEETINGS | 3 // MEETINGS |
| 4 // + all meetings have an id and a start data | 4 // + all meetings have an id and a start data |
| 5 // | 5 // |
| 6 // MEMBERS | 6 // MEMBERS |
| 7 // + all members have a "short" name | 7 // + all members have a "short" name |
| 8 // | 8 // |
| 9 // GROUPS | 9 // GROUPS |
| 10 // + all groups have a "short" name | 10 // + all groups have a "short" name |
| 11 | 11 |
| 12 var WTO = {}; | 12 var WTO = {}; |
| 13 | 13 |
| 14 WTO.ALL_MEMBERS = "WTO"; | |
| 15 WTO.BASE_URL = "http://wto-informals.org"; | |
| 16 // http://kids.yahoo.com/reference/world-factbook/country/xx--World | 14 // http://kids.yahoo.com/reference/world-factbook/country/xx--World |
| 17 // TODO(rae) P2 This should actually be from the same source as our population | 15 // TODO(rae) P2 This should actually be from the same source as our population |
| 18 // data | 16 // data |
| 19 // TODO(rae) P3 we should update this automagically | 17 // TODO(rae) P3 we should update this automagically |
| 20 WTO.WORLD_POPULATION = 6602224175; | 18 WTO.WORLD_POPULATION = 6602224175; |
| 21 WTO.MONTHS = [ "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", | 19 WTO.MONTHS = [ "???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", |
| 22 "Sep", "Oct", "Nov", "Dec" ]; | 20 "Sep", "Oct", "Nov", "Dec" ]; |
| 23 | 21 |
| 24 function glog(msg) { | 22 function glog(msg) { |
| 25 if (WTO && WTO.view && WTO.view.debug) { | 23 if (WTO && WTO.view && WTO.view.debug) { |
| 26 google.maps.Log.write(msg); | 24 google.maps.Log.write(msg); |
| 27 } | 25 } |
| 28 } | 26 } |
| 29 | 27 |
| 30 /* Each callback just saves the relevant data. */ | 28 /* Each callback just saves the relevant data. */ |
| 31 function member_callback(members) { WTO.members = members; } | 29 function member_callback(members) { WTO.members = members; } |
| 32 function meeting_callback(meetings) { WTO.meetings = meetings; } | 30 function meeting_callback(meetings) { WTO.meetings = meetings; } |
| 33 function group_callback(groups) { WTO.groups = groups; } | 31 WTO.receiveGroupDetails = function(xmlHttpRequest) { |
| 32 var data = eval(xmlHttpRequest.responseText); |
| 33 WTO.groups = {}; |
| 34 // Convert the list of groups to a map by groupname to group |
| 35 for (var i = 0; i < data.length; i++) { |
| 36 WTO.groups[data[i].name] = data[i]; |
| 37 } |
| 38 WTO.drawGroups("name"); |
| 39 } |
| 34 | 40 |
| 35 | 41 |
| 36 /* Represents the perspective we've chosen. | 42 /* Represents the perspective we've chosen. |
| 37 TODO(rae): encode this in the URL so people can pass filters etc around | 43 TODO(rae): encode this in the URL so people can pass filters etc around |
| 38 */ | 44 */ |
| 39 WTO.view = { | 45 WTO.view = { |
| 40 /* The currently selected display order for groups (and, implicitly the (TODO) | 46 /* The currently selected display order for groups (and, implicitly the (TODO) |
| 41 * parenthetical information displayed beside the group.) */ | 47 * parenthetical information displayed beside the group.) */ |
| 42 //"groupOrder": "members", | 48 //"groupOrder": "members", |
| 43 /* The "tags" entry is actually a list of indices into the WTO.tagList array | 49 /* The "tags" entry is actually a list of indices into the WTO.tagList array |
| 44 * of tags. It's parsed at load time and put in the URL in a friendly | 50 * of tags. It's parsed at load time and put in the URL in a friendly |
| 45 * format. */ | 51 * format. */ |
| 46 "tags": [], | 52 "tags": [], |
| 47 "debug":true | 53 "debug":true |
| 48 }; | 54 }; |
| 49 | 55 |
| 50 WTO.drawGroups = function(order) { | 56 WTO.drawGroups = function(order) { |
| 51 glog("drawing groups: " + order); | 57 glog("drawing groups: " + order); |
| 52 | 58 |
| 53 GROUP_ORDERS = { | 59 GROUP_ORDERS = { |
| 54 "members": function(group) { | 60 "members": function(group) { |
| 55 return $$.keys(group["members"]).length; | 61 return $$.keys(group["members"]).length || 0; |
| 56 }, | 62 }, |
| 57 "gdp": function(group) { | 63 "gdp": function(group) { |
| 58 var pop = 0; | 64 var pop = 0; |
| 59 for (var iso in group["members"]) { | 65 for (var iso in group["members"]) { |
| 60 gdp += (WTO.members[iso].gdp || 0); | 66 gdp += (WTO.members[iso].gdp || 0); |
| 61 } | 67 } |
| 62 return gdp; | 68 return gdp; |
| 63 }, | 69 }, |
| 64 "pop": function(group) { | 70 "pop": function(group) { |
| 65 var pop = 0; | 71 var pop = 0; |
| 66 for (var iso in group["members"]) { | 72 for (var iso in group["members"]) { |
| 67 if (!WTO.members[iso]) { | 73 if (!WTO.members[iso]) { |
| 68 glog("iso " + iso + " unknown"); | 74 glog("iso " + iso + " unknown"); |
| 69 continue; | 75 continue; |
| 70 } | 76 } |
| 71 pop += (WTO.members[iso].pop || 0); | 77 pop += (WTO.members[iso].pop || 0); |
| 72 } | 78 } |
| 73 return pop; | 79 return pop; |
| 74 }, | 80 }, |
| 75 "trade": function(group) { | 81 "trade": function(group) { |
| 76 var trade = 0; | 82 var trade = 0; |
| 77 for (var iso in group["members"]) { | 83 for (var iso in group["members"]) { |
| 78 trade += (WTO.members[iso].trade || 0); | 84 trade += (WTO.members[iso].trade || 0); |
| 79 } | 85 } |
| 80 return trade; | 86 return trade; |
| 81 }, | 87 }, |
| 82 "name": function(group) { | 88 "name": function(group) { |
| 83 return group["short"]; | 89 return group["name"]; |
| 84 } | 90 } |
| 85 // TODO(rae) P2 implement other ordering functions | 91 // TODO(rae) P2 implement other ordering functions |
| 86 // per-cap gdp, trade (need data) | 92 // per-cap gdp, trade (need data) |
| 87 }; | 93 }; |
| 88 | 94 |
| 89 function percent(denominator) { | 95 function percent(denominator) { |
| 90 return function(pop, name) { | 96 return function(value, name) { |
| 91 pop = (pop / denominator) * 100; | 97 value = (value / denominator) * 100; |
| 92 if (pop < 1 && pop > 0) { | 98 if (value < 1 && value > 0) { |
| 93 return "[<1%] " + name; | 99 return "[<1%] " + name; |
| 94 } else { | 100 } else { |
| 95 return "[" + Math.round(pop) + "%] " + name; | 101 return "[" + Math.round(value) + "%] " + name; |
| 96 } | 102 } |
| 97 } | 103 } |
| 98 } | 104 } |
| 99 | 105 |
| 100 function integer(val, name) { | 106 function integer(val, name) { |
| 101 return "[" + Math.round(val) + "] " + name; | 107 return "[" + Math.round(val) + "] " + name; |
| 102 } | 108 } |
| 103 | 109 |
| 104 GROUP_FORMATS = { | 110 GROUP_FORMATS = { |
| 105 "pop": percent(WTO.WORLD_POPULATION), | 111 "pop": percent(WTO.WORLD_POPULATION), |
| (...skipping 11 matching lines...) Show 10 above Show 10 below |
| 117 if (orderE) { orderE.className = "jslink"; } | 123 if (orderE) { orderE.className = "jslink"; } |
| 118 } | 124 } |
| 119 var orderE = $$.get("groups_by_" + order); | 125 var orderE = $$.get("groups_by_" + order); |
| 120 if (orderE) { | 126 if (orderE) { |
| 121 orderE.className = "jslink current"; | 127 orderE.className = "jslink current"; |
| 122 WTO.view.groupOrder = order; | 128 WTO.view.groupOrder = order; |
| 123 } | 129 } |
| 124 | 130 |
| 125 // Cache whatever values we'll use to sort the list | 131 // Cache whatever values we'll use to sort the list |
| 126 var sortCache = {}; | 132 var sortCache = {}; |
| 127 for (var group in WTO.groups) { | 133 for (var name in WTO.groups) { |
| 128 //TODO(rae) P1 make the assumption about "short" existing more robust | 134 //TODO(rae) P1 make the assumption about "short" existing more robust |
| 129 sortCache[group] = GROUP_ORDERS[order](WTO.groups[group]); | 135 sortCache[name] = GROUP_ORDERS[order](WTO.groups[name]); |
| 130 } | 136 } |
| 131 | 137 |
| 132 function cacheComparator(left, right) { | 138 function cacheComparator(left, right) { |
| 133 left = sortCache[left]; | 139 left = sortCache[left]; |
| 134 right = sortCache[right]; | 140 right = sortCache[right]; |
| 135 // TODO(rae) P3 this special-casing of name is lame. | 141 // TODO(rae) P3 this special-casing of name is lame. |
| 136 if (order == "name") { | 142 if (order == "name") { |
| 137 if (left < right) { return -1; } | 143 if (left < right) { return -1; } |
| 138 else if (left > right) { return 1; } | 144 else if (left > right) { return 1; } |
| 139 else { return 0; } | 145 else { return 0; } |
| 140 } else { | 146 } else { |
| 141 // descending sort | 147 // descending sort |
| 142 return right - left; | 148 return right - left; |
| 143 } | 149 } |
| 144 } | 150 } |
| 145 | 151 |
| 146 var groups = $$.keys(WTO.groups); | 152 var groups = $$.keys(WTO.groups); |
| 147 groups.sort(cacheComparator); | 153 groups.sort(cacheComparator); |
| 148 | 154 |
| 149 var groupSelectE = $$.get("groupList"); | 155 var groupSelectE = $$.get("groupList"); |
| 150 groupSelectE.innerHTML = ""; | 156 groupSelectE.innerHTML = ""; |
| 151 | 157 |
| 152 // Map from tagname to true for speed. | 158 // Map from tagname to true for speed. |
| 153 // TODO(rae) P2 remove fake seed-tags when we have real tags | 159 // TODO(rae) P2 remove fake seed-tags when we have real tags |
| 154 var tags = { "fake": true, "not real": true, "imaginary": true }; | 160 var tags = { "fake": true, "not real": true, "imaginary": true }; |
| 155 | 161 |
| 156 for (var i = 0; i < groups.length; i++) { | 162 for (var i = 0; i < groups.length; i++) { |
| 157 var short_ = groups[i]; | 163 var group = WTO.groups[groups[i]]; |
| 158 var group = WTO.groups[short_]; | 164 var formal = group["formal_name"]; |
| 159 var official = group["official"]; | 165 var name = group["name"]; |
| 160 | 166 |
| 161 var optionE = $$.make("option"); | 167 var optionE = $$.make("option"); |
| 162 optionE.value = short_; | 168 optionE.value = name; |
| 163 optionE.name = official; | 169 optionE.name = name; |
| 164 | 170 |
| 165 var name = short_; | 171 var display = name; |
| 166 if (official && official.length < 32) { | 172 if (formal && formal.length < 32) { |
| 167 name = official; | 173 display = formal; |
| 168 } | 174 } |
| 169 | 175 |
| 170 if (GROUP_FORMATS[order]) { | 176 if (GROUP_FORMATS[order]) { |
| 171 optionE.innerHTML = GROUP_FORMATS[order](sortCache[short_], name); | 177 optionE.innerHTML = GROUP_FORMATS[order](sortCache[name], display); |
| 172 } else { | 178 } else { |
| 173 optionE.innerHTML = name; | 179 optionE.innerHTML = display; |
| 174 } | 180 } |
| 175 | 181 |
| 176 groupSelectE.appendChild(optionE); | 182 groupSelectE.appendChild(optionE); |
| 177 if (group["tags"]) { | 183 if (group["tags"]) { |
| 178 for (var i = 0; i < group["tags"].length; i++) { | 184 for (var i = 0; i < group["tags"].length; i++) { |
| 179 tags[group["tags"][i]] = true; | 185 tags[group["tags"][i]] = true; |
| 180 } | 186 } |
| 181 } | 187 } |
| 182 } | 188 } |
| 183 | 189 |
| 184 WTO.tagList = $$.keys(tags).sort(); | 190 WTO.tagList = $$.keys(tags).sort(); |
| 191 WTO.drawTagList(); |
| 185 | 192 |
| 186 }; | 193 }; |
| 187 | 194 |
| 188 WTO.drawTagList = function() { | 195 WTO.drawTagList = function() { |
| 189 var tagListE = $$.get("groupTags"); | 196 var tagListE = $$.get("groupTags"); |
| 190 | 197 |
| 191 // see it with a clickable null-option. | 198 // see it with a clickable null-option. |
| 192 tagListE.innerHTML = "<option value='-'>-</option>"; | 199 tagListE.innerHTML = "<option value='-'>-</option>"; |
| 193 | 200 |
| 194 for(var i = 0; i < WTO.tagList.length; i++) { | 201 for(var i = 0; i < WTO.tagList.length; i++) { |
| (...skipping 634 matching lines...) Show 10 above Show 10 below |
| 829 WTO.map.setZoom(Math.max(2, WTO.map.getBoundsZoomLevel(bounds))); | 836 WTO.map.setZoom(Math.max(2, WTO.map.getBoundsZoomLevel(bounds))); |
| 830 WTO.map.setCenter(bounds.getCenter()); | 837 WTO.map.setCenter(bounds.getCenter()); |
| 831 | 838 |
| 832 WTO.geocoder = new google.maps.ClientGeocoder(); | 839 WTO.geocoder = new google.maps.ClientGeocoder(); |
| 833 | 840 |
| 834 } | 841 } |
| 835 | 842 |
| 836 function init() { | 843 function init() { |
| 837 if (GBrowserIsCompatible()) { | 844 if (GBrowserIsCompatible()) { |
| 838 WTO.initMap(); | 845 WTO.initMap(); |
| 846 } else { |
| 847 $$.get("map").innerHTML = "<b>Sorry, this site needs a browser that is suppo
rted by Google Maps.</b>"; |
| 839 } | 848 } |
| 849 |
| 850 HttpRequest("/GroupDetails", null, WTO.receiveGroupDetails); |
| 851 |
| 840 WTO.loaded = true; | 852 WTO.loaded = true; |
| 841 | 853 |
| 842 WTO.drawGroups("members"); | 854 //WTO.drawTagList(); |
| 843 WTO.drawTagList(); | |
| 844 | 855 |
| 845 $$.get("tagList").addEventListener("click", WTO.handleTagRemove, false); | 856 //$$.get("tagList").addEventListener("click", WTO.handleTagRemove, false); |
| 846 $$.get("groupOrder").addEventListener("click", WTO.handleGroupOrder, false); | 857 $$.get("groupOrder").addEventListener("click", WTO.handleGroupOrder, false); |
| 847 $$.get("groupList").addEventListener("change", WTO.handleGroupChange, false); | 858 //$$.get("groupList").addEventListener("change", WTO.handleGroupChange, false)
; |
| 848 $$.get("meetings").addEventListener("click", WTO.handleMeetingClick, false); | 859 //$$.get("meetings").addEventListener("click", WTO.handleMeetingClick, false); |
| 849 | 860 |
| 850 // FIXME handle case where members aren't loaded yet (impossible?) | 861 // FIXME handle case where members aren't loaded yet (impossible?) |
| 851 WTO.populateGroup(WTO.ALL_MEMBERS); | 862 //WTO.populateGroup(WTO.ALL_MEMBERS); |
| 852 | 863 |
| 853 WTO.fixTableWidths(); | 864 WTO.fixTableWidths(); |
| 854 //$$.get("groupTdiv").addEventListener('click', WTO.handleGroupClick, false); | 865 //$$.get("groupTdiv").addEventListener('click', WTO.handleGroupClick, false); |
| 855 $$.get("members").addEventListener('click', WTO.handleMembersClick, false); | 866 $$.get("members").addEventListener('click', WTO.handleMembersClick, false); |
| 856 | 867 |
| 857 // Synthesize a click to sort by name | 868 // Synthesize a click to sort by name |
| 858 WTO.handleMembersClick({"target": $$.get("memberThead0") }); | 869 WTO.handleMembersClick({"target": $$.get("memberThead0") }); |
| 859 | 870 |
| 860 WTO.renderMeetings(); | 871 WTO.renderMeetings(); |
| 861 | 872 |
| 862 } | 873 } |
| 863 | 874 |
| 864 | 875 |
| OLD | NEW |