2 votes

Impossible d'empiler les rectangles horizontalement

Je cherche simplement à trouver le moyen le plus simple/le plus sublime de créer une seule rangée de rectangles empilés. Utiliser un compteur let comme dans Comment empiler les rectangles en fonction de la hauteur du rectangle précédent? pour stocker le point de données précédent peut fonctionner ou calculer tous les points directement peut aussi fonctionner comme dans: http://bl.ocks.org/wpoely86/e285b8e4c7b84710e463. Pourtant, ces deux méthodes semblent vraiment élaborées pour ce qui semble être une tâche simple : trouver où placer le x d'un rectangle et quelle largeur ce rectangle devrait avoir. J'ai opté pour l'approche avec le let ci-dessous dans cet extrait de code :

    var margins = {top:20, bottom:300, left:30, right:100};

var height = 600;
var width = 900;

var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;

var svg = d3.select('body')
    .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight);

var graphGroup = svg.append('g')
    .attr('transform', "translate("+margins.left+","+margins.top+")");

 var qScale = d3.scaleLinear()
    .range([749,0])
    .domain([0,20]);

var quartiles = [3.78, 6.69, 10.09];

let qCounter = 0;
let wCounter = 0;

graphGroup.selectAll('.markers')
    .data(quartiles)
    .enter()
    .append('rect')
    .attr('class', 'markers')
    .attr('x', function(d) {
      let previous = qCounter;
      return (qCounter += qScale(d), previous)
    })
    .attr('y', 50)
    .attr('width', function(d) {return 749-qScale(d); })
    .attr('height', 50)
    .style('fill', 'gray')
    .style('stroke', '3px');

Ça ne semble pas fonctionner correctement, il n'y a que 2 rectangles. Il devrait y en avoir 3 et ils devraient être empilés les uns contre les autres. Leur largeur est déterminée par les valeurs dans quartiles.

Question

En supposant que ma logique .attr('x') est bonne, comment puis-je déterminer la bonne largeur pour les rectangles ?

Je rencontre le même problème car je n'ai aucun moyen à portée de main pour faire référence au point de données précédent si je voulais essayer de calculer la largeur du rectangle comme le pseudocode : qScale(d[1]) - qScale(d[0]). Dois-je créer un autre compteur pour chaque attribut de ce type ? J'utilise d3 v5, n'y a-t-il vraiment pas de moyen plus simple de trouver le point de données précédent pour l'utiliser avec l'empilement des rectangles et similaires ?

2voto

Gerardo Furtado Points 61849

Votre plage de qScale est inversée, cela devrait être :

.range([0, 749])

Mieux encore, vous devriez éviter les nombres magiques :

.range([0, width])

Après avoir fait cela, changez la largeur juste à ceci :

.attr('width', function(d) {
    return qScale(d);
})

Voici le code avec ces changements, et en utilisant une échelle de couleurs pour différencier les barres :

var margins = {
  top: 20,
  bottom: 300,
  left: 30,
  right: 100
};

var height = 600;
var width = 900;

var totalWidth = width + margins.left + margins.right;
var totalHeight = height + margins.top + margins.bottom;

var svg = d3.select('body')
  .append('svg')
  .attr('width', totalWidth)
  .attr('height', totalHeight);

var graphGroup = svg.append('g')
  .attr('transform', "translate(" + margins.left + "," + margins.top + ")");

var colors = d3.schemeCategory10;

var qScale = d3.scaleLinear()
  .range([0, width])
  .domain([0, 20]);

var quartiles = [3.78, 6.69, 10.09];

let qCounter = 0;
let wCounter = 0;

graphGroup.selectAll('.markers')
  .data(quartiles)
  .enter()
  .append('rect')
  .attr('class', 'markers')
  .attr('x', function(d) {
    let precedent = qCounter;
    return (qCounter += qScale(d), precedent)
  })
  .attr('y', 50)
  .attr('width', function(d) {
    return qScale(d);
  })
  .attr('height', 50)
  .style('fill', function(_, i) {
    return colors[i]
  })
  .style('stroke', '3px');

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X