Created
October 6, 2022 14:31
-
-
Save janwillemtulp/f1d7e20b7b226fa93912db9571932fbd to your computer and use it in GitHub Desktop.
Single property stack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* D3 js has a stack function: https://github.com/d3/d3-shape#stack | |
* But this function builds a stack of several properties (using the keys function) per row in the array. | |
* Often you may want to create a single stack for a full array based on 1 of its properties. | |
* That's what this function does. | |
* It will subdivide the available space (height) which you can set proportionally based on the values of the key that you provide. | |
* You can also set the padding which will be the spacing between. | |
* | |
* So, here's an example of how to call it: | |
* import { singlePropertyStack } from './singlePropertyStack.js'; | |
* | |
* const data = [{ a: 4 }, { a: 3 }, { a: 8 }, { a: 7 }, { a: 1 }]; | |
* const result = singlePropertyStack().padding(5).height(100)(data, 'a'); | |
* | |
* // result = [ | |
* // {y0: 0, y1: 13.91304347826087, data: { a: 4 }}, | |
* // {y0: 18.913043478260867, y1: 29.34782608695652, data: { a: 3 }}, | |
* // {y0: 34.347826086956516, y1: 62.17391304347825, data: { a: 8 }}, | |
* // {y0: 67.17391304347825, y1: 91.52173913043478, data: { a: 7 }}, | |
* // {y0: 96.52173913043478, y1: 100, data: { a: 1 }} | |
* // ] | |
**/ | |
function constant(x) { | |
return function () { | |
return x; | |
}; | |
} | |
export default function () { | |
let padding = constant(0); | |
let height = constant(400); | |
function singleStack(data, key) { | |
const total = data.reduce((acc, d) => acc + d[key], 0); | |
const totalPadding = (data.length - 1) * padding(); | |
return data.reduce((acc, d, i) => { | |
if (i === 0) { | |
acc.push({ y0: 0, y1: (d[key] / total) * (height() - totalPadding), data: d }); | |
} else { | |
acc.push({ | |
y0: acc[i - 1].y1 + padding(), | |
y1: acc[i - 1].y1 + padding() + (d[key] / total) * (height() - totalPadding), | |
data: d | |
}); | |
} | |
return acc; | |
}, []); | |
} | |
singleStack.padding = function (_) { | |
return arguments.length ? ((padding = typeof _ === 'function' ? _ : constant(_)), singleStack) : padding; | |
}; | |
singleStack.height = function (_) { | |
return arguments.length ? ((height = typeof _ === 'function' ? _ : constant(_)), singleStack) : height; | |
}; | |
return singleStack; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment