]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Category scale supports min / max
authorEvert Timberg <evert.timberg+github@gmail.com>
Sun, 3 Apr 2016 03:05:48 +0000 (23:05 -0400)
committerEvert Timberg <evert.timberg+github@gmail.com>
Sun, 3 Apr 2016 03:05:48 +0000 (23:05 -0400)
src/scales/scale.category.js
test/scale.category.tests.js

index 14b1d74bbb9df5b7711082098d6d7a0fe7cf5bc0..44135ebdb06e440e8582925a5b5dac4f50696a39 100644 (file)
@@ -10,7 +10,24 @@ module.exports = function(Chart) {
 
        var DatasetScale = Chart.Scale.extend({
                buildTicks: function(index) {
-                       this.ticks = this.chart.data.labels;
+                       this.startIndex = 0;
+                       this.endIndex = this.chart.data.labels.length;
+                       var findIndex;
+
+                       if (this.options.ticks.min !== undefined) {
+                               // user specified min value
+                               findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.min)
+                               this.startIndex = findIndex !== -1 ? findIndex : this.startIndex;
+                       }
+
+                       if (this.options.ticks.max !== undefined) {
+                               // user specified max value
+                               findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.max);
+                               this.endIndex = findIndex !== -1 ? findIndex : this.endIndex;
+                       }
+
+                       // If we are viewing some subset of labels, slice the original array
+                       this.ticks = (this.startIndex === 0 && this.endIndex === this.chart.data.labels.length) ? this.chart.data.labels : this.chart.data.labels.slice(this.startIndex, this.endIndex + 1);
                },
 
                getLabelForIndex: function(index, datasetIndex) {
@@ -19,10 +36,13 @@ module.exports = function(Chart) {
 
                // Used to get data value locations.  Value can either be an index or a numerical value
                getPixelForValue: function(value, index, datasetIndex, includeOffset) {
+                       // 1 is added because we need the length but we have the indexes
+                       var offsetAmt = Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
+
                        if (this.isHorizontal()) {
                                var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
-                               var valueWidth = innerWidth / Math.max((this.chart.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-                               var widthOffset = (valueWidth * index) + this.paddingLeft;
+                               var valueWidth = innerWidth / offsetAmt;
+                               var widthOffset = (valueWidth * (index - this.startIndex)) + this.paddingLeft;
 
                                if (this.options.gridLines.offsetGridLines && includeOffset) {
                                        widthOffset += (valueWidth / 2);
@@ -31,8 +51,8 @@ module.exports = function(Chart) {
                                return this.left + Math.round(widthOffset);
                        } else {
                                var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
-                               var valueHeight = innerHeight / Math.max((this.chart.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
-                               var heightOffset = (valueHeight * index) + this.paddingTop;
+                               var valueHeight = innerHeight / offsetAmt;
+                               var heightOffset = (valueHeight * (index - this.startIndex)) + this.paddingTop;
 
                                if (this.options.gridLines.offsetGridLines && includeOffset) {
                                        heightOffset += (valueHeight / 2);
@@ -40,6 +60,9 @@ module.exports = function(Chart) {
 
                                return this.top + Math.round(heightOffset);
                        }
+               },
+               getPixelForTick: function(index, includeOffset) {
+                       return this.getPixelForValue(this.ticks[index], index + this.startIndex, null, includeOffset);
                }
        });
 
index dd8e4d7622025319816ca539889a62bf1e7ca946..c59504a8b7d719432f415fc03812f404cf680290 100644 (file)
@@ -156,6 +156,68 @@ describe('Category scale tests', function() {
                expect(scale.getPixelForValue(0, 4, 0, true)).toBe(557);
        });
 
+       it ('Should get the correct pixel for a value when horizontal and zoomed', function() {
+               var scaleID = 'myScale';
+
+               var mockData = {
+                       datasets: [{
+                               yAxisID: scaleID,
+                               data: [10, 5, 0, 25, 78]
+                       }],
+                       labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
+               };
+
+               var mockContext = window.createMockContext();
+               var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
+               config.gridLines.offsetGridLines = true;
+               config.ticks.min = "tick2";
+               config.ticks.max = "tick4";
+
+               var Constructor = Chart.scaleService.getScaleConstructor('category');
+               var scale = new Constructor({
+                       ctx: mockContext,
+                       options: config,
+                       chart: {
+                               data: mockData
+                       },
+                       id: scaleID
+               });
+
+               var minSize = scale.update(600, 100);
+
+               expect(scale.width).toBe(600);
+               expect(scale.height).toBe(28);
+               expect(scale.paddingTop).toBe(0);
+               expect(scale.paddingBottom).toBe(0);
+               expect(scale.paddingLeft).toBe(28);
+               expect(scale.paddingRight).toBe(28);
+               expect(scale.labelRotation).toBe(0);
+
+               expect(minSize).toEqual({
+                       width: 600,
+                       height: 28,
+               });
+
+               scale.left = 5;
+               scale.top = 5;
+               scale.right = 605;
+               scale.bottom = 33;
+
+               expect(scale.getPixelForValue(0, 1, 0, false)).toBe(33);
+               expect(scale.getPixelForValue(0, 1, 0, true)).toBe(124);
+
+               expect(scale.getPixelForValue(0, 3, 0, false)).toBe(396);
+               expect(scale.getPixelForValue(0, 3, 0, true)).toBe(486);
+
+               config.gridLines.offsetGridLines = false;
+
+               expect(scale.getPixelForValue(0, 1, 0, false)).toBe(33);
+               expect(scale.getPixelForValue(0, 1, 0, true)).toBe(33);
+
+               expect(scale.getPixelForValue(0, 3, 0, false)).toBe(577);
+               expect(scale.getPixelForValue(0, 3, 0, true)).toBe(577);
+       });
+
        it ('should get the correct pixel for a value when vertical', function() {
                var scaleID = 'myScale';
 
@@ -215,4 +277,67 @@ describe('Category scale tests', function() {
                expect(scale.getPixelForValue(0, 4, 0, false)).toBe(199);
                expect(scale.getPixelForValue(0, 4, 0, true)).toBe(199);
        });
+
+       it ('should get the correct pixel for a value when vertical and zoomed', function() {
+               var scaleID = 'myScale';
+
+               var mockData = {
+                       datasets: [{
+                               yAxisID: scaleID,
+                               data: [10, 5, 0, 25, 78]
+                       }],
+                       labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
+               };
+
+               var mockContext = window.createMockContext();
+               var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
+               config.gridLines.offsetGridLines = true;
+               config.ticks.min = "tick2";
+               config.ticks.max = "tick4";
+               config.position = "left";
+
+               var Constructor = Chart.scaleService.getScaleConstructor('category');
+               var scale = new Constructor({
+                       ctx: mockContext,
+                       options: config,
+                       chart: {
+                               data: mockData
+                       },
+                       id: scaleID
+               });
+
+               var minSize = scale.update(100, 200);
+
+               expect(scale.width).toBe(70);
+               expect(scale.height).toBe(200);
+               expect(scale.paddingTop).toBe(6);
+               expect(scale.paddingBottom).toBe(6);
+               expect(scale.paddingLeft).toBe(0);
+               expect(scale.paddingRight).toBe(0);
+               expect(scale.labelRotation).toBe(0);
+
+               expect(minSize).toEqual({
+                       width: 70,
+                       height: 200,
+               });
+
+               scale.left = 5;
+               scale.top = 5;
+               scale.right = 75;
+               scale.bottom = 205;
+
+               expect(scale.getPixelForValue(0, 1, 0, false)).toBe(11);
+               expect(scale.getPixelForValue(0, 1, 0, true)).toBe(42);
+
+               expect(scale.getPixelForValue(0, 3, 0, false)).toBe(136);
+               expect(scale.getPixelForValue(0, 3, 0, true)).toBe(168);
+
+               config.gridLines.offsetGridLines = false;
+
+               expect(scale.getPixelForValue(0, 1, 0, false)).toBe(11);
+               expect(scale.getPixelForValue(0, 1, 0, true)).toBe(11);
+
+               expect(scale.getPixelForValue(0, 3, 0, false)).toBe(199);
+               expect(scale.getPixelForValue(0, 3, 0, true)).toBe(199);
+       });
 });
\ No newline at end of file