133 lines
		
	
	
	
		
			3.5 KiB
			
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
	
		
			3.5 KiB
			
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Derived from Chromium WebRTC Internals Dashboard - see Acknowledgements for full license details
 | 
						|
 | 
						|
// The maximum number of data points buffered for each stats. Old data points
 | 
						|
// will be shifted out when the buffer is full.
 | 
						|
export const MAX_STATS_DATA_POINT_BUFFER_SIZE = 1000;
 | 
						|
 | 
						|
/**
 | 
						|
 * A TimelineDataSeries collects an ordered series of (time, value) pairs,
 | 
						|
 * and converts them to graph points.  It also keeps track of its color and
 | 
						|
 * current visibility state.
 | 
						|
 * It keeps MAX_STATS_DATA_POINT_BUFFER_SIZE data points at most. Old data
 | 
						|
 * points will be dropped when it reaches this size.
 | 
						|
 */
 | 
						|
export class TimelineDataSeries {
 | 
						|
  constructor(statsType) {
 | 
						|
    // List of DataPoints in chronological order.
 | 
						|
    this.dataPoints_ = [];
 | 
						|
 | 
						|
    // Default color.  Should always be overridden prior to display.
 | 
						|
    this.color_ = 'red';
 | 
						|
    // Whether or not the data series should be drawn.
 | 
						|
    this.isVisible_ = true;
 | 
						|
 | 
						|
    this.cacheStartTime_ = null;
 | 
						|
    this.cacheStepSize_ = 0;
 | 
						|
    this.cacheValues_ = [];
 | 
						|
    this.statsType_ = statsType;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * @override
 | 
						|
   */
 | 
						|
  toJSON() {
 | 
						|
    if (this.dataPoints_.length < 1) {
 | 
						|
      return {};
 | 
						|
    }
 | 
						|
 | 
						|
    const values = [];
 | 
						|
    for (let i = 0; i < this.dataPoints_.length; ++i) {
 | 
						|
      values.push(this.dataPoints_[i].value);
 | 
						|
    }
 | 
						|
    return {
 | 
						|
      startTime: this.dataPoints_[0].time,
 | 
						|
      endTime: this.dataPoints_[this.dataPoints_.length - 1].time,
 | 
						|
      statsType: this.statsType_,
 | 
						|
      values: JSON.stringify(values),
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Adds a DataPoint to |this| with the specified time and value.
 | 
						|
   * DataPoints are assumed to be received in chronological order.
 | 
						|
   */
 | 
						|
  addPoint(timeTicks, value) {
 | 
						|
    const time = new Date(timeTicks);
 | 
						|
    this.dataPoints_.push(new DataPoint(time, value));
 | 
						|
 | 
						|
    if (this.dataPoints_.length > MAX_STATS_DATA_POINT_BUFFER_SIZE) {
 | 
						|
      this.dataPoints_.shift();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  isVisible() {
 | 
						|
    return this.isVisible_;
 | 
						|
  }
 | 
						|
 | 
						|
  show(isVisible) {
 | 
						|
    this.isVisible_ = isVisible;
 | 
						|
  }
 | 
						|
 | 
						|
  getColor() {
 | 
						|
    return this.color_;
 | 
						|
  }
 | 
						|
 | 
						|
  setColor(color) {
 | 
						|
    this.color_ = color;
 | 
						|
  }
 | 
						|
 | 
						|
  getCount() {
 | 
						|
    return this.dataPoints_.length;
 | 
						|
  }
 | 
						|
  /**
 | 
						|
   * Returns a list containing the values of the data series at |count|
 | 
						|
   * points, starting at |startTime|, and |stepSize| milliseconds apart.
 | 
						|
   * Caches values, so showing/hiding individual data series is fast.
 | 
						|
   */
 | 
						|
  getValues(startTime, stepSize, count) {
 | 
						|
    // Use cached values, if we can.
 | 
						|
    if (this.cacheStartTime_ === startTime &&
 | 
						|
        this.cacheStepSize_ === stepSize &&
 | 
						|
        this.cacheValues_.length === count) {
 | 
						|
      return this.cacheValues_;
 | 
						|
    }
 | 
						|
 | 
						|
    // Do all the work.
 | 
						|
    this.cacheValues_ = this.getValuesInternal_(startTime, stepSize, count);
 | 
						|
    this.cacheStartTime_ = startTime;
 | 
						|
    this.cacheStepSize_ = stepSize;
 | 
						|
 | 
						|
    return this.cacheValues_;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the cached |values| in the specified time period.
 | 
						|
   */
 | 
						|
  getValuesInternal_(startTime, stepSize, count) {
 | 
						|
    const values = [];
 | 
						|
    let nextPoint = 0;
 | 
						|
    let currentValue = 0;
 | 
						|
    let time = startTime;
 | 
						|
    for (let i = 0; i < count; ++i) {
 | 
						|
      while (nextPoint < this.dataPoints_.length &&
 | 
						|
             this.dataPoints_[nextPoint].time < time) {
 | 
						|
        currentValue = this.dataPoints_[nextPoint].value;
 | 
						|
        ++nextPoint;
 | 
						|
      }
 | 
						|
      values[i] = currentValue;
 | 
						|
      time += stepSize;
 | 
						|
    }
 | 
						|
    return values;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * A single point in a data series.  Each point has a time, in the form of
 | 
						|
 * milliseconds since the Unix epoch, and a numeric value.
 | 
						|
 */
 | 
						|
class DataPoint {
 | 
						|
  constructor(time, value) {
 | 
						|
    this.time = time;
 | 
						|
    this.value = value;
 | 
						|
  }
 | 
						|
}
 |