Graphiques à barres superposées PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Chevauchement des graphiques à barres

Comme leur nom l'indique, les graphiques superposés visualisent deux ensembles de données différents dans un seul diagramme. L’idée est que les barres qui se chevauchent nous permettent de comparer les données, disons d’une année sur l’autre. Ils sont également utiles pour des choses comme le suivi des progrès vers un objectif où une barre représente l'objectif et l'autre indique le montant actuel.

Mais ils sont beaux aussi !

Chevauchement des graphiques à barres

Votre esprit est probablement comme le mien et vous commencez déjà à comprendre comment vous pourriez procéder et coder cela. Voici comment je l'ai abordé.

Le HTML

Nous allons commencer par le balisage car, eh bien, c'est ainsi que nous savons ce qui nécessite un style.

<div class="container">
  <div class="chart">
    <dl class="numbers">
      <dd><span>100%</span></dd>
      <!-- all the way to 0% -->
    </dl>
    <dl class="bars">
      <div>
          <dt>2018</dt>
          <dd>
            <div class="bar" data-percentage="50"></div>
            <div class="bar overlap" data-percentage="53"></div>
          </dd>
        </div>
      <div>
      <!-- more bars -->
    </dl>
  </div>
</div>

Nous utiliserons des listes de descriptions (<dl>) car il s'agit d'une approche beaucoup plus sémantique par rapport aux listes ordonnées et non ordonnées standard. Une autre raison est que nous incluons une étiquette dans chaque barre. Les listes normales ne contiennent pas de balise pour ajouter un titre ou une description contrairement aux listes de définitions. En termes simples, cela a tout simplement plus de sens et est également plus lisible.

La première liste de description, .numbers, est l'axe des y. Le .bars C'est là que les données sont visualisées et j'ai fait une liste de définitions pour construire également l'axe des x. Chaque élément de la liste contient un .bar et l'étiquette comme terme de description (dt).

Et que se passe-t-il avec les données attribuer? le data-percentage est utilisé pour spécifier la hauteur de la barre, qui représente finalement sa valeur sur l'axe des y. Nous pourrions le définir manuellement en CSS pour chaque barre, mais cela est répétitif et nécessite beaucoup de code supplémentaire qui peut être remplacé par quelques lignes de CSS.

Les styles de graphiques de base

Nous travaillons avec de nombreuses directions bidimensionnelles, donc flexbox sera notre ami pour tout aligner. Nous pouvons faire le .chart élément un conteneur flexible qui positionne les étiquettes de l'axe Y et le graphique les uns à côté des autres dans le row direction.

.chart {
  display: flex;
}

Nous n'avons même pas besoin de spécifier la direction puisque la valeur par défaut de flexbox est row. Faisons cela, puis ajoutons flexbox à la liste des étiquettes le long de l'axe y pendant que nous y sommes, car nous savons qu'elles s'exécuteront dans le column direction.

.numbers {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0 15px 0 0;
  padding: 0;
}

Croyez-le ou non, nous pouvons à nouveau utiliser flexbox pour les barres puisque, elles aussi, fonctionnent de manière row direction.

.bars {
  display: flex;
  flex: auto; /* fill up the rest of the `.chart` space */
  gap: 60px;
}

J'ai configuré cela pour que le .bars occupe automatiquement tout l'espace restant par le y-axis .numbers.

Vous l'avez probablement remarqué dans le HTML, mais « bar » est en fait deux barres dont l'une se chevauche l'autre. Je les ai emballés dans un générique <div> que nous pouvons utiliser comme un autre conteneur flexible contenant le terme de définition (<dt>) nous utilisons comme étiquette et les détails de la description (<dd>) qui contient les deux valeurs de barre :

.bars > div {
  align-items: center;
  display: flex;
  flex-direction: column;
  flex: 1;
  position: relative;
}

Chaque barre aura la même largeur, donc flex: 1. Nous positionnons l'élément de manière relative pendant que nous y sommes car nous sommes sur le point de positionner absolument chaque barre et nous voulons nous assurer qu'elles restent dans leurs conteneurs.

Chaque barre a une hauteur en pourcentage qui correspond aux valeurs le long de l'axe y vertical. Vous vous souviendrez peut-être aussi que nous avons attribué à chaque barre un data-percentage attribut - nous allons saupoudrer un peu de JavaScript qui définit la hauteur de chaque barre en utilisant ces valeurs.

var bars = document.querySelectorAll("dd .bar");
bars.forEach((bar) => {
  var height = bar.getAttribute("data-percentage");
  bar.style.height = height + "%";
});

C'est notre tableau de base !

Nous voulons arriver à ce que nous puissions voir les barres se chevaucher. C'est la suite !

Barres superposées

L'astuce pour faire en sorte qu'une barre en chevauche une autre est amusante car on essaie souvent de empêcher les choses ne se chevauchent pas visuellement en CSS. Mais dans ce cas-ci, nous souhaitons réellement que cela se produise.

Les barres se chevauchent déjà ; c'est juste difficile à dire. Notez dans le HTML que le deuxième .bar dans chaque ensemble a un supplémentaire .overlap classe. Utilisons cela pour différencier les barres. Vous êtes totalement libre de choisir votre propre style pour cela. J'ajoute un peu de rembourrage au .overlap barres afin qu'elles soient plus larges que les autres barres. Ensuite, je modifie l'ordre d'empilement en utilisant z-index de sorte que la .overlap les barres se trouvent en dessous des autres barres.

Ajoutons une légende

