Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

restructure About docs #3068

Merged
merged 12 commits into from
Jan 7, 2015
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,12 +421,12 @@ The Gratipay API is comprised of these six endpoints:
**[/about/charts.json](https://gratipay.com/about/charts.json)**
([source](https://github.com/gratipay/gratipay.com/tree/master/www/about/charts.json.spt))&mdash;<i>public</i>&mdash;Returns
an array of objects, one per week, showing aggregate numbers over time. The
[charts](https://gratipay.com/about/charts.html) page uses this.
[stats](https://gratipay.com/about/stats) page uses this.

**[/about/paydays.json](https://gratipay.com/about/paydays.json)**
([source](https://github.com/gratipay/gratipay.com/tree/master/www/about/paydays.json.spt))&mdash;<i>public</i>&mdash;Returns
an array of objects, one per week, showing aggregate numbers over time. The
[charts](https://gratipay.com/about/charts.html) page used to use this.
an array of objects, one per week, showing aggregate numbers over time. The old
charts page used to use this.

**[/about/stats.json](https://gratipay.com/about/stats.json)**
([source](https://github.com/gratipay/gratipay.com/tree/master/www/about/stats.spt))&mdash;<i>public</i>&mdash;Returns
Expand Down
60 changes: 32 additions & 28 deletions js/gratipay/charts.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ Gratipay.charts = {};


Gratipay.charts.make = function(series) {
// Takes an array of time series data.
// Takes an array of data points.

if (!series.length) {
$('.chart-wrapper').remove();
return;
}


// Sort the series in increasing date order.
// =========================================
// Reverse the series.
// ===================
// For historical reasons it comes to us in the opposite order from what we
// want.

series.sort(function(a,b) { return a.date > b.date ? 1 : -1 });
series.reverse();


// Gather charts.
Expand All @@ -33,11 +35,10 @@ Gratipay.charts.make = function(series) {
}
}

var H = $('.chart').height();
var nweeks = series.length;
var w = (1 / nweeks * 100).toFixed(10) + '%';

$('.n-weeks').text(nweeks);
var flagRoom = 20;
var H = $('.chart').height() - flagRoom;
var nitems = series.length;
var w = (1 / nitems * 100).toFixed(10) + '%';


// Compute maxes and scales.
Expand All @@ -57,53 +58,56 @@ Gratipay.charts.make = function(series) {
}


// Draw weeks.
// ===========
// Draw bars.
// ==========

function Week(i, j, N, y, title) {
var week = $(document.createElement('div')).addClass('week');
function Bar(i, j, N, y, xText, xTitle) {
var yParsed = parseFloat(y);
var bar = $(document.createElement('div')).addClass('bar');
var shaded = $(document.createElement('div')).addClass('shaded');
shaded.html('<span class="y-label">'+ y.toFixed() +'</span>');
week.append(shaded);
shaded.html('<span class="y-label">'+ yParsed.toFixed() +'</span>');
bar.append(shaded);

var xTick = $(document.createElement('span')).addClass('x-tick');
xTick.text(i+1).attr('title', title);
week.append(xTick);
xTick.text(xText).attr('title', xTitle);
bar.append(xTick);

// Display a max flag (only once)
if (y === maxes[j]) {
if (yParsed === maxes[j]) {
maxes[j] = undefined;
week.addClass('flagged');
bar.addClass('flagged');
}

week.css('width', w);
shaded.css('height', y / N * H);
return week;
bar.css('width', w);
var h = yParsed / N * H;
if (yParsed > 0) h = Math.max(h, 1); // make sure only true 0 is 0 height
shaded.css('height', h)
return bar;
}

for (var i=0, point; point = series[i]; i++) {
for (var j=0, chart; chart = charts[j]; j++) {
chart.append(
Week(i, j, scales[j], point[chart.varname], point.date)
);
var xText = point.xText || i+1;
var xTitle = point.xTitle || '';
chart.append(Bar(i, j, scales[j], point[chart.varname], xText, xTitle));
}
}


// Wire up behaviors.
// ==================

$('.week').click(function() {
$('.bar').click(function() {
$(this).toggleClass('flagged');
if ($(this).hasClass('flagged'))
$(this).removeClass('hover');
});

$('.week').mouseover(function() {
$('.bar').mouseover(function() {
$(this).addClass('hover');
});

$('.week').mouseout(function() {
$('.bar').mouseout(function() {
$(this).removeClass('hover');
});
};
25 changes: 12 additions & 13 deletions scss/molecules/chart.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
padding-top: 12pt;
}
.chart {
height: 100px;
height: 120px; // 100px for the chart + room for the max flag
}
.week {
.bar {
height: 100%;
float: left;
position: relative;
Expand All @@ -18,10 +18,10 @@
bottom: 0;
width: 100%;
}
.week span, .x-axis {
.bar span, .x-axis {
font: normal 7pt/7pt "Lucida Mono", Monaco, monospace;
}
.week span.x-tick {
.bar span.x-tick {
position: absolute;
bottom: -12pt;
right: 0;
Expand All @@ -32,7 +32,7 @@
color: #630;
background: white;
}
.week span.y-label { // This is the flag.
.bar span.y-label { // This is the flag.
display: none;
position: absolute;
top: -17pt;
Expand All @@ -45,17 +45,17 @@
border-radius: 3pt 0 0 3pt;
padding: 2pt 3pt;
}
.week.max span.y-label {
.bar.max span.y-label {
display: block;
}
.week.flagged span.y-label,
.week.flagged span.x-tick,
.week.hover span.y-label,
.week.hover span.x-tick {
.bar.flagged span.y-label,
.bar.flagged span.x-tick,
.bar.hover span.y-label,
.bar.hover span.x-tick {
display: block;
}
.week.hover span.y-label,
.week.hover span.x-tick {
.bar.hover span.y-label,
.bar.hover span.x-tick {
z-index: 2
}
.x-axis {
Expand All @@ -66,6 +66,5 @@
font-style: italic;
font-size: 8pt;
line-height: 10pt;
padding-bottom: 12pt;
}
}
9 changes: 7 additions & 2 deletions templates/about.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{% extends "templates/base.html" %}
{% block sidebar %}
{% set current_page = path.raw.split('/', 2)[2] %}
{% set current_page = path.raw.split('/')[2] %}
{% set current_page = current_page if current_page in ('features', 'policies', 'security') else '' %}
{% set nav_base = "/about" %}
{% set pages = [('/', _('Welcome!')), ('/details', _('Details')), ('/faq', _('FAQ')), ('/contact', _('Contact Us')), ('/pricing', _('Pricing')), ('/teams/', _('Teams')), ('/stats', _('Stats')), ('/charts', _('Charts')), ('/terms/', _('Terms and Conditions')), ('/terms/of-service', 'Terms of Service'), ('/privacy/', _('Privacy Policy')), ('/fraud/', _('Fraud')), ('/dnt', _('DNT')), ('/security', _('Security'))] %}
{% set pages = [ ('/', _('Basic Info'))
, ('/features/', _('Features'))
, ('/policies/', _('Policies'))
, ('/security', _('Security'))
] %}
{% include "templates/nav.html" %}
{% endblock %}
13 changes: 13 additions & 0 deletions templates/basic-info.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% extends "templates/about.html" %}
{% block subnav %}
{% set current_page = path.raw.split('/')[2] %}
{% set nav_base = '/about' %}
{% set pages = [ ('/', _('Overview'))
, ('/faq', _('FAQ'))
, ('/stats', _('Stats'))
, ('/pricing', _('Pricing'))
, ('/contact', _('Contact Us'))
] %}
{% include "templates/nav.html" %}
{% endblock %}

10 changes: 10 additions & 0 deletions templates/features.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends "templates/about.html" %}
{% block subnav %}
{% set current_page = path.raw.split('/')[3] %}
{% set nav_base = '/about/features' %}
{% set pages = [ ('/', _('Overview'))
, ('/teams/', _('Teams'))
, ('/dnt', _('Do Not Track'))
] %}
{% include "templates/nav.html" %}
{% endblock %}
10 changes: 10 additions & 0 deletions templates/policies.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends "templates/about.html" %}
{% block subnav %}
{% set current_page = path.raw.split('/')[3] %}
{% set nav_base = '/about/policies' %}
{% set pages = [ ('/terms-and-conditions', _('Terms and Conditions'))
, ('/terms-of-service', _('Terms of Service'))
, ('/privacy', _('Privacy Policy'))
] %}
{% include "templates/nav.html" %}
{% endblock %}
14 changes: 8 additions & 6 deletions tests/py/test_charts_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from mock import patch

from aspen.utils import utcnow
from gratipay.billing.payday import Payday
from gratipay.testing import Harness

Expand Down Expand Up @@ -150,12 +151,13 @@ def test_transfer_volume(self):
self.run_payday()

expected = { "date": today()
, "weekly_gifts": 3.0
, "charges": 0.0
, "withdrawals": 0.0
, "active_users": 3
, "total_users": 4
, "total_gifts": 6.0
, "weekly_gifts": '3.00'
, "charges": '0.00'
, "withdrawals": '0.00'
, "active_users": '3'
, "total_users": '4'
, "total_gifts": '6.00'
, "xTitle": utcnow().strftime('%Y-%m-%d')
}
actual = json.loads(self.client.GET('/about/charts.json').body)[0]

Expand Down
9 changes: 5 additions & 4 deletions tests/py/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,19 @@ def test_about_stats(self):
assert expected in actual

def test_about_charts(self):
expected = "Money transferred"
actual = self.client.GET('/about/charts.html').body
assert expected in actual
assert self.client.GxT('/about/charts.html').code == 302

def test_about_faq(self):
expected = "What is Gratipay?"
actual = self.client.GET('/about/faq.html').body.decode('utf8')
assert expected in actual

def test_about_teams_redirect(self):
assert self.client.GxT('/about/teams/').code == 302

def test_about_teams(self):
expected = "Teams"
actual = self.client.GET('/about/teams/').body.decode('utf8')
actual = self.client.GET('/about/features/teams/').body.decode('utf8')
assert expected in actual

def test_404(self):
Expand Down
21 changes: 19 additions & 2 deletions tests/py/test_tip_distribution_json.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import unicode_literals

import json
from decimal import Decimal as D

from gratipay.testing import Harness

Expand All @@ -18,4 +17,22 @@ def test_tip_distribution_json_gives_tip_distribution(self):

response = self.client.GET("/about/tip-distribution.json")
tip_distribution = json.loads(response.body)
assert tip_distribution == [D('200.0'), D('300.0')]
assert tip_distribution == [
{'lo': '500.01', 'hi': '1000.00', 'sum': '0', 'ntips': '0', 'xText': '1000.00'},

{'lo': '200.01', 'hi': '500.00', 'sum': '300.00', 'ntips': '1', 'xText': '500.00'},
{'lo': '100.01', 'hi': '200.00', 'sum': '200.00', 'ntips': '1', 'xText': '200.00'},
{'lo': '50.01', 'hi': '100.00', 'sum': '0', 'ntips': '0', 'xText': '100.00'},

{'lo': '20.01', 'hi': '50.00', 'sum': '0', 'ntips': '0', 'xText': '50.00'},
{'lo': '10.01', 'hi': '20.00', 'sum': '0', 'ntips': '0', 'xText': '20.00'},
{'lo': '5.01', 'hi': '10.00', 'sum': '0', 'ntips': '0', 'xText': '10.00'},

{'lo': '2.01', 'hi': '5.00', 'sum': '0', 'ntips': '0', 'xText': '5.00'},
{'lo': '1.01', 'hi': '2.00', 'sum': '0', 'ntips': '0', 'xText': '2.00'},
{'lo': '0.51', 'hi': '1.00', 'sum': '0', 'ntips': '0', 'xText': '1.00'},

{'lo': '0.21', 'hi': '0.50', 'sum': '0', 'ntips': '0', 'xText': '0.50'},
{'lo': '0.11', 'hi': '0.20', 'sum': '0', 'ntips': '0', 'xText': '0.20'},
{'lo': '0.00', 'hi': '0.10', 'sum': '0', 'ntips': '0', 'xText': '0.10'},
]
19 changes: 11 additions & 8 deletions www/about/charts.json.spt
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
[---]
charts = website.db.all("""\

SELECT ts_start::date AS date
, nparticipants AS total_users
, nactive AS active_users
SELECT ts_start::date AS date
, ts_start::date AS xTitle
, nparticipants::text AS total_users
, nactive::text AS active_users
, ( SELECT sum(transfer_volume)
FROM paydays
WHERE ts_start <= p.ts_start
) AS total_gifts
, transfer_volume AS weekly_gifts
, charge_volume AS charges
, abs(ach_volume) AS withdrawals
)::text AS total_gifts
, transfer_volume::text AS weekly_gifts
, charge_volume::text AS charges
, abs(ach_volume)::text AS withdrawals
FROM paydays p
ORDER BY ts_start DESC

""")
""", back_as=dict)
for c in charts:
c['xTitle'] = c.pop('xtitle') # postgres doesn't respect case here
response.headers["Access-Control-Allow-Origin"] = "*"
[---] application/json via json_dump
charts[:-1] # Don't show Gratipay #0.
Loading