Skip to content

Commit

Permalink
Sparklines
Browse files Browse the repository at this point in the history
First simple implementation of sparklines.

Data is requested from ophan in batches, after the front is fully loaded.

For now, only the articles inside a front will displaoy sparklines and the data is filtered by referrer-url (the front).

This is a first step, we need to verify that both ophan and the tool can handle the extra load.

Everything is behind a switch (same switch as before) but it's possible to override that switch adding the url parameter `?sparklines=please`
  • Loading branch information
Fabio Crisci committed Feb 20, 2015
1 parent 309f515 commit 388c411
Show file tree
Hide file tree
Showing 21 changed files with 1,416 additions and 80 deletions.
1 change: 1 addition & 0 deletions facia-end-to-end/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ GET /switches controllers.SwitchesProxy.getSwitches()
GET /api/proxy/*path controllers.FaciaContentApiProxy.capi(path)
GET /http/proxy/*url controllers.FaciaContentApiProxy.http(url)
GET /json/proxy/*absUrl controllers.FaciaContentApiProxy.json(absUrl)
GET /ophan/*path controllers.FaciaContentApiProxy.ophan(path)

# thumbnails
GET /thumbnails/*id.svg controllers.ThumbnailController.container(id)
Expand Down
20 changes: 20 additions & 0 deletions facia-tool/app/controllers/FaciaContentApiProxy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,24 @@ object FaciaContentApiProxy extends Controller with Logging with AuthLogging wit
}
}
}

def ophan(path: String) = ExpiringActions.ExpiringAuthAction.async { request =>
FaciaToolMetrics.ProxyCount.increment()
val paths = request.queryString.get("path").map(_.mkString("path=", "&path=", "")).getOrElse("")
val queryString = request.queryString.filterNot(_._1 == "path").filter(_._2.exists(_.nonEmpty)).map { p =>
"%s=%s".format(p._1, p._2.head.urlEncoded)
}.mkString("&")
val ophanApiHost = Configuration.ophanApi.host.get
val ophanKey = Configuration.ophanApi.key.map(key => s"&api-key=$key").getOrElse("")

val url = s"$ophanApiHost/$path?$queryString&$paths&ophanKey"

log("Proxying ophan request to: %s" format url, request)

WS.url(url).withPreviewAuth.get().map { response =>
Cached(60) {
Ok(response.body).as("application/json")
}
}
}
}
4 changes: 1 addition & 3 deletions facia-tool/app/views/collections.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,7 @@
</div>

<div class="closed" data-bind="ifnot: state.isOpen">
<img class="article__spark" data-bind="
visible: state.sparkUrl,
attr: {src: state.sparkUrl}" />
<div data-bind="sparklines: $root.isSparklinesEnabled" class="sparkline"></div>

<div class="article__tools">
<a class="tool tool--small tool--small--paste" data-bind="
Expand Down
1 change: 1 addition & 0 deletions facia-tool/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ GET /switches controllers.SwitchesProxy.getSwitches()
GET /api/proxy/*path controllers.FaciaContentApiProxy.capi(path)
GET /http/proxy/*url controllers.FaciaContentApiProxy.http(url)
GET /json/proxy/*absUrl controllers.FaciaContentApiProxy.json(absUrl)
GET /ophan/*path controllers.FaciaContentApiProxy.ophan(path)

# thumbnails
GET /thumbnails/*id.svg controllers.ThumbnailController.container(id)
Expand Down
6 changes: 6 additions & 0 deletions facia-tool/public/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2058,6 +2058,12 @@ hr {
font-weight: bold;
}

.sparkline {
position: absolute;
right: 0;
top: 15px;
}

/*****************************************/
/* MEDIA QUERIES */
/*****************************************/
Expand Down
201 changes: 201 additions & 0 deletions facia-tool/public/js/components/highcharts/highcharts-custom.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions facia-tool/public/js/jspm-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ System.config({
"sinon": "npm:sinon@1.12.2",
"text": "github:systemjs/plugin-text@0.0.2",
"underscore": "npm:underscore@1.7.0",
"highcharts": "./components/highcharts/highcharts-custom",
"github:jspm/nodelibs-fs@0.1.0": {
"assert": "npm:assert@1.3.0",
"fs": "github:jspm/nodelibs-fs@0.1.0"
Expand Down
16 changes: 0 additions & 16 deletions facia-tool/public/js/models/collections/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,6 @@ define([
populateObservables(this.meta, this.metaDefaults);

this.updateEditorsDisplay();

this.loadSparkline();
}
};

Expand All @@ -579,20 +577,6 @@ define([
this.scheduledPublicationTime(humanTime(this.fields.scheduledPublicationDate()));
};

Article.prototype.loadSparkline = function() {
var self = this;

if (vars.model.switches()['facia-tool-sparklines']) {
setTimeout(function() {
if (self.state.sparkUrl()) {
self.state.sparkUrl.valueHasMutated();
} else {
self.state.sparkUrl(vars.sparksBase + urlAbsPath(self.props.webUrl()) + (self.frontPublicationDate ? '&markers=' + (self.frontPublicationDate/1000) + ':46C430' : ''));
}
}, Math.floor(Math.random() * 5000));
}
};

Article.prototype.get = function() {
return {
id: this.id(),
Expand Down
78 changes: 50 additions & 28 deletions facia-tool/public/js/models/collections/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ define([
this.state.isHistoryOpen(this.front.confirmSendingAlert());

this.setPending(true);
this.load();
this.loaded = this.load();

var that = this;
this.listeners.on('ui:open', function () {
Expand Down Expand Up @@ -243,17 +243,21 @@ define([
};

Collection.prototype.load = function(opts) {
var self = this;
var self = this,
deferred = new $.Deferred();

opts = opts || {};

return authedAjax.request({
authedAjax.request({
url: vars.CONST.apiBase + '/collection/' + this.id
})
.done(function(raw) {
if (opts.isRefresh && self.isPending()) { return; }

if (!raw) { return; }
if (!raw) {
self.loaded.resolve();
return;
}

self.state.hasConcurrentEdits(false);

Expand All @@ -265,9 +269,14 @@ define([

self.state.timeAgo(self.getTimeAgo(raw.lastUpdated));
})
.fail(function () {
self.loaded.resolve();
})
.always(function() {
self.setPending(false);
});

return deferred;
};

Collection.prototype.registerElement = function (element) {
Expand All @@ -287,7 +296,8 @@ define([

Collection.prototype.populate = function(rawCollection) {
var self = this,
list;
list,
loading = [];

this.raw = rawCollection || this.raw;

Expand All @@ -308,24 +318,27 @@ define([
var group = _.find(self.groups, function(g) {
return (parseInt((item.meta || {}).group, 10) || 0) === g.index;
}) || self.groups[0];
var article = new Article(_.extend(item, {
group: group,
slimEditor: self.front.slimEditor()
}));

group.items.push(
new Article(_.extend(item, {
group: group,
slimEditor: self.front.slimEditor()
}))
);
group.items.push(article);
});

this.populateHistory(this.raw.previously);
this.state.lastUpdated(this.raw.lastUpdated);
this.state.count(list.length);
this.decorate();
loading.push(this.decorate());
}
}

this.refreshVisibleStories();
this.setPending(false);
$.when.apply($, loading).always(function () {
mediator.emit('collection:populate', self);
self.loaded.resolve();
});
};

Collection.prototype.populateHistory = function(list) {
Expand All @@ -343,19 +356,38 @@ define([
}, this));
};

Collection.prototype.closeAllArticles = function() {
Collection.prototype.eachArticle = function (fn) {
_.each(this.groups, function(group) {
_.each(group.items(), function(item) {
item.close();
fn(item, group);
});
});
};

Collection.prototype.contains = function (article) {
return _.some(this.groups, function (group) {
return _.some(group.items(), function (item) {
return item === article;
});
});
};

Collection.prototype.closeAllArticles = function() {
this.eachArticle(function(item) {
item.close();
});
};

Collection.prototype.decorate = function() {
_.each(this.groups, function(group) {
contentApi.decorateItems(group.items());
var allItems = [],
done;
this.eachArticle(function(item) {
allItems.push(item);
});
done = contentApi.decorateItems(allItems);
contentApi.decorateItems(this.history());

return done;
};

Collection.prototype.refresh = function() {
Expand All @@ -366,19 +398,9 @@ define([
});
};

Collection.prototype.refreshSparklines = function() {
_.each(this.groups, function(group) {
_.each(group.items(), function(item) {
item.loadSparkline();
});
});
};

Collection.prototype.refreshRelativeTimes = function() {
_.each(this.groups, function(group) {
_.each(group.items(), function(item) {
item.setRelativeTimes();
});
this.eachArticle(function(item) {
item.setRelativeTimes();
});
};

Expand Down
7 changes: 6 additions & 1 deletion facia-tool/public/js/models/collections/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ define([
'utils/fetch-settings',
'utils/global-listeners',
'utils/layout-from-url',
'utils/sparklines',
'utils/parse-query-params',
'utils/update-scrollables',
'utils/terminate',
Expand All @@ -31,6 +32,7 @@ define([
fetchSettings,
globalListeners,
layoutFromUrl,
sparklines,
parseQueryParams,
updateScrollables,
terminate,
Expand All @@ -52,7 +54,10 @@ define([
switches: ko.observable(),
fronts: ko.observableArray(),
loadedFronts: ko.observableArray(),
isPasteActive: ko.observable(false)
isPasteActive: ko.observable(false),
isSparklinesEnabled: ko.pureComputed(function () {
return sparklines.isEnabled();
})
};

model.chooseLayout = function () {
Expand Down
9 changes: 6 additions & 3 deletions facia-tool/public/js/modules/content-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,14 @@ function (
}

function decorateItems (articles) {
var num = vars.CONST.capiBatchSize || 10;
var num = vars.CONST.capiBatchSize || 10,
pending = [];

_.each(_.range(0, articles.length, num), function(index) {
decorateBatch(articles.slice(index, index + num));
pending.push(decorateBatch(articles.slice(index, index + num)));
});

return $.when.apply($, pending);
}

function decorateBatch (articles) {
Expand All @@ -142,7 +145,7 @@ function (
}
});

fetchContentByIds(ids)
return fetchContentByIds(ids)
.done(function(results){
if (!_.isArray(results)) {
return;
Expand Down
19 changes: 3 additions & 16 deletions facia-tool/public/js/modules/vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,17 @@ define([
ophanBase: 'http://dashboard.ophan.co.uk/graph/breakdown',
ophanFrontBase: 'http://dashboard.ophan.co.uk/info?path=',

sparksServer: 'http://sparklines.ophan.co.uk',
sparksParams: {
graphs: 'other:3279F1,google:65b045,guardian:376ABF',
showStats: 1,
showHours: 1,
width: 100,
height: 35
},
internalContentPrefix: 'internal-code/content/',

internalContentPrefix: 'internal-code/content/'
sparksBatchQueue: 15
};

function sparksBaseUrl(args) {
return CONST.sparksServer + '/png?' + _.map(args, function(v,k) { return k + '=' + v; }).join('&') + '&page=/';
}

return {
CONST: CONST,
model: undefined,
sparksBase: sparksBaseUrl(CONST.sparksParams),
priority: pageConfig.priority === 'editorial' ? undefined : pageConfig.priority,
state: {
config: {},
openFronts: {}
config: {}
}
};
});
Loading

0 comments on commit 388c411

Please sign in to comment.