]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Time scale will now scale units. For example, it will try 1hr then 2hrs then 3 hrs...
authoretimberg <evert.timberg@gmail.com>
Wed, 2 Dec 2015 01:02:44 +0000 (20:02 -0500)
committeretimberg <evert.timberg@gmail.com>
Wed, 2 Dec 2015 01:02:44 +0000 (20:02 -0500)
src/scales/scale.time.js

index ad8fee7d4ffbbbba43e14f43374162ef53778b3b..2f562bb7912a62929fb7b298428ac10206417f66 100644 (file)
 
        var time = {
                units: [
-                       'millisecond',
-                       'second',
-                       'minute',
-                       'hour',
-                       'day',
-                       'week',
-                       'month',
-                       'quarter',
-                       'year',
+                       {
+                               name: 'millisecond',
+                               steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
+                       }, {
+                               name: 'second',
+                               steps: [1, 2, 5, 10, 30]
+                       }, {
+                               name: 'minute',
+                               steps: [1, 2, 5, 10, 30]
+                       }, {
+                               name: 'hour',
+                               steps: [1, 2, 3, 6, 12]
+                       }, {
+                               name: 'day',
+                               steps: [1, 2, 5]
+                       }, {
+                               name: 'week',
+                               maxStep: 4
+                       }, {
+                               name: 'month',
+                               maxStep: 3
+                       }, {
+                               name: 'quarter',
+                               maxStep: 4,
+                       }, {
+                               name: 'year',
+                               maxStep: false
+                       },
                ],
        };
 
                        } else {
                                // Determine the smallest needed unit of the time
                                var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
-                               var labelCapacity = innerWidth / this.options.ticks.fontSize + 4;
+                               var labelCapacity = innerWidth / (this.options.ticks.fontSize + 10);
                                var buffer = this.options.time.round ? 0 : 2;
 
                                // Start as small as possible
                                this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true) + buffer);
                                this.displayFormat = this.options.time.displayFormats[this.tickUnit];
 
-                               // Work our way up to comfort
-                               helpers.each(time.units, function(format) {
-                                       if (this.tickRange <= labelCapacity) {
-                                               return;
-                                       }
-                                       this.tickUnit = format;
-                                       this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit) + buffer);
-                                       this.displayFormat = this.options.time.displayFormats[format];
+                               // How much we scale the unit by, ie 2 means 2x unit per step 
+                               this.unitScale = 1;
+                               var unitDefinitionIndex = 0;
+                               var unitDefinition = time.units[unitDefinitionIndex];
+
+                               // While we aren't ideal and we don't have units left 
+                               while (unitDefinitionIndex < time.units.length) {
+                                       // Can we scale this unit. If `false` we can scale infinitely
+                                       //var canScaleUnit = ;
+                                       this.unitScale = 1;
+
+                                       if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.tickRange / labelCapacity) < helpers.max(unitDefinition.steps)) {
+                                               // Use one of the prefedined steps
+                                               for (var idx = 1; idx < unitDefinition.steps.length; ++idx) {
+                                                       if (unitDefinition.steps[idx] > Math.ceil(this.tickRange / labelCapacity)) {
+                                                               this.unitScale = unitDefinition.steps[idx - 1];
+                                                               break;
+                                                       }
+                                               }
 
-                               }, this);
+                                               break;
+                                       } else if ((unitDefinition.maxStep === false) || (Math.ceil(this.tickRange / labelCapacity) < unitDefinition.maxStep)) {
+                                               // We have a max step. Scale this unit
+                                               this.unitScale = Math.ceil(this.tickRange / labelCapacity);
+                                               break;
+                                       } else {
+                                               // Move to the next unit up
+                                               ++unitDefinitionIndex;
+                                               unitDefinition = time.units[unitDefinitionIndex];
+                                               
+                                               this.tickUnit = unitDefinition.name;
+                                               this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit) + buffer);
+                                               this.displayFormat = this.options.time.displayFormats[unitDefinition.name];
+                                       }
+                               }
                        }
 
                        this.firstTick.startOf(this.tickUnit);
 
                        // For every unit in between the first and last moment, create a moment and add it to the ticks tick
                        for (var i = 0; i <= this.tickRange; ++i) {
-                               this.ticks.push(this.firstTick.clone().add(i, this.tickUnit));
+                               if (i % this.unitScale === 0) {
+                                       this.ticks.push(this.firstTick.clone().add(i, this.tickUnit));
+                               } else if (i === this.tickRange) {
+                                       // Expand out the last one if not an exact multiple
+                                       this.tickRange = Math.ceil(this.tickRange / this.unitScale) * this.unitScale;
+                                       this.ticks.push(this.firstTick.clone().add(this.tickRange, this.tickUnit));
+                                       this.lastTick = this.ticks[this.ticks.length - 1].clone();
+                                       break;
+                               }
                        }
                },
                // Get tooltip label