Skip to content

Instantly share code, notes, and snippets.

@janwillemtulp
Created October 6, 2022 14:31
Show Gist options
  • Save janwillemtulp/f1d7e20b7b226fa93912db9571932fbd to your computer and use it in GitHub Desktop.
Save janwillemtulp/f1d7e20b7b226fa93912db9571932fbd to your computer and use it in GitHub Desktop.
Single property stack
/**
* 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