Reputation: 484
I am trying to set the x attribute values of single stacked horizontal bar chart. After messing with javascript for about an hour, I can't seem to get the x values lined up so that the bars line up one after the other from largest value to smallest.
Below is my js:
const abuseNeglectData = [
{
type: "Neglected-Related",
data: 122214,
color: "red",
},
{
type: "Abuse-Related",
data: 47364,
color: "orange",
},
{
type: "Other",
data: 2972,
color: "blue",
},
];
dataSum = d3.sum(abuseNeglectData, d=>{return d.data})
const width = 400,
height = 100,
bottom = 20,
xScale = d3
.scaleLinear()
.range([0,width])
.domain([
0,dataSum
]),
xBand = d3.scaleBand()
.range([0,width])
.domain(abuseNeglectData.map(d=>{return d.data}));
const svg = d3.select('.graph-wrapper.abuse-neglect').append('svg')
.attr('width', width)
.attr('height', height + bottom);
svg.append('g').attr('class','bars').selectAll('rect')
.data(abuseNeglectData)
.enter()
.append('rect')
.attr('y', d=>{return 0})
.attr('height',d=>{return height})
.style('width',d=> {return xScale(d.data)+'px'})
.style('fill', d=>{return d.color})
.attr('x',d=>{return xBand(d.data)})
//xaxis
svg.append('g').attr('class','x-axis')
.call(d3.axisBottom(xBand))
.attr('transform',`translate(0,${height})`)
Thanks for the help.
Upvotes: 1
Views: 80
Reputation: 1787
You can manually calculate the x coordinate for each bar based on the preceding elements' values, which offsets the rect. The example below does that within a forEach loop.
const abuseNeglectData = [
{
type: "Neglected-Related",
data: 122214,
color: "red",
},
{
type: "Abuse-Related",
data: 47364,
color: "orange",
},
{
type: "Other",
data: 2972,
color: "blue",
},
];
dataSum = d3.sum(abuseNeglectData, d=>{return d.data})
let offset = 0
abuseNeglectData.forEach(function(d){
d.offset = offset
offset = offset + d.data
})
const width = 400,
height = 100,
bottom = 20,
xScale = d3
.scaleLinear()
.range([0,width])
.domain([
0,dataSum
]);
const svg = d3.select('body'/*'.graph-wrapper.abuse-neglect'*/).append('svg')
.attr('width', width)
.attr('height', height + bottom);
svg.append('g').attr('class','bars').selectAll('rect')
.data(abuseNeglectData)
.enter()
.append('rect')
.attr('y', d=>{return 0})
.attr('height',d=>{return height})
.style('width',d=> {return xScale(d.data)+'px'})
.style('fill', d=>{return d.color})
.attr('x',d=>{return xScale(d.offset)})
svg.append('g').attr('class','x-axis')
.call(d3.axisBottom(xScale))
.attr('transform',`translate(0,${height})`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Upvotes: 2