]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Modify layout service to be able to place horizontal boxes as either full width or...
authorEvert Timberg <evert.timberg@gmail.com>
Sat, 21 Nov 2015 15:51:32 +0000 (10:51 -0500)
committerEvert Timberg <evert.timberg@gmail.com>
Sat, 21 Nov 2015 15:51:32 +0000 (10:51 -0500)
Updated unit tests to use correct 'boxes' property of chart instance. Tests did not require numerical updates!

Added a test to cover placing a full width box.

src/core/core.layoutService.js
src/core/core.legend.js
src/core/core.scale.js
src/scales/scale.category.js
src/scales/scale.linear.js
test/core.layoutService.tests.js

index 982c42d8a98541d92ca4ba81926ab1f2fb075b4c..fed4d0b9b3bf12ae6d42f8247e7ee94d3ee19286 100644 (file)
                                var isHorizontal = box.isHorizontal();
 
                                if (isHorizontal) {
-                                       minSize = box.update(chartWidth, horizontalBoxHeight);
+                                       minSize = box.update(box.options.fullWidth ? chartWidth : chartAreaWidth, horizontalBoxHeight);
                                } else {
                                        minSize = box.update(verticalBoxWidth, chartAreaHeight);
                                }
+
                                minBoxSizes.push({
                                        horizontal: isHorizontal,
                                        minSize: minSize,
                        // Set the Left and Right margins for the horizontal boxes
                        helpers.each(topBoxes.concat(bottomBoxes), fitBox);
 
+                       // Function to fit a box
                        function fitBox(box) {
-
                                var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
                                        return minBoxSize.box === box;
                                });
 
-                               if (box.isHorizontal() && minBoxSize) {
-                                       var scaleMargin = {
-                                               left: totalLeftBoxesWidth,
-                                               right: totalRightBoxesWidth,
-                                               top: 0,
-                                               bottom: 0,
-                                       };
-
-                                       box.update(chartWidth, minBoxSize.minSize.height, scaleMargin);
-                               } else {
-                                       box.update(minBoxSize.minSize.width, maxChartAreaHeight);
+                               if (minBoxSize) {
+                                       if (box.isHorizontal()) {
+                                               var scaleMargin = {
+                                                       left: totalLeftBoxesWidth,
+                                                       right: totalRightBoxesWidth,
+                                                       top: 0,
+                                                       bottom: 0,
+                                               };
+
+                                               box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, minBoxSize.minSize.height, scaleMargin);
+                                       } else {
+                                               box.update(minBoxSize.minSize.width, maxChartAreaHeight);
+                                       }
                                }
                        }
 
 
                        function placeBox(box) {
                                if (box.isHorizontal()) {
-                                       box.left = xPadding;
-                                       box.right = width - xPadding;
+                                       box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;
+                                       box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;
                                        box.top = top;
                                        box.bottom = top + box.height;
 
index dfc06a77d5730906a795d5316e3480688f880a0a..b8bf967345f9ba14ca82d1b1585998ecf7068a5b 100644 (file)
@@ -9,6 +9,7 @@
 
                display: true,
                position: 'top',
+               fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
                onClick: false, // a callback will override the default behavior of toggling the datasets
 
                title: {
index 9bab29c2ae3dfb3caa4580ffe22fe61a9d8c7d2c..f60d8f09c0e9a41b30e605f809a12a7bc13ab702 100644 (file)
 
                        // Width
                        if (this.isHorizontal()) {
-                               // subtract the margins to line up with the chartArea
-                               this.minSize.width = this.maxWidth - this.margins.left - this.margins.right;
+                               // subtract the margins to line up with the chartArea if we are a full width scale
+                               this.minSize.width = this.isFullWidth() ? this.maxWidth - this.margins.left - this.margins.right : this.maxWidth;
                        } else {
                                this.minSize.width = this.options.gridLines.show && this.options.display ? 10 : 0;
                        }
                isHorizontal: function() {
                        return this.options.position == "top" || this.options.position == "bottom";
                },
+               isFullWidth: function() {
+                       return (this.options.fullWidth);
+               },
 
                // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
                getRightValue: function getRightValue(rawValue) {
                                if (includeOffset) {
                                        pixel += tickWidth / 2;
                                }
-                               return this.left + this.margins.left + Math.round(pixel);
+
+                               var finalVal = this.left + Math.round(pixel);
+                               finalVal += this.isFullWidth() ? this.margins.left : 0;
+                               return finalVal;
                        } else {
                                var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
                                return this.top + (index * (innerHeight / (this.ticks.length - 1)));
                                var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
                                var valueOffset = (innerWidth * decimal) + this.paddingLeft;
 
-                               return this.left + this.margins.left + Math.round(valueOffset);
+                               var finalVal = this.left + Math.round(valueOffset);
+                               finalVal += this.isFullWidth() ? this.margins.left : 0;
+                               return finalVal;
                        } else {
                                return this.top + (decimal * this.height);
                        }
index c0fabe4070abd451fdd160091e85820e8933cd47..8d8f709f0ff476d90f135f606e374b6f0bf380f4 100644 (file)
@@ -30,7 +30,7 @@
                     widthOffset += (valueWidth / 2);
                 }
 
-                return this.left + this.margins.left + Math.round(widthOffset);
+                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);
index 631d9c12928eca66fc319849dc4eae8fe5053387..2cc8254e60f0381916d66f252a748d6f4abfc140 100644 (file)
                        if (this.isHorizontal()) {
 
                                var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
-                               pixel = this.left + this.margins.left + (innerWidth / range * (rightValue - this.start));
+                               pixel = this.left + (innerWidth / range * (rightValue - this.start));
                                return Math.round(pixel + this.paddingLeft);
                        } else {
                                var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
index 8210bc5254829d6a939b8763d7aef2e48f8cb95c..355986282ede46eac97d21c11817d96f3fe17af4 100644 (file)
@@ -2,7 +2,7 @@
 describe('Test the layout service', function() {
        it('should fit a simple chart with 2 scales', function() {
                var chartInstance = {
-                       scales: [],
+                       boxes: [],
                };
 
                var xScaleID = 'xScale';
@@ -38,8 +38,8 @@ describe('Test the layout service', function() {
                        id: yScaleID
                });
 
-               chartInstance.scales.push(xScale);
-               chartInstance.scales.push(yScale);
+               chartInstance.boxes.push(xScale);
+               chartInstance.boxes.push(yScale);
 
                var canvasWidth = 250;
                var canvasHeight = 150;
@@ -68,7 +68,7 @@ describe('Test the layout service', function() {
 
        it('should fit scales that are in the top and right positions', function() {
                var chartInstance = {
-                       scales: [],
+                       boxes: [],
                };
 
                var xScaleID = 'xScale';
@@ -106,8 +106,8 @@ describe('Test the layout service', function() {
                        id: yScaleID
                });
 
-               chartInstance.scales.push(xScale);
-               chartInstance.scales.push(yScale);
+               chartInstance.boxes.push(xScale);
+               chartInstance.boxes.push(yScale);
 
                var canvasWidth = 250;
                var canvasHeight = 150;
@@ -136,7 +136,7 @@ describe('Test the layout service', function() {
 
        it('should fit multiple axes in the same position', function() {
                var chartInstance = {
-                       scales: [],
+                       boxes: [],
                };
 
                var xScaleID = 'xScale';
@@ -184,9 +184,9 @@ describe('Test the layout service', function() {
                        id: yScaleID2
                });
 
-               chartInstance.scales.push(xScale);
-               chartInstance.scales.push(yScale1);
-               chartInstance.scales.push(yScale2);
+               chartInstance.boxes.push(xScale);
+               chartInstance.boxes.push(yScale1);
+               chartInstance.boxes.push(yScale2);
 
                var canvasWidth = 250;
                var canvasHeight = 150;
@@ -223,7 +223,7 @@ describe('Test the layout service', function() {
        // due to the lack of label rotation
        it('should fit scales that overlap the chart area', function() {
                var chartInstance = {
-                       scales: [],
+                       boxes: [],
                };
 
                var scaleID = 'scaleID';
@@ -250,7 +250,7 @@ describe('Test the layout service', function() {
                        id: scaleID
                });
 
-               chartInstance.scales.push(scale);
+               chartInstance.boxes.push(scale);
 
                var canvasWidth = 300;
                var canvasHeight = 350;
@@ -270,4 +270,91 @@ describe('Test the layout service', function() {
                expect(scale.width).toBe(290);
                expect(scale.height).toBe(340)
        });
+
+       it ('should fix a full width box correctly', function() {
+               var chartInstance = {
+                       boxes: [],
+               };
+
+               var xScaleID1= 'xScale1';
+               var xScaleID2 = 'xScale2';
+               var yScaleID = 'yScale2';
+
+               var mockData = {
+                       datasets: [{
+                               xAxisID: xScaleID1,
+                               data: [10, 5, 0, 25, 78, -10]
+                       }, {
+                               xAxisID: xScaleID2,
+                               data: [-19, -20, 0, -99, -50, 0]
+                       }],
+                       labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
+               };
+               var mockContext = window.createMockContext();
+
+               var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
+               var XConstructor = Chart.scaleService.getScaleConstructor('category');
+               var xScale1 = new XConstructor({
+                       ctx: mockContext,
+                       options: xScaleConfig,
+                       chart: {
+                               data: mockData
+                       },
+                       id: xScaleID1
+               });
+               var xScale2 = new XConstructor({
+                       ctx: mockContext,
+                       options: Chart.helpers.extend(Chart.helpers.clone(xScaleConfig), {
+                               position: 'top',
+                               fullWidth: true
+                       }),
+                       chart: {
+                               data: mockData,
+                       },
+                       id: xScaleID2
+               });
+
+               var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
+               var YConstructor = Chart.scaleService.getScaleConstructor('linear');
+               var yScale = new YConstructor({
+                       ctx: mockContext,
+                       options: yScaleConfig,
+                       chart: {
+                               data: mockData
+                       },
+                       id: yScaleID
+               });
+
+               chartInstance.boxes.push(xScale1);
+               chartInstance.boxes.push(xScale2);
+               chartInstance.boxes.push(yScale);
+
+               var canvasWidth = 250;
+               var canvasHeight = 150;
+               Chart.layoutService.update(chartInstance, canvasWidth, canvasHeight);
+
+               expect(chartInstance.chartArea).toEqual({
+                       left: 45,
+                       right: 245,
+                       top: 45,
+                       bottom: 105,
+               });
+
+               // Are xScales at the right spot
+               expect(xScale1.left).toBe(45);
+               expect(xScale1.right).toBe(245);
+               expect(xScale1.top).toBe(105);
+               expect(xScale1.bottom).toBe(145);
+
+               expect(xScale2.left).toBe(5);
+               expect(xScale2.right).toBe(245);
+               expect(xScale2.top).toBe(5);
+               expect(xScale2.bottom).toBe(45);
+
+               // Is yScale at the right spot
+               expect(yScale.left).toBe(5);
+               expect(yScale.right).toBe(45);
+               expect(yScale.top).toBe(45);
+               expect(yScale.bottom).toBe(105);
+       });
 });
\ No newline at end of file