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).
And here is the chart if my data is higher than the domain I set on my backend:
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))....