Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

partition.padding should accept a function? #123

Open
alexlenail opened this issue Sep 7, 2018 · 1 comment
Open

partition.padding should accept a function? #123

alexlenail opened this issue Sep 7, 2018 · 1 comment

Comments

@alexlenail
Copy link

alexlenail commented Sep 7, 2018

What if partition.padding accepted a function which returned an int, instead of just an int?

d3.partition().size([w, h]).padding(d => d.height * 10).round(true);

Result would look like:

untitled drawing

@alexlenail alexlenail changed the title partition.padding dependent on node height / depth [FR]: partition.padding dependent on node height / depth Sep 7, 2018
@alexlenail
Copy link
Author

alexlenail commented Sep 10, 2018

I have solved this problem via this ghastly code:

let sum_counts_objects = (a, b) => _.object(_.uniq(Object.keys(a).concat(Object.keys(b))).map(key => [key, (a[key] || 0) + (b[key] || 0)]));

...

margin = {'2': 10};

...


    function offset(partition, margin) {

        counter = 0; current_depth = 0;
        partition.each((node) => {
            node.num_below = _(node.descendants().map(d => d.height)).countBy();

            if (node.depth !== current_depth) { current_depth = node.depth; counter = 0; }
            node.sibling_index = counter; counter += 1;
        });

        partition.each((node) => {
            if (node.parent) {
                node.num_left = node.parent.children.filter(sibling => sibling.sibling_index !== undefined && sibling.sibling_index < node.sibling_index)
                                                    .reduce((acc, sibling) => sum_counts_objects(acc, sibling.num_below), {});

                node.offset = d3.sum(Object.entries(node.num_left).map(([level, num]) => (margin[level] || 0)*(num))) + node.parent.offset;
                node.x0 += node.offset;
                node.x1 += node.offset + d3.sum(Object.entries(node.num_below).map(([level, num]) => (margin[level] || 0)*(num-1)));
            } else {
                node.offset = 0;
                node.num_left = 0;
                node.x1 += d3.sum(Object.entries(node.num_below).map(([level, num]) => (margin[level] || 0)*(num-1)));
            }
        });

    }

I believe this is a fairly general approach, if you'd like to specify the margin between items at each of the levels, vial the margin object.

@mbostock mbostock changed the title [FR]: partition.padding dependent on node height / depth partition.padding should accept a function? Oct 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant