Skip to content

Commit b9596eb

Browse files
committed
Merge branch 'master' into gh-pages
2 parents db51745 + cc622cc commit b9596eb

File tree

7 files changed

+254
-140
lines changed

7 files changed

+254
-140
lines changed

datasets/shiller_absolute.json

Lines changed: 6 additions & 0 deletions
Large diffs are not rendered by default.

index.html

Lines changed: 15 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -2,130 +2,10 @@
22
<html>
33
<head>
44
<title>S&P Viewer</title>
5-
<script type="text/javascript" src="sp.json"></script>
6-
<script type="text/javascript">
7-
var topPad = 50;
8-
9-
var width, height, data, canvas, ctx;
10-
var startMonth, endMonth, min, max;
11-
12-
function $(id) { return document.getElementById(id);}
13-
Number.prototype.formatMoney = function(c, d, t){
14-
var n = this,
15-
c = isNaN(c = Math.abs(c)) ? 2 : c,
16-
d = d == undefined ? "." : d,
17-
t = t == undefined ? "," : t,
18-
s = n < 0 ? "-" : "",
19-
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
20-
j = (j = i.length) > 3 ? j % 3 : 0;
21-
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
22-
};
23-
24-
function loadCanvas(){
25-
canvas = $('graph');
26-
width = canvas.width;
27-
height = canvas.height;
28-
if (canvas.getContext){
29-
ctx = canvas.getContext('2d');
30-
31-
canvas.addEventListener('mousewheel',function(event){
32-
zoom(event);
33-
return false;
34-
}, false);
35-
36-
data = spData["data"];
37-
startMonth = 1200;
38-
endMonth = data.length;
39-
draw();
40-
}
41-
}
42-
43-
function zoom(event) {
44-
var deltaFactor = (event.deltaMode == WheelEvent.DOM_DELTA_LINE) ? 20 : 1;
45-
var delta = event.deltaY * deltaFactor;
46-
var mouseX = event.clientX - canvas.offsetLeft;
47-
48-
var span = endMonth-startMonth;
49-
var centerMonth = startMonth + mouseX/(width/span);
50-
var factor = 1 + delta * 0.0002;
51-
endMonth = Math.round(factor*endMonth - centerMonth*(factor - 1));
52-
startMonth = Math.round(factor*startMonth + centerMonth*(1 - factor));
53-
54-
startMonth = Math.max(startMonth,0);
55-
endMonth = Math.min(Math.max(endMonth,startMonth+10), data.length);
56-
draw();
57-
}
58-
59-
function updateStats() {
60-
var totalGrowth = data[endMonth-1]/data[startMonth];
61-
var avgGrowth = Math.pow(totalGrowth,(12/(endMonth-startMonth)))-1;
62-
var doubled = Math.log(totalGrowth)/Math.log(2);
63-
// console.log([data[startMonth],data[endMonth],endMonth,totalGrowth]);
64-
$('stat-growth').innerHTML = String((avgGrowth*100).toFixed(2)) + '%';
65-
$('stat-total').innerHTML = "$" + totalGrowth.formatMoney(2,'.',',');
66-
$('stat-doubled').innerHTML = String(doubled.toFixed(2));
67-
}
68-
69-
function dataRange(data, startMonth, endMonth) {
70-
min = Infinity;
71-
max = 0.0;
72-
for (var i = startMonth; i < endMonth; i++) {
73-
if(data[i]>max) max = data[i];
74-
if(data[i]<min) min = data[i];
75-
};
76-
}
77-
78-
function draw() {
79-
drawData(ctx, data, startMonth, endMonth);
80-
81-
var startYear = Math.round(spData["start"] + (startMonth/12));
82-
var endYear = Math.round(spData["start"] + (endMonth/12));
83-
ctx.font = "20pt sans-serif";
84-
ctx.fillText(String(startYear) + " - " + String(endYear),10,30);
85-
86-
updateStats();
87-
}
88-
89-
function drawData(ctx, data, startMonth, endMonth){
90-
dataRange(data, startMonth, endMonth);
91-
var span = endMonth-startMonth;
92-
var dx = (width/span);
93-
var jump = Math.ceil(span/width);
94-
95-
ctx.clearRect(0,0,width, height);
96-
97-
// Year lines
98-
var minSpace = 20;
99-
var alpha = Math.min((dx*12)/minSpace*0.7,0.7);
100-
if (alpha < 0.3) alpha = 0.0;
101-
ctx.strokeStyle = "rgba(202,226,255,"+alpha+")";
102-
ctx.lineWidth = 1;
103-
104-
ctx.beginPath();
105-
for (var i = startMonth; i < endMonth; i++) {
106-
if (i % 12 == 0) {
107-
var x = (i-startMonth)*dx;
108-
ctx.moveTo(x,0);
109-
ctx.lineTo(x,height);
110-
}
111-
};
112-
ctx.stroke();
113-
114-
// Graph
115-
ctx.strokeStyle = "rgb(74,144,226)";
116-
ctx.lineWidth = 4;
117-
ctx.lineJoin = "round";
118-
119-
ctx.beginPath();
120-
ctx.moveTo(0,height);
121-
for (var i = startMonth; i < endMonth; i+=jump) {
122-
var y = (data[i]-min)/(max-min)*(height-topPad);
123-
var x = (i-startMonth)*dx;
124-
ctx.lineTo(x,height - y);
125-
};
126-
ctx.stroke();
127-
}
128-
</script>
5+
<script type="text/javascript" src="datasets/shiller_absolute.json"></script>
6+
<script type="text/javascript" src="js/lib.js"></script>
7+
<script type="text/javascript" src="js/viewer.js"></script>
8+
<script type="text/javascript" src="js/main.js"></script>
1299
<style type="text/css">
13010
body {
13111
font-family: sans-serif;
@@ -162,20 +42,22 @@
16242
}
16343
</style>
16444
</head>
165-
<body onload="loadCanvas();">
45+
<body onload="load();">
16646
<h1>S&amp;P 500 Index</h1>
16747
<div id="widget">
168-
<canvas id="graph" width="500" height="200"></canvas>
48+
<canvas id="graph" width="500" height="250"></canvas>
16949
<div id="stats">
170-
<strong>Average Growth</strong><br>
171-
<div class="num" id="stat-growth"></div><br>
172-
<strong>One Dollar Becomes</strong><br>
173-
<div class="num" id="stat-total"></div><br>
174-
<strong>Times Doubled</strong><br>
175-
<div class="num" id="stat-doubled"></div><br>
17650
</div>
17751
<div class="sep"></div>
17852
</div>
179-
<p><strong>Note:</strong> Scroll to zoom and move around. Better date entry coming soon.</p>
53+
<div id="datasets">
54+
<strong>Data Set: </strong>
55+
<select name="datasets" id="dataset-chooser" onchange="setChooserChanged()">
56+
</select>
57+
</div>
58+
59+
60+
<h3>Note:</h3>
61+
<p>Scroll to zoom and move around. Better date entry coming soon.</p>
18062
</body>
18163
</html>

