Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

195
Visualizações
D3: use an alternate field for axis labels with scaleBand

I'm working on a D3 (V5) chart from a dataset that includes both a JobCode (unique) and JobTitle (not unique). I need to use the JobCode for the axis, but would like to display the JobTitle as the label.

enter image description here

Relevant code:

const xScale = d3.scaleLinear().domain([0,d3.max(grouped, d => d.jobCodeMax)-d3.min(grouped, d => d.jobCodeMax)]).range([0,width-margin.left-margin.right]);
const yScale = d3.scaleBand().domain(grouped.map(d => d.all[0].jobCode)).range([0,height - margin.top - margin.bottom]).padding(0.3);
const yAxis = d3.axisLeft(yScale);
const xAxis = d3.axisTop(xScale);
const radius = yScale.bandwidth()/2.75
const g = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`)

yAxis(g.append("g"));
xAxis(g.append("g"));

I can access the jobTitles with d.jobTitle.

My tentative plan is to abandon the d3.axisLeft() function and draw my own. Is there a more straightforward method? Something like a parameter to d3.axisLeft() where I specify an alternate field?

Thank you for any insights.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

The domain of d3.scaleBand:

... Domain values are stored internally in an InternMap from primitive value to index; the resulting index is then used to determine the band. Thus, a band scale’s values must be coercible to a primitive value, and the primitive domain value uniquely identifies the corresponding band. ...

InternMap extends a standard Map object which - so we can see that values in the domain of a scaleBand need to be unique.

To get the result you want you can switch the text values to jobTitle after the axis is rendered e.g.:

// replace text values on y axis
yLabels = d3.selectAll(".yaxis g text");
yLabels.each(function(d, i) { d3.select(this).text(data[i].alias) });

Using arrow functions, the equivalent is:

// arrow function way
yLabels = d3.selectAll(".yaxis g text");
yLabels.each((d, i, n) => d3.select(n[i]).text(data[i].alias))

Working example below:

const margin = {top: 10, bottom: 30, left: 60, right: 10}
const width = 500 - margin.left - margin.right;
const height = 180 - margin.top - margin.bottom;
const svg = d3.select("body")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", `translate(${margin.left}, ${margin.top})`);

const data = [
  {group: "A", value: 3, alias: "foo"}, 
  {group: "B", value: 1, alias: "foo"}, 
  {group: "C", value: 2, alias: "bar"},
  {group: "D", value: 5, alias: "bar"},
  {group: "E", value: 4, alias: "bar"}
];

const xScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([0, width]);

const yScale = d3.scaleBand()
  .domain(data.map(d => d.group))
  .range([height, 0])
  .padding(.2);

const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);
  
const gXAxis = svg.append("g")
  .attr("transform", `translate(0, ${height})`)
  .call(xAxis);

const gYAxis = svg.append("g")
  .attr("class", "yaxis")
  .call(yAxis);

svg.selectAll(".bar")
  .data(data)
  .enter()
  .append("rect")
  .attr("x", xScale(0))
  .attr("y", d => yScale(d.group))
  .attr("width", d => xScale(d.value))
  .attr("height", yScale.bandwidth())
  .attr("fill", "steelblue");
  
// replace text values on y axis
yLabels = d3.selectAll(".yaxis g text");
yLabels.each(function(d, i) { d3.select(this).text(data[i].alias) });
// arrow function way
//yLabels.each((d, i, n) => d3.select(n[i]).text(data[i].alias))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda