-
Notifications
You must be signed in to change notification settings - Fork 0
/
forecast.js
68 lines (62 loc) · 2.33 KB
/
forecast.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var gammaln = function gammaln(x) {
if(x < 0) return NaN;
if(x == 0) return Infinity;
if(!isFinite(x)) return x;
var lnSqrt2PI = 0.91893853320467274178;
var gamma_series = [76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5];
var denom;
var x1;
var series;
// Lanczos method
denom = x+1;
x1 = x + 5.5;
series = 1.000000000190015;
for(var i = 0; i < 6; i++) {
series += gamma_series[i] / denom;
denom += 1.0;
}
return( lnSqrt2PI + (x+0.5)*Math.log(x1) - x1 + Math.log(series/x) );
};
var data = [];
var x_data = [];
var N = 10000;
for (var i = 0; i <= N; i++) {
x_data.push((i*100)/N);
}
var path = window.location.pathname.split('/');
var date = path[1];
var race = path[2];
$.getJSON("/" + date + "/" + race + "/summary.json", function(summary) {
var totalC = 0.0;
for (var key in summary.forecast) {
//console.log(key, summary.forecast, summary.forecast[key]);
totalC += summary.forecast[key].concentration_param;
}
var min = N;
var max = 0;
for (var key in summary.forecast) {
if (summary.forecast[key].concentration_param/totalC < summary.graph_portion_thresh || summary.forecast[key].odds < summary.graph_odds_thresh) {
continue;
}
var alpha = summary.forecast[key].concentration_param;
var beta = totalC-summary.forecast[key].concentration_param;
var gamma = gammaln(alpha+beta)-gammaln(alpha)-gammaln(beta);
var tmp_data = [];
for (var i = 0; i <= N; i++) {
var s = Math.exp(Math.log(i/N)*(alpha-1)+Math.log((N-i)/N)*(beta-1)+gamma);
tmp_data.push(s);
if (i > 0 && tmp_data[tmp_data.length-1] > 1e-5 && tmp_data[tmp_data.length-2] < 1e-5 && i < min) {
min = i;
}
if (i > 0 && tmp_data[tmp_data.length-1] < 1e-5 && tmp_data[tmp_data.length-2] > 1e-5 && i > max) {
max = i;
}
}
data.push({x:x_data, y:tmp_data, mode:'lines', name: summary.forecast[key].candidate, line: {width: 4, color: summary.colors[summary.forecast[key].candidate]}});
}
for (var i in data) {
data[i].x = data[i].x.slice(min, max+1);
data[i].y = data[i].y.slice(min, max+1);
}
Plotly.newPlot('forecast', data.reverse(), {margin: {r: 10, t: 30, b: 30, l: 10}, legend: {x: 0.92, y: 0.99}, title: summary.name + ' Forecast', yaxis: {showline: false, showgrid: false, showticklabels: false}, xaxis: {title: 'Percent of vote'}}, {displayModeBar: false});
});