I am quite new to D3 and JavaScript in general, so I'm sure there is a way to write the following in a lot less code:
function CalculatePeriodReturns(){
periodReturns = [];
[...]
periodReturns.push({
length: [...],
mean: [...],
pctile50: [pctile(0.25),pctile(0.75)],
pctile90: [pctile(0.05),pctile(0.95)],
pctile99: [pctile(0.005),pctile(0.995)],
min: [...],
max: [...]
});
}
function DrawChart(){
var margin = {top: 20, right: 100, bottom: 30, left: 100},
width = $("#multiperiod_chart").width() - margin.left - margin.right,
height = $("#multiperiod_chart").height() - margin.top - margin.bottom;
var svg = d3.select("#multiperiod_chart").append("svg")
.datum(periodReturns)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id", "multiperiod_chart_svg")
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
x.domain(d3.extent(periodReturns, d=>d.length));
y.domain([d3.min(periodReturns, d => d.min),
d3.max(periodReturns, d => d.max)]);
var area99 = d3.area()
.x(d=>x(d.length))
.y0(d=>y(d.pctile99[0]))
.y1(d=>y(d.pctile99[1]))
svg.append("path")
.attr("class", "area")
.attr("id", "area99")
.attr("fill", "#565A68")
.attr("d", area99);
var area90 = d3.area()
.x(d=>x(d.length))
.y0(d=>y(d.pctile90[0]))
.y1(d=>y(d.pctile90[1]))
svg.append("path")
.attr("class", "area")
.attr("id", "area90")
.attr("fill", "#7B7F8B")
.attr("d", area90);
var area50 = d3.area()
.x(d=>x(d.length))
.y0(d=>y(d.pctile50[0]))
.y1(d=>y(d.pctile50[1]))
svg.append("path")
.attr("class", "area")
.attr("id", "area50")
.attr("fill", "#A1A3AA")
.attr("d", area50);
[...]
}
For a start, is there a way to create an accessor area(y0,y1)
that takes the two d.pctileXX
properties as attributes or similar? Maybe I can combine the three svg.append
's as well?