forked from jdmarlin's block: Stacked Bar Chart
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
const data = [
{
'package': 'AAPL',
'nominal': '-100.0',
'financing_type': 'pay'
},
{
'package': 'AAPL',
'nominal': '-200.0',
'financing_type': 'pay'
},
{
'package': 'AAPL',
'nominal': '150.0',
'financing_type': 'receive'
},
{
'package': 'AAPL',
'nominal': '160.0',
'financing_type': 'receive'
},
{
'package': 'AMZN',
'nominal': '100',
'financing_type': 'receive'
},
{
'package': 'AMZN',
'nominal': '-110',
'financing_type': 'pay'
}
]
const nest = d3.nest()
.key(d => d.package)
.rollup(packages => {
let obj = {};
let netNominal = d3.sum(packages, d => d.nominal);
netNominal >= 0 ? key = 'surplus' : key = 'deficit'
obj[key] = Math.abs(netNominal);
let nominal = d3.nest()
.key(d => d.financing_type)
.rollup(financing => d3.sum(financing, d => d.nominal))
.entries(packages)
nominal = nominal.length > 1 ? d3.min(nominal, d => Math.abs(d.value)) : 0
obj['package'] = packages[0].package
obj['nominal'] = nominal
obj['total'] = obj['nominal'] + obj[key]
return obj
})
.entries(data)
const svg = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 200)
const margin = {top: 20, right: 20, bottom: 30, left: 40}
const width = svg.attr('width') - margin.left - margin.right
const height = svg.attr('height') - margin.top - margin.bottom
const g = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
const x = d3.scaleLinear()
.domain([0, d3.max(nest, d => d.value.total)])
.range([1, width]).nice()
const y = d3.scaleBand()
.domain(nest.map(d => d.key))
.range([height, 0])
.padding(0.1)
// var x = d3.scaleBand()
// .domain(nestData.map(d => d.key))
// .rangeRound([0, width])
// .paddingInner(0.05)
// var y = d3.scaleLinear()
// .domain([0, d3.max(nestData, d => d.value.total)])
// .rangeRound([height, 0]).nice()
var z = d3.scaleOrdinal()
.range(["#dbdbdb", "#00b774", "#fe434f"]);
g.append('g')
.attr('class', 'axis x-axis')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(x))
g.append('g')
.attr('class', 'axis y-axis')
.call(d3.axisLeft(y).ticks(null, 's'))
g.append('g')
.selectAll('g')
.data(d3.stack().keys(['nominal', 'surplus', 'deficit'])(nest.map(d => d.value)))
.enter().append("g")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(d => d)
.enter().append("rect")
.attr('x', d => x(d[0]))
.attr('y', d => y(d.data.package))
.attr('height', y.bandwidth())
.attr('width', d => (x(d[1]) - x(d[0])))
// .attr('x', d => x(d.data.package))
// .attr('y', d => y(d[1]))
// .attr('height', d => (y(d[0]) - y(d[1])))
// .attr('width', x.bandwidth())
</script>
</body>
https://d3js.org/d3.v4.min.js