I'm building a complex nested visualization in Deneb using the full Vega grammar. I have several 'group' marks acting as containers for small multiples, and I need a way for the child marks (rects and symbols) to know their parent's absolute X/Y coordinates on the main canvas. Is there a built-in signal or a specific syntax like parent.x that allows a nested mark to calculate its position relative to the root rather than just the local group origin?
3 answers
In Vega, marks are typically positioned relative to their immediate parent container's coordinate system (0,0). To reference data fields from a parent group, you can use the {"parent": "fieldname"} syntax within an encoding block. However, for absolute geometric positions like the parent's current x or y coordinates, Vega doesn't provide a direct parent.x signal out of the box. The standard workaround is to define a signal at the parent level that captures its layout position and then reference that signal name within the child marks. If you are using a layout operator for small multiples, you might need to pre-calculate the offsets in your data transformation pipeline using a window or formula transform so that each datum already carries its "global" coordinate before it reaches the mark encoding stage.
I've tried using signals, but I struggle when the parent groups are generated dynamically via a facet or from: {data: ...}. If there are 20 groups, how can a single signal name provide the unique position of each specific parent to its respective children
You can use {"field": {"parent": "column_name"}} to grab data, but for layout, naming the group mark and using datum from the parent's facet is usually the most reliable path.
Exactly, Robert. I've found that using the stratify and tree transforms helps here too, as they explicitly assign x and y values to every node in a hierarchy. By using those generated coordinates, you bypass the need to "ask" the parent for its position because the child already has that data-driven coordinate assigned to it during the transform phase.
That is the classic Vega "scoping" challenge, Steven. When you use facets, the signals inside the group are instantiated for each facet. However, you can use "Reactive Geometry" by giving your parent group a name property. Then, child marks can use the boundary or extent of that named group using a signal expression like vlSelectionTest('groupName', ...) or by referencing the group's backing data. If that feels too complex, many pros recommend "flattening" the layout: calculate the X/Y grid coordinates in your Power BI DAX or a Vega transform first, then render everything in one flat coordinate space instead of nesting groups.