Skip to content

Commit

Permalink
color countries by type of peers online
Browse files Browse the repository at this point in the history
  • Loading branch information
_pants committed Feb 1, 2013
1 parent 4f0bd8f commit 708aafd
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 26 deletions.
2 changes: 1 addition & 1 deletion app/_css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -6915,7 +6915,7 @@ circle.get {
fill: #ffcc66;
}

path.p2p {
path.connection {
fill: none;
stroke-width: 1;
stroke: white;
Expand Down
9 changes: 7 additions & 2 deletions app/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function makeLogger(prefix) {
};
}

//var log = makeLogger('helpers');
var log = makeLogger('helpers');

function randomChoice(collection) {
if (_.isArray(collection)) {
Expand Down Expand Up @@ -54,7 +54,12 @@ function deleteByPath(obj, path) {
path = path.split('.');
var name = path[0], i = 0, l = path.length;
for (; i<l-1 && path[i+1]; ++i) {
obj = obj[name];
try {
obj = obj[name];
} catch(e) {
log('deleteByPath(', obj, path, ') caused', e);
return; // XXX
}
name = path[i+1];
}
if (i == l - 1 && name && obj) { // XXX && obj check necessary?
Expand Down
8 changes: 5 additions & 3 deletions app/js/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,17 @@ angular.module('app.services', [])

function handleSync(msg) {
// XXX use modelValidatorSrvc to validate update before accepting
var data = msg.data, path = data.path, value = data.value;
if (data.delete) {
var data = msg.data, path = data.path, value = data.value, state = data.state;
if (state) {
merge(model, state);
} else if (data.delete) {
deleteByPath(model, path);
} else {
deleteByPath(model, path);
merge(model, value, path);
}
$rootScope.$apply();
log.debug('handleSync applied sync:\npath:', path || '""', '\nvalue:', value, '\ndelete:', data.delete);
//log.debug('handleSync applied sync:\npath:', path || '""', '\nvalue:', value, '\ndelete:', data.delete);
}

syncSubscriptionKey = {chan: MODEL_SYNC_CHANNEL, cb: handleSync};
Expand Down
55 changes: 48 additions & 7 deletions app/js/vis.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ angular.module('app.vis', [])
scale: 1400,
translate: [500, 350],
style: {
giveModeColor: '#00ff80',
getModeColor: '#ffcc66',
countryOpacityMin: 0,
countryOpacityMax: .5,
self: {
r: 5
},
Expand Down Expand Up @@ -76,18 +80,55 @@ function VisCtrl($scope, $window, logFactory, modelSrvc, CONFIG) {
$scope.self = $scope.project(loc);
}, true);

$scope.opacityByCountry = {};
var countryOpacityScale = d3.scale.linear()
.domain([0, 1000])
.range([0, .2])
.clamp(true);
$scope.fillByCountry = {};
var maxGiveGet = 0,
countryOpacityScale = d3.scale.linear()
.range([CONFIG.style.countryOpacityMin, CONFIG.style.countryOpacityMax])
.clamp(true),
countryFillScale = d3.scale.linear(),
GMC = d3.rgb(CONFIG.style.getModeColor),
getModeColorPrefix = 'rgba('+GMC.r+','+GMC.g+','+GMC.b+',',
countryFillInterpolator = d3.interpolateRgb(CONFIG.style.giveModeColor,
CONFIG.style.getModeColor);

function updateFill(country) {
var npeers = getByPath(model, 'countries.'+country+'.npeers.online');
if (!npeers) return;
var censors = getByPath(model, 'countries.'+country).censors,
scaledOpacity = countryOpacityScale(npeers.giveGet),
colorPrefix, fill;
if (_.isNaN(scaledOpacity)) {
log.error('scaledOpacity is NaN');
debugger;
}
if (censors) {
if (npeers.giveGet !== npeers.get) {
log.warn('npeers.giveGet (', npeers.giveGet, ') !== npeers.get (', npeers.get, ') for censoring country', country);
}
colorPrefix = getModeColorPrefix;
} else {
countryFillScale.domain([-npeers.giveGet, npeers.giveGet]);
var scaledFill = countryFillScale(npeers.get - npeers.give),
color = d3.rgb(countryFillInterpolator(scaledFill));
colorPrefix = 'rgba('+color.r+','+color.g+','+color.b+',';
}
fill = colorPrefix+(scaledOpacity||0)+')';
$scope.fillByCountry[country] = fill;
}

var unwatchAllCountries = $scope.$watch('model.countries', function(countries) {
if (!countries) return;
unwatchAllCountries();
_.forEach(countries, function(stats, country) {
$scope.$watch('model.countries.'+country+'.nusers.online', function(nusers) {
$scope.opacityByCountry[country] = countryOpacityScale(nusers) || 0;
$scope.$watch('model.countries.'+country+'.npeers.online', function(npeers) {
if (!npeers) return;
if (npeers.giveGet > maxGiveGet) {
maxGiveGet = npeers.giveGet;
countryOpacityScale.domain([0, maxGiveGet]);
_.forEach(countries, updateFill);
} else {
updateFill(country);
}
});
});
}, true);
Expand Down
4 changes: 2 additions & 2 deletions app/partials/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
{{ model.settings.email }} ·
{{ model.connectivity.gtalk }} to Google Talk ·
XXX Lantern friends online ·
connected to {{ model.connectivity.peers.lifetime.length }} peers in {{ ncountries || 'XXX' }} countries ·
connected to {{ model.connectivity.peers.current.length }} peers in {{ ncountries || 'XXX' }} countries ·
{{ model.transfers.bpsUp }} M/s up ·
{{ model.transfers.bpsDn }} M/s down ·
{{ model.transfers.bytesTotal || '0B' }} lifetime
{{ model.transfers.bytesTotal || 'XXX M' }} lifetime
</span>
<span ng-hide="model.connectivity.peers.lifetime.length">
{{ model.connectivity.gtalk }} to Google Talk ·
Expand Down
6 changes: 3 additions & 3 deletions app/partials/vis.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<svg id="vis" ng-controller="VisCtrl" ng-show="model.showVis">
<g id="countries">
<g ng-repeat="d in countryGeometries">
<title>{{ d.alpha2 | i18n }}: {{ model.countries[d.alpha2].nusers.online || 0 }} users online</title><!-- XXX i18n -->
<path d="{{ countryPaths[d.alpha2] }}" fill="rgba(255, 255, 255, {{ opacityByCountry[d.alpha2] || 0 }})" class="{{ d.alpha2 }}"/>
<title ui-if="d.alpha2">{{ d.alpha2 | i18n }}: {{ model.countries[d.alpha2].npeers.online.giveGet || 0 }} peers online, {{ model.countries[d.alpha2].npeers.online.give || 0 }} in Give Mode, {{ model.countries[d.alpha2].npeers.online.get || 0 }} in Get Mode</title><!-- XXX i18n -->
<path fill="{{ fillByCountry[d.alpha2] || 'rgba(0, 0, 0, 0)' }}" class="{{ d.alpha2 }}" d="{{ countryPaths[d.alpha2] }}"/>
</g>
</g>
<g id="peersCurrent">
<g ng-repeat="peer in model.connectivity.peers.current">
<path d="M {{ self.x }} {{ self.y }} Q {{ controlpoint(peer).x }} {{ controlpoint(peer).y }} {{ project(peer).x }} {{ project(peer).y }}" class="p2p"/>
<path d="M {{ self.x }} {{ self.y }} Q {{ controlpoint(peer).x }} {{ controlpoint(peer).y }} {{ project(peer).x }} {{ project(peer).y }}" class="connection"/>
<circle cx="{{ project(peer).x }}" cy="{{ project(peer).y }}" r="{{ peerR }}"
id="{{ peer.peerid }}" class="peer {{ peer.mode }}" filter="url(#blur)">
<title>{{ peer | prettyUser }}</title>
Expand Down
12 changes: 11 additions & 1 deletion mock/bayeux_backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ BayeuxBackend.prototype.resetModel = function() {
merge(this.model, {bayeuxProtocol: BayeuxBackend.VERSION}, 'version.installed');
};

BayeuxBackend.prototype.publishMultiple = function(state) {
if (_.isEmpty(this._clients)) {
//log('[publishSync]', 'no clients to publish to');
return;
}
var data = {state: state};
log('[publishMultiple]\n', data);
this._bayeux._server._engine.publish({channel: MODEL_SYNC_CHANNEL, data: data});
};

BayeuxBackend.prototype.publishSync = function(path, delete_) {
if (_.isEmpty(this._clients)) {
//log('[publishSync]', 'no clients to publish to');
Expand All @@ -48,7 +58,7 @@ BayeuxBackend.prototype.publishSync = function(path, delete_) {
} else {
data.value = getByPath(this.model, path);
}
//log('[publishSync]\n', data);
log('[publishSync]\n', data);
this._bayeux._server._engine.publish({channel: MODEL_SYNC_CHANNEL, data: data});
//this._bayeux.getClient().publish({ // XXX why doesn't this work?
};
Expand Down
7 changes: 7 additions & 0 deletions mock/http_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ ApiServlet.prototype.updateModel = function(state, publish) {
}
};

ApiServlet.prototype.updateMultiple = function(state, publish) {
for (var path in state) {
merge(this.model, state[path], path);
}
this._bayeuxBackend.publishMultiple.call(this._bayeuxBackend, state);
};

/*
* Show next modal that should be shown, including possibly MODAL.none.
* Needed because some modals can be skipped if the user is
Expand Down
20 changes: 14 additions & 6 deletions mock/scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,13 +363,21 @@ exports.SCENARIOS = {
func: function() {
var this_ = this;
setInterval(function() {
var randomCountry = randomChoice(this_.model.countries),
stats = this_.model.countries[randomCountry],
nusersOnlineNow = getByPath(stats, 'nusers.online', _.random(0, 1000)),
nusersOnlineNext = Math.max(0, nusersOnlineNow + _.random(-50, 50)),
var country = randomChoice(this_.model.countries),
stats = this_.model.countries[country],
censors = stats.censors,
npeersOnlineGive = getByPath(stats, 'npeers.online.give',
censors ? 0 : _.random(0, 1000)),
npeersOnlineGet = getByPath(stats, 'npeers.online.get',
censors ? _.random(0, 1000) :_.random(0, 500)),
npeersOnlineGive_ = censors ? npeersOnlineGive :
Math.max(0, npeersOnlineGive + _.random(-50, 50)),
npeersOnlineGet_ = Math.max(0, npeersOnlineGet + _.random(-50, 50)),
update = {};
update['countries.'+randomCountry+'.nusers.online'] = nusersOnlineNext;
this_.updateModel(update, true);
update['countries.'+country+'.npeers.online.give'] = npeersOnlineGive_;
update['countries.'+country+'.npeers.online.get'] = npeersOnlineGet_;
update['countries.'+country+'.npeers.online.giveGet'] = npeersOnlineGive_ + npeersOnlineGet_;
this_.updateMultiple(update);
}, 1000);
}
}
Expand Down
2 changes: 1 addition & 1 deletion sass/_vis.sass
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ circle.give
circle.get
fill: $getModeColor

path.p2p
path.connection
fill: none
stroke-width: 1
stroke: #fff
Expand Down

0 comments on commit 708aafd

Please sign in to comment.