web-dev-qa-db-fra.com

étiquetage axe d3

Comment ajouter des étiquettes de texte aux axes dans d3?

Par exemple, j'ai un graphique linéaire simple avec un axe x et y.

Sur mon axe x, les graduations vont de 1 à 10. Je veux que le mot "jours" apparaisse en dessous afin que les gens sachent que l'axe x compte les jours.

De même, sur l’axe des ordonnées, les chiffres 1 à 10 sont marqués comme des graduations et je veux que les mots "sandwichs mangés" apparaissent latéralement.

Y a-t-il un moyen simple de faire cela?

90
user1474218

Les étiquettes d'axe ne sont pas intégrées aux composants D3 composant de l'axe , mais vous pouvez les ajouter vous-même en ajoutant simplement un élément SVG text. Un bon exemple de ceci est ma reconstitution du graphique à bulles animé de Gapminder, La richesse et la santé des nations . L'étiquette de l'axe des x ressemble à ceci:

svg.append("text")
    .attr("class", "x label")
    .attr("text-anchor", "end")
    .attr("x", width)
    .attr("y", height - 6)
    .text("income per capita, inflation-adjusted (dollars)");

Et l'étiquette d'axe des y ressemble à ceci:

svg.append("text")
    .attr("class", "y label")
    .attr("text-anchor", "end")
    .attr("y", 6)
    .attr("dy", ".75em")
    .attr("transform", "rotate(-90)")
    .text("life expectancy (years)");

Vous pouvez également utiliser une feuille de style pour styler ces étiquettes à votre guise, soit ensemble (.label) ou individuellement (.x.label, .y.label).

157
mbostock

Dans la nouvelle version de D3js (à partir de la version 3), lorsque vous créez un axe de graphique à l'aide de la fonction d3.svg.axis(), vous avez accès à deux méthodes appelées tickValues et tickFormat. dans la fonction pour que vous puissiez spécifier les valeurs pour lesquelles vous avez besoin des ticks et dans quel format vous souhaitez que le texte apparaisse:

var formatAxis = d3.format("  0");
var axis = d3.svg.axis()
        .scale(xScale)
        .tickFormat(formatAxis)
        .ticks(3)
        .tickValues([100, 200, 300]) //specify an array here for values
        .orient("bottom");
30
ambodi

Si vous voulez que l'étiquette d'axe des y soit au milieu de celui-ci, comme je l'ai déjà fait:

  1. Faire pivoter le texte de 90 degrés avec le centre d'ancrage du texte
  2. Traduire le texte par son point milieu
    • position x: pour éviter le chevauchement des étiquettes de graduation sur l'axe des y (-50)
    • position y: pour correspondre au point médian de l’axe des y (chartHeight / 2)

Exemple de code:

var axisLabelX = -50;
var axisLabelY = chartHeight / 2;

chartArea
    .append('g')
    .attr('transform', 'translate(' + axisLabelX + ', ' + axisLabelY + ')')
    .append('text')
    .attr('text-anchor', 'middle')
    .attr('transform', 'rotate(-90)')
    .text('Y Axis Label')
    ;

Ceci empêche la rotation de tout le système de coordonnées comme mentionné par lubar ci-dessus.

12
Michael Clark

D3 fournit un ensemble de composants de bas niveau que vous pouvez utiliser pour assembler des graphiques. Vous obtenez les blocs de construction, un composant d'axe, une jointure de données, une sélection et un fichier SVG. C'est à vous de les assembler pour former un tableau!

Si vous voulez un graphique conventionnel, c'est-à-dire une paire d'axes, des étiquettes d'axe, un titre de graphique et une zone de tracé, pourquoi ne pas jeter un œil à d3fc ? c'est un ensemble open source de plusieurs composants D3 de haut niveau. Il comprend un composant de graphique cartésien qui pourrait être ce dont vous avez besoin:

var chart = fc.chartSvgCartesian(
    d3.scaleLinear(),
    d3.scaleLinear()
  )
  .xLabel('Value')
  .yLabel('Sine / Cosine')
  .chartLabel('Sine and Cosine')
  .yDomain(yExtent(data))
  .xDomain(xExtent(data))
  .plotArea(multi);

// render
d3.select('#sine')
  .datum(data)
  .call(chart);

Vous pouvez voir un exemple plus complet ici: https://d3fc.io/examples/simple/index.html

1
ColinE

Si vous travaillez dans d3.v4, comme suggéré, vous pouvez utiliser cette instance en offrant tout ce dont vous avez besoin.

Vous voudrez peut-être simplement remplacer les données de l'axe X par vos "jours", sans oublier d'analyser correctement les valeurs de chaîne sans appliquer de concaténation.

parseTime pourrait aussi bien faire l'affaire pour la mise à l'échelle des jours avec un format de date?

d3.json("data.json", function(error, data) {
if (error) throw error;

data.forEach(function(d) {
  d.year = parseTime(d.year);
  d.value = +d.value;
});

x.domain(d3.extent(data, function(d) { return d.year; }));
y.domain([d3.min(data, function(d) { return d.value; }) / 1.005, d3.max(data, function(d) { return d.value; }) * 1.005]);

g.append("g")
    .attr("class", "axis axis--x")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x));


g.append("g")
    .attr("class", "axis axis--y")
    .call(d3.axisLeft(y).ticks(6).tickFormat(function(d) { return parseInt(d / 1000) + "k"; }))
  .append("text")
    .attr("class", "axis-title")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .attr("fill", "#5D6971")
    .text("Population)");

bidouiller avec global css/js

1
因特网的小熊
chart.xAxis.axisLabel('Label here');

ou

xAxis: {
   axisLabel: 'Label here'
},
0
Ravi Tej