old_contents: import { debounce } from 'lodash';
  import { calcEntropyInView } from "../util/tree/traversals";
  import * as types from "./types";
  
  export const updateEntropyVisibility = debounce((dispatch, getState) => {
    const { entropy, controls, tree } = getState();
    if (!tree.nodes || !tree.visibility || !entropy.geneMap || controls.mapAnimationPlayPauseButton !== "Play") {return;}
    const [data, maxYVal] = calcEntropyInView(tree.nodes, tree.visibility, controls.mutType, entropy.geneMap);
    dispatch({type: types.ENTROPY_DATA, data, maxYVal});
  }, 1000, { leading: true, trailing: true });
  
  export const changeMutType = (newMutType) => (dispatch, getState) => {
    dispatch({type: types.TOGGLE_MUT_TYPE, data: newMutType});
    updateEntropyVisibility(dispatch, getState);
  };
  
new_contents: import { debounce } from 'lodash';
  import { calcEntropyInView } from "../util/tree/traversals";
  import * as types from "./types";
  
  /* debounce works better than throttle, as it _won't_ update while events are still coming in (e.g. dragging the date slider) */
  export const updateEntropyVisibility = debounce((dispatch, getState) => {
    const { entropy, controls, tree } = getState();
    if (!tree.nodes || !tree.visibility || !entropy.geneMap || controls.mapAnimationPlayPauseButton !== "Play") {return;}
    const [data, maxYVal] = calcEntropyInView(tree.nodes, tree.visibility, controls.mutType, entropy.geneMap);
    dispatch({type: types.ENTROPY_DATA, data, maxYVal});
  }, 500, { leading: true, trailing: true });
  
  export const changeMutType = (newMutType) => (dispatch, getState) => {
    dispatch({type: types.TOGGLE_MUT_TYPE, data: newMutType});
    updateEntropyVisibility(dispatch, getState);
  };
  
subject: reduce debounce time