Home | History | Annotate | Download | only in media
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 /**
      6  * A TimelineDataSeries collects an ordered series of (time, value) pairs,
      7  * and converts them to graph points.  It also keeps track of its color and
      8  * current visibility state.
      9  * It keeps MAX_STATS_DATA_POINT_BUFFER_SIZE data points at most. Old data
     10  * points will be dropped when it reaches this size.
     11  */
     12 var TimelineDataSeries = (function() {
     13   'use strict';
     14 
     15   /**
     16    * @constructor
     17    */
     18   function TimelineDataSeries() {
     19     // List of DataPoints in chronological order.
     20     this.dataPoints_ = [];
     21 
     22     // Default color.  Should always be overridden prior to display.
     23     this.color_ = 'red';
     24     // Whether or not the data series should be drawn.
     25     this.isVisible_ = true;
     26 
     27     this.cacheStartTime_ = null;
     28     this.cacheStepSize_ = 0;
     29     this.cacheValues_ = [];
     30   }
     31 
     32   TimelineDataSeries.prototype = {
     33     /**
     34      * @override
     35      */
     36     toJSON: function() {
     37       if (this.dataPoints_.length < 1)
     38         return {};
     39 
     40       var values = [];
     41       for (var i = 0; i < this.dataPoints_.length; ++i) {
     42         values.push(this.dataPoints_[i].value);
     43       }
     44       return {
     45         startTime: this.dataPoints_[0].time,
     46         endTime: this.dataPoints_[this.dataPoints_.length - 1].time,
     47         values: JSON.stringify(values),
     48       };
     49     },
     50 
     51     /**
     52      * Adds a DataPoint to |this| with the specified time and value.
     53      * DataPoints are assumed to be received in chronological order.
     54      */
     55     addPoint: function(timeTicks, value) {
     56       var time = new Date(timeTicks);
     57       this.dataPoints_.push(new DataPoint(time, value));
     58 
     59       if (this.dataPoints_.length > MAX_STATS_DATA_POINT_BUFFER_SIZE)
     60         this.dataPoints_.shift();
     61     },
     62 
     63     isVisible: function() {
     64       return this.isVisible_;
     65     },
     66 
     67     show: function(isVisible) {
     68       this.isVisible_ = isVisible;
     69     },
     70 
     71     getColor: function() {
     72       return this.color_;
     73     },
     74 
     75     setColor: function(color) {
     76       this.color_ = color;
     77     },
     78 
     79     /**
     80      * Returns a list containing the values of the data series at |count|
     81      * points, starting at |startTime|, and |stepSize| milliseconds apart.
     82      * Caches values, so showing/hiding individual data series is fast.
     83      */
     84     getValues: function(startTime, stepSize, count) {
     85       // Use cached values, if we can.
     86       if (this.cacheStartTime_ == startTime &&
     87           this.cacheStepSize_ == stepSize &&
     88           this.cacheValues_.length == count) {
     89         return this.cacheValues_;
     90       }
     91 
     92       // Do all the work.
     93       this.cacheValues_ = this.getValuesInternal_(startTime, stepSize, count);
     94       this.cacheStartTime_ = startTime;
     95       this.cacheStepSize_ = stepSize;
     96 
     97       return this.cacheValues_;
     98     },
     99 
    100     /**
    101      * Returns the cached |values| in the specified time period.
    102      */
    103     getValuesInternal_: function(startTime, stepSize, count) {
    104       var values = [];
    105       var nextPoint = 0;
    106       var currentValue = 0;
    107       var time = startTime;
    108       for (var i = 0; i < count; ++i) {
    109         while (nextPoint < this.dataPoints_.length &&
    110                this.dataPoints_[nextPoint].time < time) {
    111           currentValue = this.dataPoints_[nextPoint].value;
    112           ++nextPoint;
    113         }
    114         values[i] = currentValue;
    115         time += stepSize;
    116       }
    117       return values;
    118     }
    119   };
    120 
    121   /**
    122    * A single point in a data series.  Each point has a time, in the form of
    123    * milliseconds since the Unix epoch, and a numeric value.
    124    * @constructor
    125    */
    126   function DataPoint(time, value) {
    127     this.time = time;
    128     this.value = value;
    129   }
    130 
    131   return TimelineDataSeries;
    132 })();
    133