Légende. C'est un si beau mot, n'est-ce pas ? Plein de toutes sortes de significations. Dans ce cas, c'est plus qu'une belle touche car, visuellement, nous encombrons deux barres dans des espaces qui sont généralement réservés à une seule barre. Une légende fournit un contexte qui explique ce que représente chaque barre.

<figure class="legend">
  <div class="type1">Estimate</div>
  <div class="type2">Actual</div>
</figure>

L'utilisation d'un <figure> cela me semble correct. Ils sont souvent utilisés pour envelopper des images, mais la spécification dit ils sont utilisés « pour annoter des illustrations, des diagrammes, des photos, des listes de codes, etc. » et nous travaillons avec un diagramme. Nous pourrions probablement utiliser une liste non ordonnée pour contenir les éléments, mais j'ai opté pour une liste non sémantique <div>. Si quelqu'un a une opinion sur la meilleure façon de marquer cela, je suis tout ouïe dans les commentaires !

Encore une fois, le style dépend entièrement de vous :

Considérations d'accessibilité

Nous avons consacré une grande partie de nos efforts à prendre des décisions concernant le balisage et le style de notre graphique à barres superposées. C'est formidable jusqu'à présent, mais nous n'avons certainement pas terminé car nous pouvons faire davantage pour rendre cela plus agréable. accessible expérience. Tout le monde n'est pas un internaute voyant, il y a donc un travail supplémentaire à faire pour transmettre le contenu dans ces contextes.

Plus précisément, nous devons :

  1. vérifier que nos couleurs ont beaucoup de contraste entre elles,
  2. permettre aux utilisateurs du clavier de tabuler sur chaque barre qui se chevauche, et
  3. assurez-vous que les lecteurs d’écran annoncent le contenu.

Contrastes de couleurs

Nous avons besoin de suffisamment de contraste entre :

  • les barres qui se chevauchent
  • les barres et l'arrière-plan du graphique
  • le texte et l'arrière-plan de l'étiquette

J'ai fait quelques devoirs à l'avance sur les couleurs que j'ai utilisées dans les exemples que nous avons examinés jusqu'à présent, en m'assurant qu'il y en avait suffisamment. contraste entre les premiers plans et les arrière-plans pour atteindre la conformité WCAG AA.

Voici ce que j'utilise :

  • Barres superposées : (#25DEAA ainsi que les #696969: rapport 3.16:1)
  • Barres et arrière-plan du graphique (#696969 ainsi que les #111: rapport 3.43:1)
  • Texte et arrière-plan de l'étiquette de l'axe Y (#fff ainsi que les #333: 12.63 : 1)

Tabulation entre les barres

Pour obtenir cela, les utilisateurs du clavier peuvent sélectionner chaque barre individuelle avec le Languette clé, nous pouvons atteindre le HTML tabindex attribut. Nous pouvons utiliser le JavaScript suivant dans la fonction for-each pour ajouter cette propriété à chaque barre (les deux). Nous allons définir l'index des onglets sur 0:

bar.setAttribute("tabindex", 0);

On peut aussi ajouter du CSS pour améliorer le contour lorsque la barre est sélectionnée tant qu'on y est :

.bar:focus {
  outline: 1.5px solid #f1f1f1;
}

Annoncer du contenu sur les lecteurs d'écran

Un autre aspect important de l'accessibilité consiste à garantir que les lecteurs d'écran peuvent annoncer les barres et leurs pourcentages.

Nous travaillons avec deux graphiques différents en un : un graphique qui montre les valeurs « estimées » et un autre qui montre les valeurs « réelles ». Ce serait génial si l'utilisateur savait quelle barre était annoncée, alors étiquetons-les avec le aria-label attribut:

<div class="bar" data-percentage="50" aria-label="Estimate">50%</div>

Notez que nous avons également la valeur de la barre directement dans le code HTML. Cela sera annoncé, mais nous souhaitons toujours le cacher visuellement. Nous pourrions utiliser transparent texte pour cela, mais une autre façon est d'utiliser le classiques .visually-hidden astuce en enveloppant la valeur dans span:

<div class="bar" data-percentage="50" aria-label="Estimate">
  <span class="visually-hidden">50%</span>
</div>
.visually-hidden {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

Pendant que nous parlons d'annoncer du contenu, nous pouvons probablement empêcher la lecture des étiquettes de l'axe Y. Ce n'est pas comme si l'utilisateur manquait d'informations, car les pourcentages réels pour chaque barre sont déjà disponibles et annoncés. Nous pouvons utiliser le aria-hidden attribut pour cela :

<dl class="numbers" aria-hidden="true">
  <dd><span>100%</span></dd>
  <dd><span>80%</span></dd>
  <dd><span>60%</span></dd>
  <dd><span>40%</span></dd>
  <dd><span>20%</span></dd>
  <dd><span>0%</span></dd>
</dl>

Je pense aussi que les lecteurs d'écran peuvent ignorer la légende puisqu'il s'agit d'une aide visuelle :

<figure class="legend" aria-hidden="true">
  <div class="type1">Estimate</div>
  <div class="type2">Actual</div>
</figure>

La démo finale

C'est un wrap!

Et voilà, un graphique avec des barres qui se chevauchent ! C'est une bonne façon de comparer des données et j'espère que vous pourrez en trouver une utilité sur certains projets.

Y a-t-il d'autres façons dont nous aurions pu aborder cela ? Bien sûr! Tout ce que nous avons couvert ici ne fait que vous guider à travers mon processus de réflexion. J'imagine que certains d'entre vous auraient adopté une approche différente — si c'est votre cas, partagez-la ! Ce serait formidable de voir d'autres techniques de mise en page CSS et des perspectives sur l'accessibilité.

Horodatage:

Plus de Astuces CSS