redrawLayerIfNeeded = (curLayerIndex, i) => {
  // Determine the range for this layerview, and redraw the layer with
  // smaller range so all layers have the same range
  let rangePre = cnnLayerRanges[selectedScaleLevel][curLayerIndex - 1];
  let rangeCur = cnnLayerRanges[selectedScaleLevel][curLayerIndex];
  let range = Math.max(rangePre, rangeCur);

  if (rangePre > rangeCur) {
    // Redraw the current layer (selected node)
    svg.select(`g#layer-${curLayerIndex}-node-${i}`)
      .select('image.node-image')
      .each((d, g, i) => drawOutput(d, g, i, range));
    
    // Record the change so we will re-redraw the layer when user quits
    // the intermediate view
    needRedraw = [curLayerIndex, i];
    needRedrawStore.set(needRedraw);
    
  } else if (rangePre < rangeCur) {
    // Redraw the previous layer (whole layer)
    svg.select(`g#cnn-layer-group-${curLayerIndex - 1}`)
      .selectAll('image.node-image')
      .each((d, g, i) => drawOutput(d, g, i, range));

    // Record the change so we will re-redraw the layer when user quits
    // the intermediate view
    needRedraw = [curLayerIndex - 1, undefined];
    needRedrawStore.set(needRedraw);
  }

  // Compute the min, max value of all nodes in pre-layer and the selected
  // node of cur-layer
  let min = cnnLayerMinMax[curLayerIndex - 1].min,
    max = cnnLayerMinMax[curLayerIndex - 1].max;

  // Selected node
  let n = cnn[curLayerIndex][i];
  for (let r = 0; r < n.output.length; r++) {
    for (let c = 0; c < n.output[0].length; c++) {
      if (n.output[r][c] < min) { min = n.output[r][c]; }
      if (n.output[r][c] > max) { max = n.output[r][c]; }
    }
  }

  return {range: range, minMax: {min: min, max: max}};
}
Redraw the layer if needed (entering the intermediate view to make sure
all layers have the same color scale)
@param {number} curLayerIndex Index of the selected layer
@param {number} i Index of the selected node