Built with blockbuilder.org
forked from romsson's block: loading multiple stock data from dataset
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin: 0;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
svg {font: 10px sans-serif;}
</style>
</head>
<body>
<script>
var margin = {top: 20,right: 40, bottom: 20,left: 100};
var width = 760 - margin.left - margin.right;
var height = 300 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%b %Y");
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var color = d3.scaleOrdinal(d3.schemeCategory10);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top +
")");
/******************/
/* fonctions Areas*/
/******************/
var separated_area = d3.area()
.curve(d3.curveBasis)
.x(function(d) {
return x(d.date);
})
.y0(function(d) {
return y(d.base);
})
.y1(function(d) {
return y(d.based_price);
});
var stacked_area = d3.area()
.curve(d3.curveBasis)
.x(function(d) {
return x(d.date);
})
.y0(function(d) {
return y(d.sums);
})
.y1(function(d) {
return y(d.prices);
});
var centered_area = d3.area()
.curve(d3.curveBasis)
.x(function(d) {
return x(d.date);
})
.y0(function(d) {
return y(d.sums_centered);
})
.y1(function(d) {
return y(d.prices_centered);
});
var area = d3.area()
.curve(d3.curveBasis)
.x(function(d) {
return x(d.date);
})
.y0(height)
.y1(function(d) {
return y(d.price);
});
var g = svg.append("g");
//Problème pour le dataset par rapport à ce qui est demandé ;
//Données à l'affichage pas dans le bon sens (AAPL en bas par exemple)
//Cause pas trouvée
d3.text("dataset.csv", function(err, raw) {
if (err) throw err;
var data = d3.csvParse(raw);
data.forEach(function(d) {
d.price = +d.price;
d.date = parseDate(d.date);
});
var datas = d3.nest()
.key(function(d) {
return d.symbol;
})
.entries(data);
data.sort(function(a, b) { return b.maxPrice - a.maxPrice; });
// stacked/centered :
for (i = 0; i < datas.length; ++i) {
for (j = 0; j < datas[i].values.length; ++j) {
var elem = datas[i].values[j];
elem.sums = 0;
for (k = i + 1; k < datas.length; ++k) {
elem.sums += datas[k].values[j].price;
}
elem.prices = elem.price + elem.sums;
}
}
var maxY = d3.max(data, function(d) {
return d.prices;
});
x.domain(d3.extent(data, function(d) {
return d.date;
}));
var price_opt = d3.max(datas, function(d) {
return d.price_max;
});
// centered :
for (i = 0; i < datas[0].values.length; ++i) {
var blank_under = (maxY - datas[0].values[i].prices) /
2;
for (j = 0; j < datas.length; ++j) {
var elem = datas[j].values[i];
elem.prices_centered = elem.prices +
blank_under;
elem.sums_centered = elem.sums +
blank_under;
}
}
for (i = 0; i < datas.length; ++i) {
datas[i].price_max = d3.max(datas[i].values, function(
d) {
return d.price;
});
}
var price_opt = d3.max(datas, function(d) {
return d.price_max;
});
for (i = 0; i < datas.length; ++i) {
for (j = 0; j < datas[i].values.length; ++j) {
var elem = datas[i].values[j];
elem.base = (price_opt / 4) * (datas.length -
(i +
1));
var normalized_price = price_opt * elem.price /
datas[i].price_max;
elem.based_price = (normalized_price / datas.length) +
elem.base;
}
}
console.log(datas);
// Courbes
function area_generalizer(area_func, color_opacity) {
g.selectAll(".area").data(datas).enter().append("path")
.attr("class", "area")
.attr("d", function(d) {
return area_func(d.values)
})
.attr("fill", function(d, i) {
return color(d.key);
})
.attr("opacity", color_opacity)
g.selectAll(".area")
.attr("class", "area")
.transition().duration(1000)
.attr("d", function(d) {
return area_func(d.values)
})
.attr("fill", function(d, i) {
return color(d.key);
})
.attr("opacity", color_opacity);
}
//Fonctions permettant de gérer les légendes
function legends(upper_bound, lower_bound) {
var legend = svg.selectAll(".legend").data(color.domain())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) {
var vals = datas[i].values;
return "translate(" + (width - 40) + "," +
(y((vals[vals.length - 1][upper_bound] +
vals[vals.length - 1][
lower_bound
]) / 2)) +
")";
})
svg.selectAll(".legend")
.attr("class", "legend")
.transition().duration(1000)
.attr("transform", function(d, i) {
var vals = datas[i].values;
return "translate(" + (width - 40) + "," +
(y((vals[vals.length - 1][upper_bound] +
vals[vals.length - 1][
lower_bound
]) / 2)) +
")";
})
.select("rect").attr("opacity", 0);
return legend;
}
function legend_layout(legend) {
legend.append("text")
.attr("x", 50)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d) {
return d;
});
}
//Fonctions des affichages demandés
function separated() {
y.domain([0, d3.max(data, function(d) {
return d.price;
})]);
area_generalizer(separated_area, 1);
var legend = legends("based_price", "base");
legend_layout(legend);
setTimeout(stacked, 2000);
}
function stacked() {
y.domain([0, maxY]);
area_generalizer(stacked_area, 1);
var legend = legends("prices",
"sums");
legend_layout(legend);
setTimeout(centered, 2000);
}
function centered() {
y.domain([0, maxY]);
area_generalizer(centered_area, 1);
var legend = legends("prices_centered",
"sums_centered");
legend_layout(legend);
setTimeout(transparent, 2000);
}
function transparent() {
y.domain([0, d3.max(data, function(d) {
return d.price;
})]);
area_generalizer(area, .5);
var legend = legends("based_price", "base");
legend_layout(legend);
setTimeout(separated, 2000);
}
separated();
});
</script>
</body>
https://d3js.org/d3.v4.min.js