|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<!-- trying to demo what they did here with Java: http://onlinestatbook.com/2/sampling_distributions/clt_demo.html Except without Java --> |
|
<meta charset="utf-8"><!-- Load c3.css --> |
|
|
|
<link href="http://c3js.org/css/c3-b03125fa.css" rel="stylesheet" type="text/css"> |
|
<!-- Load d3.js and c3.js --> |
|
<script src="https://d3js.org/d3.v3.min.js"></script> |
|
<script src="http://c3js.org/js/c3.min-4c5bef8f.js"></script> |
|
<style> |
|
|
|
.c3-axis-x .domain, |
|
.c3-axis-y .domain, |
|
.c3-axis-x .tick line, |
|
.c3-axis-y .tick line{ |
|
display:none; |
|
} |
|
.tick text, |
|
.c3-axis-y-label, |
|
.c3-axis-x-label { |
|
font-size:1.5em; |
|
} |
|
.c3-axis-y .tick text{ |
|
display:none; |
|
} |
|
.c3-axis-y .tick:nth-child(2n) text{ |
|
display:block; |
|
} |
|
.c3-circles-min, |
|
.c3-circles-max { |
|
display:none; |
|
} |
|
.c3-lines-min { |
|
/* Because max has it covered */ |
|
display:none; |
|
} |
|
|
|
.c3-lines-max path { |
|
stroke-width:0px; |
|
stroke:transparent; |
|
} |
|
|
|
.c3-ygrids line { |
|
/*was going for a grey background white-line look, but... */ |
|
stroke: rgba(0,0,0,0.1); |
|
stroke-dasharray: none; |
|
} |
|
|
|
.c3-ygrids line:nth-child(2n){ |
|
/*stroke:rgba(0,0,0,0.05); |
|
*/ |
|
stroke-dasharray: 3 3; |
|
} |
|
|
|
.c3-ygrid-line line { |
|
stroke : rgba(0,0,00,.5); |
|
} |
|
|
|
.c3-xgrid-line line { |
|
stroke :rgba(19,160,243,0.8); |
|
} |
|
.buy-in rect{ |
|
fill: rgba(19,160,243,0.2); |
|
/* |
|
#13e3e2; |
|
*/ |
|
fill-opacity:1!important; |
|
|
|
} |
|
.tip { |
|
position:relative; |
|
background-color:rgba(19,160,243,1); |
|
color:white; |
|
padding:1em; |
|
line-height:0; |
|
|
|
font-size:1.5em; |
|
} |
|
.range.tip { |
|
width:450px; |
|
margin-left:80px; |
|
box-sizing:border-box; |
|
} |
|
.arrow.tip { |
|
width:200px; |
|
/* If it were directly lining up |
|
|
|
margin-left:530px; |
|
*/ |
|
margin-left:465px; |
|
margin-bottom:0px; |
|
margin-top:40px; |
|
/*Gotta leave room for the triangles */ |
|
margin-bottom:40px; |
|
} |
|
|
|
.range.tip.bottom { |
|
/*height:200px; |
|
*/ |
|
} |
|
.range.tip.top { |
|
margin-bottom:40px; |
|
padding:0.5em; |
|
|
|
} |
|
body { |
|
font-family:Calibri, sans-serif; |
|
} |
|
.amt { |
|
font-size:2.2em; |
|
} |
|
|
|
/* https://css-tricks.com/snippets/css/css-triangle/*/ |
|
.arrow-right, |
|
.arrow-left { |
|
|
|
position:absolute; |
|
} |
|
.range.tip.top .arrow-right, |
|
.range.tip.top .arrow-left{ |
|
bottom:-30px; |
|
} |
|
|
|
.range.tip.bottom .arrow-right, |
|
.range.tip.bottom .arrow-left{ |
|
top:-30px; |
|
} |
|
|
|
.range.tip .arrow-right{ |
|
left:0px; |
|
} |
|
|
|
.range.tip .arrow-left{ |
|
right:0px; |
|
} |
|
.arrow-right { |
|
width: 0; |
|
height: 0; |
|
border-top: 30px solid transparent; |
|
border-bottom: 30px solid transparent; |
|
border-left: 30px solid rgba(19,160,243,1); |
|
} |
|
|
|
.arrow .arrow-right { |
|
position:absolute; |
|
top:-30px; |
|
left:0px; |
|
} |
|
.arrow .arrow-right.dir { |
|
left:auto; |
|
right:-50px; |
|
border-width:70px; |
|
top:-22px; |
|
} |
|
|
|
.arrow-left { |
|
width: 0; |
|
height: 0; |
|
border-top: 30px solid transparent; |
|
border-bottom: 30px solid transparent; |
|
|
|
border-right:30px solid rgba(19,160,243,1); |
|
} |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<div class="range tip top"> |
|
<p>Stuff happens here</p> |
|
<div class="arrow-right"></div> |
|
<div class="arrow-left"></div> |
|
</div> |
|
<div id="c1"></div> |
|
<div id="c2"></div> |
|
<div class="arrow tip right bottom"> |
|
|
|
<div class="arrow-right"></div> |
|
<p>Stuff happens</p> |
|
<div class="arrow-right dir"></div> |
|
</div> |
|
<div class="range tip bottom"> |
|
<div class="arrow-right"></div> |
|
<div class="arrow-left"></div> |
|
<p class="exp">A few words here and there</p> |
|
<p class="amt">$45.5-$34.2</p> |
|
</div> |
|
<script> |
|
|
|
|
|
var start_year = 2017; |
|
|
|
|
|
var year_range = d3.range(start_year, start_year + 14); |
|
|
|
var tooltip_contents = function (data) { |
|
//data is an array of all the data points for a given x-axis |
|
return '<em>hi</em>'; |
|
}; |
|
|
|
var min = function (d) { |
|
return d3.min(d); //ignore remaining params |
|
}; |
|
var max = function (d) { |
|
return d3.max(d); |
|
} |
|
|
|
|
|
|
|
|
|
var range_chart = function (o) { |
|
|
|
var on_rendered = function () { |
|
var max_path_el = d3.selectAll(o.bindto + ' .c3-line-max')[0][0]; |
|
|
|
var min_path_el = d3.selectAll(o.bindto + ' .c3-line-min')[0][0]; |
|
|
|
var min_psl = min_path_el.pathSegList; |
|
|
|
//reversed path_seg_list of min |
|
var r_psl = d3 |
|
.range(min_psl.numberOfItems) |
|
.map(function (_) { |
|
/* go in reverse order */ |
|
return min_psl |
|
.getItem(min_psl.numberOfItems - (_ + 1)) |
|
}); |
|
|
|
r_psl.forEach(function (_) { |
|
max_path_el.pathSegList |
|
.appendItem(new SVGPathSegLinetoAbs( |
|
undefined, _.x, _.y)) |
|
}); |
|
|
|
d3.select(max_path_el) |
|
.style({ |
|
fill : 'rgba(0,0,0,0.1)', |
|
stroke : 'grey' |
|
}); |
|
|
|
}; |
|
|
|
var left_right_zip = d3.zip(o.left_range, o.right_range); |
|
|
|
|
|
var min_range = left_right_zip.map(min); |
|
var max_range = left_right_zip.map(max); |
|
|
|
var min_max_zip = d3.zip(max_range, min_range); |
|
var spread_range = min_max_zip.map(function (v) { |
|
return v[0] - v[1]; |
|
d3.max(v) - d3.min(v) |
|
}); |
|
var mean_range = min_max_zip.map(function (v) { |
|
return d3.mean(v); |
|
}); |
|
|
|
var columns = [ |
|
['year'].concat(year_range), |
|
['min'].concat(min_range), |
|
['max'].concat(max_range), |
|
['mean'].concat(mean_range), |
|
]; |
|
|
|
var chart = c3.generate({ |
|
regions : o.regions, |
|
size : { |
|
height : 500, |
|
width:960 |
|
}, |
|
padding :{ |
|
bottom: 20 |
|
}, |
|
onrendered : on_rendered, |
|
axis : { |
|
y : { |
|
label : { |
|
text : o.y, |
|
position : 'outer-middle' |
|
}, |
|
padding : 0, |
|
tick : { |
|
values : d3.range( |
|
Math.floor(d3.min(min_range)), |
|
Math.ceil(d3.max(max_range)), |
|
o.y_tick_height) |
|
} |
|
}, |
|
x : { |
|
label : { |
|
text : o.x, |
|
position : 'outer-center' |
|
} |
|
} |
|
}, |
|
grid : { |
|
y : { |
|
show : true, |
|
lines : [{ |
|
value : 0 |
|
} |
|
], |
|
}, |
|
x: { |
|
lines : [{ |
|
value : 2023 |
|
|
|
},{ |
|
value : 2024 |
|
|
|
}] |
|
} |
|
}, |
|
bindto : o.bindto, |
|
//point: {show:false}, |
|
//Show them; use CSS to hide the ones you don't want |
|
//tooltip : { contents: mean_range_contents}, |
|
legend : { |
|
show : false |
|
}, |
|
data : { |
|
x : 'year', |
|
columns : columns, |
|
colors : { |
|
spread : 'grey', |
|
mean : 'black', |
|
left : 'grey', |
|
right : 'red', |
|
max: 'black', |
|
|
|
} |
|
} |
|
}); |
|
} |
|
|
|
range_chart({ |
|
bindto: '#c1', |
|
x: 'X axis', |
|
y: 'Y axis', |
|
y_tick_height:0.5 , |
|
regions: [{ |
|
axis : 'x', |
|
start : 2017, |
|
end : 2024, |
|
class : 'buy-in' |
|
} |
|
], |
|
|
|
left_range : [4.5, 0, -0.2, -0.5, -0.4, -0.6, -2.7, -2.3, -2.6, -2.6, -2.6, -2.6, -2.6, -2.6], |
|
right_range : [7, -0.8, -0.9, -0.9, -1, -1, -2.9, -3.3, -2.6, -2.6, -2.6, -2.6, -2.6, -2.6] |
|
}); |
|
|
|
range_chart({ |
|
bindto: '#c2', |
|
x: 'X axis', |
|
y: 'Y axis', |
|
y_tick_height:10 , |
|
regions: [{ |
|
axis : 'x', |
|
start : 2017, |
|
end : 2024, |
|
class : 'buy-in' |
|
} |
|
], |
|
|
|
left_range : [-36, .62, 3, 5, 6, 8, 41, 34, 41, 43, 44, 45, 46, 48], |
|
right_range : [-68, 10, 13, 19, 13, 15, 42, 51, 45, 43, 44, 45, 46, 48] |
|
}); |
|
</script> |
|
</body> |
|
</html> |