Responsive views - abudaan/vega-multi-view GitHub Wiki

If you want your view to change its dimensions as soon as the container element or browser window is resized, you can define it in the spec itself like this:

signals:
- name: width
  value: "containerSize()[0] - padding.left - padding.right"
  # this update expression does not work in Chrome, see below
  update: "containerSize()[0] - padding.left - padding.right"
  on:
    - events:
        source: window
        type: resize
      update: "containerSize()[0] - padding.left - padding.right"
- name: height
  value: "containerSize()[1] - padding.top - padding.bottom"
  # this update expression does not work in Chrome, see below
  update: "containerSize()[1] - padding.top - padding.bottom"
  on:
    - events:
        source: window
        type: resize
      update: "containerSize()[1] - padding.top - padding.bottom"

In the example above the view responds to dimension changes of the container element; in case you want your view to respond to changes of the browser window, use windowSize() instead of containerSize().

This method works perfectly in Firefox but unfortunately for Chrome this isn't a completely reliable method; sometimes during the initial rendering the view gets no dimensions at all and you end up seeing an empty space. Therefor vmv forces the view to the right dimensions by injecting the initial width and height of the container element into the spec before the spec gets parsed into a view. This only happens if no value has been set in the spec for width and/or height:

  • if you omit both, the width and height will be set to the width and height of the containing element
  • if you omit width, only the width will be set and height will remain as defined in the spec
  • if you omit height, only the height will be set and width will remain as defined in the spec

Another issue with Chrome is that if you set a value for update like in the snippet above, nothing will be rendered during the initial rendering. If you want your view to be rendered with the same dimensions as the container element (minus eventual padding) the most reliable solution is to leave both width and height empty (or set it to value 0), and only define update expressions inside the event handlers:

# most reliable cross-browser solution

autosize: none # other values can yield weird results
width: 0 # don't define width or set it to 0
height: 0 # don't define height or set it to 0
signals:
- name: width
  on:
    - events:
        source: window
        type: resize
      update: "containerSize()[0] - padding.left - padding.right"
- name: height
  on:
    - events:
        source: window
        type: resize
      update: "containerSize()[1] - padding.top - padding.bottom"