code: function updateComponents(selection, state) {
    const nodesToRender = state.nodesToRender();
    const [nodesSelected, nodesNotSelected] = _.partition(
      nodesToRender, d => d.selected);
    const numNodes = nodesToRender.length;
    if (state.enableFocusedView) {
      state.focusedView = numNodes < state.focusedViewThreshold;
    }
    if (state.enableOverlookView) {
      state.overlookView = numNodes > state.overlookViewThreshold;
    }
    const edgesToRender = state.overlookView ? [] : state.edgesToRender();
    const [edgesSelected, edgesNotSelected] = _.partition(
        edgesToRender, d => d.selected);
    selection.select('.node-layer')
        .call(component.updateNodes, nodesNotSelected, state.focusedView)
      .selectAll('.node .node-symbol')
        .attr('stroke-opacity', 0);
    selection.select('.edge-layer')
        .call(component.updateEdges, edgesNotSelected);
    selection.select('.selected-nodes')
        .call(component.updateNodes, nodesSelected, state.focusedView)
      .selectAll('.node .node-symbol')
        .attr('stroke', 'red')
        .attr('stroke-width', 10)
        .attr('stroke-opacity', 0.5);
    selection.select('.selected-edges')
        .call(component.updateEdges, edgesSelected);
    selection.call(component.updateAttrs, state);
  }
docs: TODO: refactor Custom updater for interactive mode