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

Manually control horizontal position of nodes? #227

Open
LinqLover opened this issue Aug 24, 2023 · 2 comments
Open

Manually control horizontal position of nodes? #227

LinqLover opened this issue Aug 24, 2023 · 2 comments

Comments

@LinqLover
Copy link

Is your feature request related to a problem? Please describe.
I am visualizing a program trace using this nice package and want to display the exact progress over time. So, every node has a time interval. However, this package has no support for this, I can only provide a duration (endTime - startTime) for each node, and somehow the nodes are then layouted using d3-hierarchy's partition mechanism.

Describe the solution you'd like
Ideally, the possible input format would be extended like this:

 {
   "name": "<name>",
   "value": <value>,
+  "start": <value>,  // optional
+  "stop": <value>,  // optional
   "children": [
     <Object>
   ]
 }

If not both values are specified, the layout would still work as before. Some kind of error checking for out-of-parent times etc. might be appropriate.
However, I'm not sure whether this is in the scope of this project. But it would be great!

Describe alternatives you've considered
My current workaround is to transform my program trace into a hierarchy for d3-flame-graph where all "gaps" between nodes are filled up with transparent spacer nodes:

const toFlamegraphData = frame => {
    const data = {
        frame,
        get name() { return frame.name },
        value: frame.endTime + 1 - frame.startTime
    }
    data.children = []
    if (frame.children.length) {
        let time = frame.startTime
        frame.children.forEach((child, index) => {
            // insert dummy to reserve space
            data.children.push({
                value: child.startTime - time,
                children: []
            })
            // insert child
            data.children.push(toFlamegraphData(child))
            time = child.endTime + 1
        })
        // insert dummy to reserve space
        data.children.push({
            value: frame.endTime + 1 - time,
            children: []
        })
    }
    return data
}

And then I wrap all other functions (label, color, etc.) to answer null/transparent for the dummy nodes. But you can imagine the overhead in terms of inner complexity and performance.

@hrishikeshdok
Copy link

hrishikeshdok commented Sep 18, 2023

+1

This would be super useful feature for displaying datasets that have explicit start and end times for frames. Currently it ends up displaying a left skewed flamegraph by displaying child start == parent start

@LinqLover I ended up implementing something similar to add dummy spacer nodes, but unable to figure out how to style them (to make them transparent). Mind sharing how you made them hidden?


Update:
I ended up implementing the transparency of spacer nodes by doing the following (open to other better ideas :))

  • Setting the spacer node text as undefined
  • Setting the spacer node color to #0000
flamegraph.setColorMapper(function (d, originalColor) {
      return d.data.name ? originalColor : '#0000';
    });
 .d3-flame-graph rect {
-  stroke: #2e8d05;
   fill-opacity: 0.8;
 }

@LinqLover
Copy link
Author

@hrishikeshdok Yes, pretty much this was also my approach. If you still need it, you can find my full code here:

https://github.com/LinqLover/trace4d/blob/8b3fd2665a9bb38c07e78c28d96c0c84e922ae2c/packages/frontend/src/player.js#L248

Interestingly, CSS overrides were not required for me ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants