Dessin de plusieurs lignes dans D3.js

Jusqu’à présent, j’utilisais des boucles pour append 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 le X pour tous 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 un moyen plus général d’append ces chemins?

Oui. Tout d’abord, je restructurerais 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 append tous les éléments du 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 distinct, 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] ]; 

Étant donné que la masortingce ne comprend pas la valeur de temps, vous devez rechercher l’accesseur X du générateur de ligne. En revanche, l’accessoire y est simplifié car vous pouvez transmettre la valeur de la masortingce 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 rest la même:

 group.selectAll(".line") .data(values) .enter().append("path") .attr("class", "line") .attr("d", line);