Reputation: 333
I have a D3 stacked bar chart component and I am trying to make it fill the available space in the parent SVG. This will allow me to resize the chart with HTML rather than having to manually input sizes.
Currently my sizes are hard coded and I have no idea how to change this to a more responsive format.
Here is the relevant component code slice:
let data = this.get('data')
let div = select('body')
.append("div")
.attr("class", "stack-tooltip")
let series = stack()
.keys(["count1", "count2", "count3"])
.offset(stackOffsetDiverging)
(data);
let svg = select(this.$('svg')[0]),
margin = {
top: 20,
right: 30,
bottom: 30,
left: 60
},
width = +svg.attr("width"),
height = +svg.attr("height");
let x = scaleBand()
.domain(data.map(function(d) {
return d.label;
}))
.rangeRound([margin.left, width - margin.right])
.padding(0.1);
let y = scaleLinear()
.domain([min(series, stackMin), max(series, stackMax)])
.rangeRound([height - margin.bottom, margin.top]);
let z = scaleOrdinal().range(['#DAEAF1', '#99CFE0', '#72BCD4']);
svg.append("g")
.selectAll("g")
.data(series)
.enter().append("g")
.attr("fill", function(d) {
return z(d.key);
})
.selectAll("rect")
.data(function(d) {
return d;
})
.enter().append("rect")
.attr("width", x.bandwidth)
.attr("x", function(d) {
return x(d.data.label);
})
.attr("y", function(d) {
return y(d[1]);
})
.attr("height", function(d) {
return y(d[0]) - y(d[1]);
})
.attr('opacity', d => {
let selected = this.get('selectedLabel');
return (selected && d.data.label !== selected) ? '0.5' : '1.0';
})
function stackMin(h) {
return min(h, function(d) {
return d[0];
});
}
function stackMax(h) {
return max(h, function(d) {
return d[1];
});
}
I did try to change the rangeRound values to a percentage on both the 'X' and 'Y' functions but I was unable to render the bars of the chart when trying to change the values in the X and Y attributes to template literals.
The SVG in the component template is created with a simple <svg width='800' height="300"></svg>
Any help is greatly appreciated
Upvotes: 1
Views: 555
Reputation: 101800
If you want it to scale to its parent container, you'll need to give the SVG a viewBox
, instead of a width
and height
.
The viewBox
tells the browser which area of the SVG coordinate space, the contents occupy. That way it knows how to scale the contents.
Upvotes: 1