Home > Back-end >  D3js, dynamically change the domain of X-axis
D3js, dynamically change the domain of X-axis

Time:09-23

The current project that I am working on has this barchart and it has x and y axis. The problem is that if the domain of the X-axis is initialized to be from 0 to 10 from the beginning, that's gonna be even if I have data longer than 10 and the bar will just cover the whole width of the chart. Here's the example if I have smaller data and if the domain is set to 10(which is way higher than the data I have now).

enter image description here

And here is the chart if my data is higher than the domain I set on my backend: enter image description here

It will just go away from the X-axes and the domain will still the same...

My question is: is there any way I can initialize the domain of my x-axis to be the maximum of my data or at least higher than the expected data. Because of that my data are dynamic and I can never know how much to expect so it would be a huge problem if I get some data lost or don't display they real number.

Here's also my snipped code:

var margin = { top: 5, right: 25, bottom: 25, left: 125 },
  width3 = 440 - margin.left - margin.right,
  height3 = 150 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg3 = d3
  .select('#graphic2')
  .append('svg')
  .attr('width', width3   margin.left   margin.right)
  .attr('height', height3   margin.top   margin.bottom)
  .append('g')
  .attr('transform', 'translate('   margin.left   ','   margin.top   ')');

var data = [
  { name: 'a', Number: 1 },
  { name: 'b', Number: 2 },
  { name: 'c', Number: 3 },
  { name: 'd', Number: 4 },
  { name: 'e', Number: 5 },
  { name: 'f', Number: 3 },
  { name: 'g', Number: 2 },
  { name: 'h', Number: 4 },
];

// Add X axis
var x3 = d3.scaleLinear().domain([0, 4]).range([0, width3]);
svg3
  .append('g')
  .attr('transform', 'translate(0,'   height3   ')')
  .call(d3.axisBottom(x3))
  .selectAll('text')
  .style('text-anchor', 'end');

// Y axis
var y3 = d3
  .scaleBand()
  .range([0, height3])
  .domain(
    data.map(function (d) {
      return d.name;
    })
  )
  .padding(0.1);

svg3.append('g').call(d3.axisLeft(y3));

//Bars
svg3
  .selectAll('myRect')
  .data(data)
  .enter()
  .append('rect')
  .attr('x', 4)
  .attr('y', function (d) {
    return y3(d.name);
  })
  .attr('width', function (d) {
    return x3(d.Number);
  })
  .attr('height', y3.bandwidth())
  .attr('fill', function (d) {
    if (d.Number < 45) {
      return '#abd1e0';
    } else if (d.Number > 45 && d.Number < 55) {
      return '#76a1b3';
    } else {
      return '#33505c';
    }
  });
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="graphic2"></div>

CodePudding user response:

Do you want this?

const numbers = data.map(d=>d.Number);
var x3 = d3.scaleLinear().domain(d3.extent(numbers))....
  • Related