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 displayDate = d3.timeFormat("%y");
var displayValue = d3.format(",.0f");
var color = d3.scaleOrdinal(d3.schemeCategory10);
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
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 +
")");
/********** Gestion des Aires **********/
// Calcul des aires du graphe separe
var separatedAreas = 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.basedPrice); });
// Calcul des aires du graphe rapproche
var stackedAreas = d3.area()
.curve(d3.curveBasis)
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.stackedSum); })
.y1(function(d) { return y(d.stackedPrice); });
// Calcul des aires du graphe centre
var centeredAreas = d3.area()
.curve(d3.curveBasis)
.x(function(d) { return x(d.date); })
.y0(function(d) { return y(d.centeredSum); })
.y1(function(d) { return y(d.centeredPrice); });
// Calcul des aires du graphe transparent
var transparentAreas = 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");
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; });
// Calcul du prix
for (i = 0; i < datas.length; ++i) {
for (j = 0; j < datas[i].values.length; ++j) {
var elem = datas[i].values[j];
elem.stackedSum = 0;
for (k = i + 1; k < datas.length; ++k) {
elem.stackedSum += datas[k].values[j].price;
}
elem.stackedPrice = elem.price + elem.stackedSum;
}
}
var maxY = d3.max(data, function(d) { return d.stackedPrice; });
x.domain(d3.extent(data, function(d) { return d.date; }));
// centered :
for (i = 0; i < datas[0].values.length; ++i) {
var blankUnder = (maxY - datas[0].values[i].stackedPrice) / 2;
for (j = 0; j < datas.length; ++j) {
var elem = datas[j].values[i];
elem.centeredPrice = elem.stackedPrice + blankUnder;
elem.centeredSum = elem.stackedSum + blankUnder;
}
}
for (i = 0; i < datas.length; ++i) {
datas[i].maxPrice = d3.max(datas[i].values, function(d) {
return d.price;
});
}
var maxPrice = d3.max(datas, function(d) { return d.maxPrice; });
for (i = 0; i < datas.length; ++i) {
for (j = 0; j < datas[i].values.length; ++j) {
var elem = datas[i].values[j];
elem.base = (maxPrice / 4) * (datas.length - (i + 1));
var normalizedPrice = maxPrice * elem.price / datas[i].maxPrice;
elem.basedPrice = (normalizedPrice / datas.length) + elem.base;
}
}
console.log(datas);
/********** Gestion des Axes **********/
// On crée l'axe X
function createAxisX () {
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.transition()
.delay(1750).remove();
}
// On crée l'axe Y
function createAxisY () {
svg.append("g")
.attr("class", "axis axis--y")
.attr("transform", "translate(0,0)")
.call(d3.axisLeft(y).ticks(20))
.transition()
.delay(1750).remove();
}
// Creation des axes X et Y
function createAxes () {
createAxisX () ;
createAxisY () ;
}
/****************************************/
// On dessine les courbes en fonction du type d'aire
function drawAreas(areaFunc, colorOpacity) {
g.selectAll(".area").data(datas).enter().append("path")
.attr("class", "area")
.attr("d", function(d) { return areaFunc(d.values) })
.attr("fill", function(d, i) { return color(d.key); })
.attr("opacity", colorOpacity)
g.selectAll(".area")
.attr("class", "area")
.transition().duration(1000)
.attr("d", function(d) { return areaFunc(d.values) })
.attr("fill", function(d, i) { return color(d.key); })
.attr("opacity", colorOpacity);
}
/********** Gestion de la Legende **********/
function rightLegend(upperBound, lowerBound) {
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][upperBound] +
vals[vals.length - 1][lowerBound]) / 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][upperBound] +
vals[vals.length - 1][lowerBound]) / 2)) +
")";
})
.select("rect").attr("opacity", 0);
return legend;
}
// On ajoute le texte de la legende
function legendAppendText(legend) {
legend.append("text")
.attr("x", 50)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d) { return d; });
}
/****************************************/
/********** Gestion de la Transition des Graphes **********/
// Generation du graphe separe
function separated() {
y.domain([0, d3.max(data, function(d) { return d.price; })]);
createAxisX();
drawAreas(separatedAreas, 1);
var legend = rightLegend("basedPrice", "base");
legendAppendText(legend);
setTimeout(stacked, 2000);
}
/* ---> Transition ---> */
// Generation du graphe rapproche
function stacked() {
y.domain([0, maxY]);
createAxes();
drawAreas(stackedAreas, 1);
var legend = rightLegend("stackedPrice", "stackedSum");
legendAppendText(legend);
setTimeout(centered, 2000);
}
/* ---> Transition ---> */
// Generation du graphe centre
function centered() {
y.domain([0, maxY]);
createAxes();
drawAreas(centeredAreas, 1);
var legend = rightLegend("centeredPrice", "centeredSum");
legendAppendText(legend);
setTimeout(transparent, 2000);
}
/* ---> Transition ---> */
// Generation du graphe transparent
function transparent() {
y.domain([0, d3.max(data, function(d) { return d.price; })]);
createAxes();
drawAreas(transparentAreas, .5);
var legend = rightLegend("basedPrice", "base");
legendAppendText(legend);
setTimeout(separated, 2000);
}
/****************************************/
// On debute la transition par le graphe separe
separated();
});
</script>
</body>
https://d3js.org/d3.v4.min.js