1

I have a LWC that has an svg embedded inside of it. The SVG is a D3js tree grid that I can select parent nodes and the children will appear below it. The issue that I am having is that when I embed the component into the lightning app builder page layout, I am limited by the size that I can set the component to. I know that there is a workaround that I could make the svg size really big and have it scroll, but I don't necessarily know the full size of the component if I expand every possible parent node. And if all the nodes are closed, I don't want the user to have a scroll bar with a bunch of whitespace. Is there a way that I can override the Lightning App Builder sizing, so that however long the SVG becomes, the component grows to continue to make it visible to the user? Thanks!

Update:

This is essentially the component I am building. https://blockbuilder.org/mbostock/1093025 Unlike a static SVG, this one with the expanding/collapsing of the different elements changes the height differing amounts. So I essentially need a way of figuring out the height as I expand and collapse the different nodes.

2
  • Maybe I'm missing something here, but App Builder can respond to the height of your component's content. I'm not experienced with D3js, but I'm going to venture a guess that there is some kind of communication breakdown between the SVG and the component's top-level template about what height it has. Here's an example of a component with a variable-height SVG: developer.salesforce.com/docs/component-library/tools/… You can install it in a Trailhead playground and and play with the height via the config property in App Builder (must be on the home tab). Commented May 14, 2020 at 0:10
  • 1
    @MatthewSouther Maybe this will help. This is essentially the component I am building. blockbuilder.org/mbostock/1093025 Unlike a static SVG, this one with the expanding/collapsing of the different elements changes the height differing amounts. So I essentially need a way of figuring out the height as I expand and collapse the different nodes.
    – Stephen
    Commented May 14, 2020 at 13:44

1 Answer 1

1
+50

This answer doesn't have much to do with Lightning App Builder -- it has more to do with D3 internals and understanding how to manage the value of the SVG's height attribute in LWC.

For a working LWC + D3 starting point, I played around with the D3 example in lwc-recipes to see if I could get the component to adjust its height automatically. I was able to make it work with the following steps:

  1. Add the @track decorator to svgHeight so changes to its value force the DOM to rerender.
  2. At the start of the initializeD3() method, declare const cmp = this;. This allows you to update the main class's svgHeight property inside any of the D3 callback functions via the cmp variable.
  3. Do some console logging to determine which callback functions are the last to execute when the user interacts with the SVG. In this example it was the ticked() function.
  4. Add the following lines at the end of ticked() or whatever function(s) you think are going to be most closely associated with the SVG resizing:
// Update the height of the SVG (remember, cmp was defined in step 2 above)
cmp.svgHeight = svg.node().getBBox().height;

// Vertically re-center the SVG (may or may not be needed in your tree grid example)
simulation.force('center', d3.forceCenter(width / 2, cmp.svgHeight / 2));

The alignment of the graphic elements inside the SVG wasn't perfect in this example, but could probably be improved by someone with a deeper knowledge of D3. Bottom line: the component continually adjusted its height on the Lightning Page as I was interacting with it.

If interested, you can refer to this StackOverflow thread for background on how I came up with the getBBox() solution.

6
  • I'm getting the error of [Cannot read property 'force' of undefined]. I made sure that the height and width within the simulation line has valid values which is does. I tried logging the result of the d3.forceCenter function, and it returns another function. Is there something that I'm missing? It seems so close, but I can't figure out where I'm going wrong. Any suggestions?
    – Stephen
    Commented May 14, 2020 at 20:35
  • 1
    Your Blockbuilder example doesn't have a simulation variable like the lwc-recipes example. Not sure that part is needed since a tree grid would probably stay vertically aligned at the top anyway. Have you tried removing that line and seeing what happens? Commented May 14, 2020 at 20:44
  • Yeah, realized that as well after posting. Removed it and it's working for the most part, except for some tweaks that I need to make. Thank you so much!
    – Stephen
    Commented May 14, 2020 at 20:47
  • one last question. The last function that I am trying to add the snippet of code to set the svg height is a toggle function. So as a result I am getting the expanded svg height when its collapsing and the collapsed svg height when its expanding. Any suggestions?
    – Stephen
    Commented May 14, 2020 at 21:38
  • 1
    I was able to get it to work. I needed to have the height determination function near the start of the function that was getting called last. I also needed to wrap it in a Math.max() to get the greatest either from the getBBox() or from the calculation determining the size of all the rectangle elements holding the different values (nodes.length * barHeight + margin.top + margin.bottom). Once I did that it worked perfectly! Thank you for the help!
    – Stephen
    Commented May 18, 2020 at 12:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .