From d16101e848db3f427a848b45249a286cc303c293 Mon Sep 17 00:00:00 2001 From: fkloft Date: Sun, 15 Dec 2013 16:19:18 +0100 Subject: [PATCH] portal-counts: display graphs for level distribution --- plugins/portal-counts.user.js | 238 +++++++++++++++++++++++++++++----- 1 file changed, 207 insertions(+), 31 deletions(-) diff --git a/plugins/portal-counts.user.js b/plugins/portal-counts.user.js index 520e0514..47fb7ae6 100644 --- a/plugins/portal-counts.user.js +++ b/plugins/portal-counts.user.js @@ -2,7 +2,7 @@ // @id iitc-plugin-portals-count@yenky // @name IITC plugin: Show total counts of portals // @category Info -// @version 0.0.10.@@DATETIMEVERSION@@ +// @version 0.1.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -19,6 +19,7 @@ // PLUGIN START //////////////////////////////////////////////////////// /* whatsnew +* 0.1.0 : display graphs * 0.0.10 : show in nav drawer on mobile devices * 0.0.9 : fix for new intel map * 0.0.8 : use dialog() instead of alert() @@ -31,74 +32,157 @@ */ // use own namespace for plugin -window.plugin.portalcounts = function() {}; +window.plugin.portalcounts = { + BAR_TOP: 20, + BAR_HEIGHT: 180, + BAR_WIDTH: 25, + BAR_PADDING: 5, + RADIUS_INNER: 70, + RADIUS_OUTER: 100, + CENTER_X: 200, + CENTER_Y: 100, +}; //count portals for each level available on the map window.plugin.portalcounts.getPortals = function(){ //console.log('** getPortals'); - var retval=false; + var self = window.plugin.portalcounts; var displayBounds = map.getBounds(); - window.plugin.portalcounts.enlP = 0; - window.plugin.portalcounts.resP = 0; - window.plugin.portalcounts.neuP = 0; - - window.plugin.portalcounts.PortalsEnl = new Array(); - window.plugin.portalcounts.PortalsRes = new Array(); + self.enlP = 0; + self.resP = 0; + self.neuP = 0; + + self.PortalsEnl = new Array(); + self.PortalsRes = new Array(); for(var level = window.MAX_PORTAL_LEVEL; level > 0; level--){ - window.plugin.portalcounts.PortalsEnl[level] = 0; - window.plugin.portalcounts.PortalsRes[level] = 0; + self.PortalsEnl[level] = 0; + self.PortalsRes[level] = 0; } - + $.each(window.portals, function(i, portal) { - retval=true; var level = portal.options.level; var team = portal.options.team; // just count portals in viewport if(!displayBounds.contains(portal.getLatLng())) return true; switch (team){ case 1 : - window.plugin.portalcounts.resP++; - window.plugin.portalcounts.PortalsRes[level]++; + self.resP++; + self.PortalsRes[level]++; break; case 2 : - window.plugin.portalcounts.enlP++; - window.plugin.portalcounts.PortalsEnl[level]++; + self.enlP++; + self.PortalsEnl[level]++; break; default: - window.plugin.portalcounts.neuP++; + self.neuP++; break; } }); - + //get portals informations from IITC var minlvl = getMinPortalLevel(); + var total = self.neuP + self.enlP + self.resP; - var counts = ''; - if(retval) { - counts += ''; //'+window.plugin.portalcounts.enlP+' Portal(s)'; + var counts = ''; + if(total > 0) { + counts += '
EnlightenedResistance
'; //'+self.enlP+' Portal(s)'; for(var level = window.MAX_PORTAL_LEVEL; level > 0; level--){ counts += ''; if(minlvl > level) counts += ''; else - counts += ''; + counts += ''; counts += ''; } - counts += ''; + counts += ''; counts += ''; + counts += self.neuP; + counts += '
EnlightenedResistance
Level '+level+'zoom in to see portals in this level'+window.plugin.portalcounts.PortalsEnl[level]+''+window.plugin.portalcounts.PortalsRes[level]+''+self.PortalsEnl[level]+''+self.PortalsRes[level]+'
Total:'+window.plugin.portalcounts.enlP+''+window.plugin.portalcounts.resP+'
Total:'+self.enlP+''+self.resP+'
Neutral:'; if(minlvl > 0) counts += 'zoom in to see unclaimed portals'; else - counts += window.plugin.portalcounts.neuP; - counts += '
'; + var svg = $('').css("padding-top", 10); + + var all = self.PortalsRes.map(function(val,i){return val+self.PortalsEnl[i]}); + all[0] = self.neuP; + + // bar graphs + self.makeBar(self.PortalsEnl, "Enl", COLORS[2], 0 ).appendTo(svg); + self.makeBar(all , "All", "#FFFFFF", 1*(self.BAR_WIDTH + self.BAR_PADDING)).appendTo(svg); + self.makeBar(self.PortalsRes, "Res", COLORS[1], 2*(self.BAR_WIDTH + self.BAR_PADDING)).appendTo(svg); + + // pie graph + var g = $("") + .attr("transform", self.format("translate(%s,%s)", self.CENTER_X, self.CENTER_Y)) + .appendTo(svg); + + // inner parts - factions + self.makePie(0, self.resP/total, COLORS[1]).appendTo(g); + self.makePie(self.resP/total, (self.neuP + self.resP)/total, COLORS[0]).appendTo(g); + self.makePie((self.neuP + self.resP)/total, 1, COLORS[2]).appendTo(g); + + // outer part - levels + var angle = 0; + for(var i=self.PortalsRes.length-1;i>=0;i--) { + if(!self.PortalsRes[i]) + continue; + + var diff = self.PortalsRes[i] / total; + self.makeRing(angle, angle+diff, COLORS_LVL[i]).appendTo(g); + angle += diff; + } + + var diff = self.neuP / total; + self.makeRing(angle, angle+diff, COLORS_LVL[0]).appendTo(g); + angle += diff; + + for(var i=0;i") + .attr({ + x1: self.resP") + .attr({ + x1: self.resP' + counts + '', title: 'Portal counts: ' + title, + width: 'auto' }); } } +window.plugin.portalcounts.makeBar = function(portals, text, color, shift) { + var self = window.plugin.portalcounts; + var g = $("").attr("transform", "translate("+shift+",0)"); + var sum = portals.reduce(function(a,b){ return a+b }); + var top = self.BAR_TOP; + + if(sum != 0) { + for(var i=portals.length-1;i>=0;i--) { + if(!portals[i]) + continue; + var height = self.BAR_HEIGHT * portals[i] / sum; + $("") + .attr({ + x: 0, + y: top, + width: self.BAR_WIDTH, + height: height, + fill: COLORS_LVL[i] + }) + .appendTo(g); + top += height; + } + } + + $('') + .html(text) + .attr({ + x: self.BAR_WIDTH * 0.5, + y: self.BAR_TOP * 0.75, + fill: color, + "text-anchor": "middle" + }) + .appendTo(g); + + return g; +}; + +window.plugin.portalcounts.makePie = function(startAngle, endAngle, color) { + var self = window.plugin.portalcounts; + var large_arc = (endAngle - startAngle) > 0.5 ? 1 : 0; + + startAngle = 0.5 - startAngle; + endAngle = 0.5 - endAngle; + + var p1x = Math.sin(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p1y = Math.cos(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p2x = Math.sin(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p2y = Math.cos(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + + return $("") + .attr({ + fill: color, + d: self.format("M %s,%s A %s,%s 0 %s 1 %s,%s L 0,0 z", p1x,p1y, self.RADIUS_INNER,self.RADIUS_INNER, large_arc, p2x,p2y) + }); +}; + +window.plugin.portalcounts.makeRing = function(startAngle, endAngle, color) { + var self = window.plugin.portalcounts; + var large_arc = (endAngle - startAngle) > 0.5 ? 1 : 0; + + startAngle = 0.5 - startAngle; + endAngle = 0.5 - endAngle; + + var p1x = Math.sin(startAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p1y = Math.cos(startAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p2x = Math.sin(endAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p2y = Math.cos(endAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p3x = Math.sin(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p3y = Math.cos(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p4x = Math.sin(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p4y = Math.cos(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + + return $("") + .attr({ + fill: color, + d: self.format("M %s,%s ", p1x, p1y) + + self.format("A %s,%s 0 %s 1 %s,%s ", self.RADIUS_OUTER,self.RADIUS_OUTER, large_arc, p2x,p2y) + + self.format("L %s,%s ", p3x,p3y) + + self.format("A %s,%s 0 %s 0 %s,%s ", self.RADIUS_INNER,self.RADIUS_INNER, large_arc, p4x,p4y) + + "Z" + }); +}; + +window.plugin.portalcounts.format = function(str) { + var re = /%s/; + for(var i = 1; i < arguments.length; i++) { + str = str.replace(re, arguments[i]); + } + return str; +} + window.plugin.portalcounts.onPaneChanged = function(pane) { if(pane == "plugin-portalcounts") window.plugin.portalcounts.getPortals(); @@ -129,7 +305,7 @@ var setup = function() { $('#toolbox').append(' Portal counts'); } - $('head').append('