J'utilise actuellement des graphiques ngx pour Angular2, et je voudrais personnaliser certaines légendes, par exemple placez la légende sous le graphique, ou renommez les champs de légende, ou agrandissez la légende (certaines parties du texte sont simplement coupées ..) etc.
Existe-t-il de bonnes options pour personnaliser la légende? Ou n'est-il généralement pas possible, ou quelle est la meilleure façon de le faire? Actuellement, mes légendes de graphique ressemblent à ceci:
Certaines légendes sont trop larges, certaines sont coupées, et je voudrais placer la légende par exemple sous le graphique ...
Pour positionner la légende sous le graphique, vous pouvez utiliser l'entrée legendPosition
:
<ngx-charts-chart [legendPosition]="'below'" [results]="chartData" [legend]="true"></ngx-charts-chart>
Les seules options pour legendPosition
sont 'droite' (par défaut) et 'ci-dessous'.
Il ne semble pas y avoir d'options pour personnaliser les champs de légende (il y a une légende plus personnalisable dans le graphique à secteurs avancé, mais vos exemples sont d'autres types de graphiques.) Je pense que la meilleure solution serait de passer les titres des champs dans votre graphique chartData[i].name
valeurs exactement telles que vous souhaitez qu'elles apparaissent dans la légende, puis personnalisez vos info-bulles pour y afficher un nom de champ différent.
Cette réponse donne un aperçu de la façon de personnaliser les info-bulles. À partir de là, j'ai rassemblé un exemple avec un graphique en courbes qui ressemblera aux info-bulles par défaut, sauf avec un nom de champ différent:
<ngx-charts-line-chart [legendPosition]="'right'" [results]="chartData" [legend]="true">
<ng-template #tooltipTemplate let-model="model">
<xhtml:div class="area-tooltip-container">
<span class="tooltip-label">{{ formatFieldName(model.series) }} • {{ formatXvalue(model.name) }}</span>
<span class="tooltip-val">{{ formatYvalue(model.value) }}</span>
</xhtml:div>
</ng-template>
<ng-template #seriesTooltipTemplate let-model="model">
<xhtml:div class="area-tooltip-container">
<xhtml:div *ngFor="let tooltipItem of model" class="tooltip-item">
<span class="tooltip-item-color" [style.background-color]="tooltipItem.color">
</span>
{{ formatFieldName(tooltipItem.series) }}: {{ formatYvalue(tooltipItem.value) }}
</xhtml:div>
</xhtml:div>
</ng-template>
</ngx-charts-line-chart>
La largeur de la légende est calculée dans le ngx-charts-chart
composant que les autres graphiques étendent. Il définira la largeur à environ 1/6 ou 1/12 du conteneur de graphique, selon votre type de données. Il n'y a aucun moyen d'entrer une largeur différente dans cette légende, donc votre solution la plus simple est de définir legendPosition
sur 'en dessous' lorsque la largeur automatique ne fonctionne pas pour vous.
Cependant, vous n'avez pas besoin d'utiliser la légende intégrée au graphique! Voici une alternative plus complexe (mais plus précise): set [legend]="false"
dans votre graphique, puis ajoutez un nouveau ngx-charts-legend
composant en dehors du graphique.
Vous pouvez soit saisir la largeur et la hauteur de cette légende externe, soit l'encapsuler dans un div qui gère le dimensionnement de manière plus réactive. J'ai dû définir la largeur de la légende à 100% de son conteneur lors de l'utilisation de cette dernière méthode.
Pour que cette solution fonctionne, vous devez lier les événements d'activation de légende externes au graphique et définir certaines des propriétés d'entrée de légende sur Init. Dans le composant qui contient votre graphique, vous aurez besoin de quelque chose comme ceci:
import { ColorHelper } from '@swimlane/ngx-charts';
...
export class ChartContainerComponent implements OnInit {
public activeEntries: any[];
public chartData: { name: string, series: { name: string, value?: string | number }[] }[];
public chartNames: string[];
public colors: ColorHelper;
public colorScheme = { domain: ['#0000FF', '#008000'] }; // Custom color scheme in hex
public legendLabelActivate(item: any): void {
this.activeEntries = [item];
}
public legendLabelDeactivate(item: any): void {
this.activeEntries = [];
}
public ngOnInit(): void {
// Get chartNames
this.chartNames = this.chartData.map((d: any) => d.name);
// Convert hex colors to ColorHelper for consumption by legend
this.colors = new ColorHelper(this.colorScheme, 'ordinal', this.chartNames, this.colorScheme);
}
Ensuite, mon modèle (avec graphique et légende prenant chacun la moitié de la largeur) ressemble à ceci:
<div fxLayout="row">
<div fxFlex="50%">
<ngx-charts-line-chart [legend]="false" [activeEntries]="activeEntries" [results]="chartData" [scheme]="colorScheme"></ngx-charts-line-chart>
</div>
<div fxFlex="50%">
<ngx-charts-legend fxFlex="100%" class="chart-legend" [data]="chartNames" [title]="'Legend Title'" [colors]="colors" (labelActivate)="legendLabelActivate($event)" (labelDeactivate)="legendLabelDeactivate($event)"></ngx-charts-legend>
</div>
</div>