Jusqu'à présent, j'utilisais des boucles pour ajouter des éléments de ligne à une visualisation D3, mais cela ne semble pas dans l'esprit de l'API.
Disons que j'ai des données,
var data = {time: 1, value: 2, value2: 5, value3: 3,value4: 2},
{time: 2, value: 4, value2: 9, value3: 2,value4: 4},
{time: 3, value: 8, value2:12, value3: 2,value4:15}]);
Je voudrais quatre lignes, avec le temps comme X pour les 4.
Je peux faire quelque chose comme ça:
var l = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[1]]);})
.interpolate("basis");
var l2 = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[2]]);})
.interpolate("basis");
var l3 = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[3]]);})
.interpolate("basis");
var l4 = d3.svg.line()
.x(function(d){return xScale(d[keys[0]]);})
.y(function(d,i){
return yScale(d[keys[4]]);})
.interpolate("basis");
Et puis ajoutez-les un par un (ou par une boucle).
var line1 = group.selectAll("path.path1")
.attr("d",l(data));
var line2 = group.selectAll("path.path2")
.attr("d",l2(data));
var line3 = group.selectAll("path.path3")
.attr("d",l3(data));
var line4 = group.selectAll("path.path4")
.attr("d",l4(data));
Existe-t-il une meilleure façon plus générale d'ajouter ces chemins?
Oui. Je voudrais d'abord restructurer vos données pour une itération plus facile, comme ceci:
var series = [
[{time: 1, value: 2}, {time: 2, value: 4}, {time: 3, value: 8}],
[{time: 1, value: 5}, {time: 2, value: 9}, {time: 3, value: 12}],
[{time: 1, value: 3}, {time: 2, value: 2}, {time: 3, value: 2}],
[{time: 1, value: 2}, {time: 2, value: 4}, {time: 3, value: 15}]
];
Maintenant, vous n'avez besoin que d'une seule ligne générique:
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.value); });
Et, vous pouvez ensuite ajouter tous les éléments de chemin en une seule fois:
group.selectAll(".line")
.data(series)
.enter().append("path")
.attr("class", "line")
.attr("d", line);
Si vous souhaitez réduire le format de la structure de données, vous pouvez également extraire les heures dans un tableau séparé, puis utiliser un tableau 2D pour les valeurs. Cela ressemblerait à ceci:
var times = [1, 2, 3];
var values = [
[2, 4, 8],
[5, 9, 12],
[3, 2, 2],
[2, 4, 15]
];
Puisque la matrice n'inclut pas la valeur de temps, vous devez la rechercher à partir de l'accessoire x du générateur de ligne. En revanche, l'accesseur y est simplifié puisque vous pouvez passer la valeur de la matrice directement à l'échelle y:
var line = d3.svg.line()
.interpolate("basis")
.x(function(d, i) { return x(times[i]); })
.y(y);
La création des éléments reste la même:
group.selectAll(".line")
.data(values)
.enter().append("path")
.attr("class", "line")
.attr("d", line);