getNextBatchFunction(
      shuffle, lookBack, delay, batchSize, step, minIndex, maxIndex, normalize,
      includeDateTime) {
    let startIndex = minIndex + lookBack;
    const lookBackSlices = Math.floor(lookBack / step);

    return {
      next: () => {
        const rowIndices = [];
        let done = false;  // Indicates whether the dataset has ended.
        if (shuffle) {
          // If `shuffle` is `true`, start from randomly chosen rows.
          const range = maxIndex - (minIndex + lookBack);
          for (let i = 0; i < batchSize; ++i) {
            const row = minIndex + lookBack + Math.floor(Math.random() * range);
            rowIndices.push(row);
          }
        } else {
          // If `shuffle` is `false`, the starting row indices will be sequential.
          let r = startIndex;
          for (; r < startIndex + batchSize && r < maxIndex; ++r) {
            rowIndices.push(r);
          }
          if (r >= maxIndex) {
            done = true;
          }
        }

        const numExamples = rowIndices.length;
        startIndex += numExamples;

        const featureLength =
            includeDateTime ? this.numColumns + 2 : this.numColumns;
        const samples = tf.buffer([numExamples, lookBackSlices, featureLength]);
        const targets = tf.buffer([numExamples, 1]);
        // Iterate over examples. Each example contains a number of rows.
        for (let j = 0; j < numExamples; ++j) {
          const rowIndex = rowIndices[j];
          let exampleRow = 0;
          // Iterate over rows in the example.
          for (let r = rowIndex - lookBack; r < rowIndex; r += step) {
            let exampleCol = 0;
            // Iterate over features in the row.
            for (let n = 0; n < featureLength; ++n) {
              let value;
              if (n < this.numColumns) {
                value = normalize ? this.normalizedData[r][n] : this.data[r][n];
              } else if (n === this.numColumns) {
                // Normalized day-of-the-year feature.
                value = this.normalizedDayOfYear[r];
              } else {
                // Normalized time-of-the-day feature.
                value = this.normalizedTimeOfDay[r];
              }
              samples.set(value, j, exampleRow, exampleCol++);
            }

            const value = normalize ?
                this.normalizedData[r + delay][this.tempCol] :
                this.data[r + delay][this.tempCol];
            targets.set(value, j, 0);
            exampleRow++;
          }
        }
        return {
          value: {xs: samples.toTensor(), ys: targets.toTensor()},
          done
        };
      }
    };
  }
Get a data iterator function.

@param {boolean} shuffle Whether the data is to be shuffled. If `false`,
  the examples generated by repeated calling of the returned iterator
  function will scan through range specified by `minIndex` and `maxIndex`
  (or the entire range of the CSV file if those are not specified) in a
  sequential fashion. If `true`, the examples generated by the returned
  iterator function will start from random rows.
@param {number} lookBack Number of look-back time steps. This is how many
  steps to look back back when making a prediction. Typical value: 10 days
  (i.e., 6 * 24 * 10 = 1440).
@param {number} delay Number of time steps from the last time point in the
  input features to the time of prediction. Typical value: 1 day (i.e.,
  6 * 24 = 144).
@param {number} batchSize Batch size.
@param {number} step Number of steps between consecutive time points in the
  input features. This is a downsampling factor for the input features.
  Typical value: 1 hour (i.e., 6).
@param {number} minIndex Optional minimum index to draw from the original
  data set. Together with `maxIndex`, this can be used to reserve a chunk
  of the original data for validation or evaluation.
@param {number} maxIndex Optional maximum index to draw from the original
  data set. Together with `minIndex`, this can be used to reserve a chunk
  of the original data for validation or evaluation.
@param {boolean} normalize Whether the iterator function will return
  normalized data.
@param {boolean} includeDateTime Include the date-time features, including
  normalized day-of-the-year and normalized time-of-the-day.
@return {Function} An iterator Function, which returns a batch of features
  and targets when invoked. The features and targets are arranged in a
  length-2 array, in the said order.
  The features are represented as a float32-type `tf.Tensor` of shape
    `[batchSize, Math.floor(lookBack / step), featureLength]`
  The targets are represented as a float32-type `tf.Tensor` of shape
    `[batchSize, 1]`.