Embedding Vega-lite charts that have width value set to container, leads to null width until window is resized

When embedding cells from Vega-lite notebooks that have the width value set to “container”, the plot does not appear, unless the window is resized. Why is this bug happening ? I’m using the Runtime with JavaScript.

Can you try and make sure that the container already has a width when the plot is created? This might depend on many things (its element type, css)… it’s hard to tell without seeing the example.

The image below shows the container with a red border, demonstrating that it already has a non null width. As you can see the slider shows up, but the chart itself do not. However, when resizing the window, the chart shows up.

the html element of the canvas is the following:

< canvas width="0" height="1050" class="marks" style="width: 0px; height: 525px;" ></canvas>

A live example can be seen on this link:

https://observablehq.com/embed/@d6465476926575b4/vega-lite?cells=chart4

At first, it is not possible to see nothing. After changing the screen size, it is possible to see the chat.

Any help is appreciated!

1 Like

You could use Observable’s width macro to specify the Vega-Lite width. You could specify the height that way as well, if you like. Perhaps, something like

.width(0.9*width)
.height(0.5*width)

Note that, to include the legend, we need to specify .width(${k}*width), where k is a bit less than one. You probably need to tweak the value of k depending on where you want to embed it. I, also, suspect there’s a decrease in performance relative to Vega-Lite’s .width('container') but it seems to work reasonably well:

1 Like

another approach is to trigger a resize event just after returning the chart:

chart4 = vl
  .markPoint({ opacity: 0.5, filled: true })
  .data("data/penguins.json")
  .encode(
    vl
      .x()
      .fieldQ("Beak Depth (mm)")
      .scale({ domain: [10, 25] }),
    vl
      .y()
      .fieldQ("Beak Length (mm)")
      .scale({ domain: [30, 65] }),
    vl.size().fieldQ("Body Mass (g)"),
    vl.color().fieldN("Species")
  )
  .width("container")
  // .width(600)
  .height(500) // fix the height to keep stability over missing data
  .render()
  .then((chart) => {
    setTimeout(() => window.dispatchEvent(new Event("resize")), 1);
    return chart;
  })
2 Likes

I’m sure this is preferred!

I don’t know. It probably means it renders twice (once with a 0 width, then with the correct with).

Thanks, Fil and Mark ! Both solutions work. Yet I chose to trigger the window resize:

window.dispatchEvent(new Event(‘resize’))