js/lib.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function $(id) { return document.getElementById(id);}
2+
Number.prototype.formatMoney = function(c, d, t){
3+
var n = this,
4+
c = isNaN(c = Math.abs(c)) ? 2 : c,
5+
d = d == undefined ? "." : d,
6+
t = t == undefined ? "," : t,
7+
s = n < 0 ? "-" : "",
8+
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
9+
j = (j = i.length) > 3 ? j % 3 : 0;
10+
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
11+
};

js/main.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
var Stats = {
2+
_calcTotalGrowth: function(data, start, end) {
3+
return data[end-1]/data[start];
4+
},
5+
totalGrowth: function(data, start, end) {
6+
var totalGrowth = Stats._calcTotalGrowth(data,start,end);
7+
var text = String(((totalGrowth-1)*100).toFixed(2)) + '%';
8+
return ["Total Growth", text];
9+
},
10+
dollarsNow: function(data, start, end) {
11+
var totalGrowth = Stats._calcTotalGrowth(data,start,end);
12+
var text = "$" + totalGrowth.formatMoney(2,'.',',');
13+
return ["One Dollar Becomes", text];
14+
},
15+
averageGrowth: function(data, start, end) {
16+
var totalGrowth = Stats._calcTotalGrowth(data,start,end);
17+
var avgGrowth = Math.pow(totalGrowth,(12/(end-start)))-1;
18+
var text = String((avgGrowth*100).toFixed(2)) + '%';
19+
return ["Average Growth", text];
20+
},
21+
timesDoubled: function(data, start, end) {
22+
var totalGrowth = Stats._calcTotalGrowth(data,start,end);
23+
var doubled = Math.log(totalGrowth)/Math.log(2);
24+
var text = String(doubled.toFixed(2));
25+
return ["Times Doubled", text];
26+
}
27+
};
28+
29+
var defaultStats = [Stats.averageGrowth, Stats.dollarsNow, Stats.timesDoubled, Stats.totalGrowth];
30+
var dataSets = [
31+
{
32+
name: "S&P500",
33+
file: "shiller_absolute.json",
34+
statFuncs: defaultStats,
35+
startYear: function(struct) {return struct["start"];},
36+
datFunc: function(struct) {
37+
return struct["price"];
38+
}
39+
},
40+
{
41+
name: "S&P500 (Reinvested Dividends)",
42+
file: "shiller_absolute.json",
43+
statFuncs: defaultStats,
44+
startYear: function(struct) {return struct["start"];},
45+
datFunc: function(struct) {
46+
var newData = [1.0];
47+
var price = struct["price"];
48+
var dividend = struct["dividend"];
49+
50+
for (var i = 1; i < price.length; i++) {
51+
var grownVal = (price[i]/price[i-1]);
52+
grownVal += (dividend[i]/12.0)/price[i];
53+
grownVal *= newData[i-1];
54+
newData[i] = grownVal;
55+
};
56+
57+
return newData;
58+
}
59+
},
60+
];
61+
62+
function loadSetChooser() {
63+
var select = $('dataset-chooser');
64+
for (var i = 0; i < dataSets.length; i++) {
65+
var opt = document.createElement("option");
66+
opt.value = i;
67+
opt.text = dataSets[i].name;
68+
select.add(opt,null);
69+
};
70+
}
71+
72+
function setChooserChanged() {
73+
var select = $('dataset-chooser');
74+
loadData(select.selectedIndex);
75+
}
76+
77+
function loadData(setNum) {
78+
var set = dataSets[setNum];
79+
var startYear = set.startYear(spData);
80+
var data = set.datFunc(spData);
81+
82+
Viewer.loadData(data, startYear, set.statFuncs);
83+
}
84+
85+
function load() {
86+
Viewer.loadCanvas();
87+
loadSetChooser();
88+
loadData(0);
89+
}

0 commit comments

Comments
 (0)