]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Allow axes to be centered on the chart area (#6818)
authorEvert Timberg <evert.timberg+github@gmail.com>
Mon, 16 Dec 2019 23:17:42 +0000 (18:17 -0500)
committerGitHub <noreply@github.com>
Mon, 16 Dec 2019 23:17:42 +0000 (18:17 -0500)
Allow axes to be centered on the chart area or at a dynamic position based on another axis

22 files changed:
docs/axes/cartesian/README.md
samples/samples.js
samples/scales/axis-center-position.html [new file with mode: 0644]
src/core/core.controller.js
src/core/core.layouts.js
src/core/core.scale.js
src/scales/scale.category.js
src/scales/scale.linear.js
src/scales/scale.logarithmic.js
src/scales/scale.time.js
test/fixtures/core.scale/x-axis-position-center.json [new file with mode: 0644]
test/fixtures/core.scale/x-axis-position-center.png [new file with mode: 0644]
test/fixtures/core.scale/x-axis-position-dynamic.json [new file with mode: 0644]
test/fixtures/core.scale/x-axis-position-dynamic.png [new file with mode: 0644]
test/fixtures/core.scale/y-axis-position-center.json [new file with mode: 0644]
test/fixtures/core.scale/y-axis-position-center.png [new file with mode: 0644]
test/fixtures/core.scale/y-axis-position-dynamic.json [new file with mode: 0644]
test/fixtures/core.scale/y-axis-position-dynamic.png [new file with mode: 0644]
test/specs/scale.category.tests.js
test/specs/scale.linear.tests.js
test/specs/scale.logarithmic.tests.js
test/specs/scale.time.tests.js

index 6b9b98253ae53afb65ae3bef5eb229e9fe601cb4..91bde595430e4df3237e63433c854eb4dd82e6cc 100644 (file)
@@ -14,13 +14,30 @@ All of the included cartesian axes support a number of common options.
 | Name | Type | Default | Description
 | ---- | ---- | ------- | -----------
 | `type` | `string` | | Type of scale being employed. Custom scales can be created and registered with a string key. This allows changing the type of an axis for a chart.
-| `position` | `string` | | Position of the axis in the chart. Possible values are: `'top'`, `'left'`, `'bottom'`, `'right'`
+| `position` | `string` | | Position of the axis. [more...](#axis-position)
+| `axis` | `string` | | Which type of axis this is. Possible values are: `'x'`, `'y'`. If not set, this is inferred from the first character of the ID which should be `'x'` or `'y'`.
 | `offset` | `boolean` | `false` | If true, extra space is added to the both edges and the axis is scaled to fit into the chart area. This is set to `true` for a bar chart by default.
 | `id` | `string` | | The ID is used to link datasets and scale axes together. [more...](#axis-id)
 | `gridLines` | `object` | | Grid line configuration. [more...](../styling.md#grid-line-configuration)
 | `scaleLabel` | `object` | | Scale title configuration. [more...](../labelling.md#scale-title-configuration)
 | `ticks` | `object` | | Tick configuration. [more...](#tick-configuration)
 
+### Axis Position
+
+An axis can either be positioned at the edge of the chart, at the center of the chart area, or dynamically with respect to a data value.
+
+To position the axis at the edge of the chart, set the `position` option to one of: `'top'`, `'left'`, `'bottom'`, `'right'`.
+To position the axis at the center of the chart area, set the `position` option to `'center'`. In this mode, either the `axis` option is specified or the axis ID starts with the letter 'x' or 'y'.
+To position the axis with respect to a data value, set the `position` option to an object such as: 
+
+```javascript
+{
+    x: -20
+}
+```
+
+This will position the axis at a value of -20 on the axis with ID "x". For cartesian axes, only 1 axis may be specified.
+
 ### Tick Configuration
 The following options are common to all cartesian axes but do not apply to other axes.
 
index 15ece3ff5680c284d65510a1cae1d18de5cc5c1d..d1cae567280590c076636620d909093f6dea0d6a 100644 (file)
                }, {
                        title: 'Axes Labels',
                        path: 'scales/axes-labels.html'
+               }, {
+                       title: 'Center Positioning',
+                       path: 'scales/axis-center-position.html'
                }]
        }, {
                title: 'Legend',
diff --git a/samples/scales/axis-center-position.html b/samples/scales/axis-center-position.html
new file mode 100644 (file)
index 0000000..e3f942c
--- /dev/null
@@ -0,0 +1,117 @@
+<!doctype html>
+<html>
+
+<head>
+       <title>Scatter Chart</title>
+       <script src="../../dist/Chart.js"></script>
+       <script src="../utils.js"></script>
+       <style>
+       canvas {
+               -moz-user-select: none;
+               -webkit-user-select: none;
+               -ms-user-select: none;
+       }
+       .chart-container {
+               width: 500px;
+               margin-left: 40px;
+               margin-right: 40px;
+               margin-bottom: 40px;
+       }
+       .container {
+               display: flex;
+               flex-direction: row;
+               flex-wrap: wrap;
+               justify-content: center;
+       }
+       </style>
+</head>
+
+<body>
+       <div class="container"></div>
+       <script>
+               var color = Chart.helpers.color;
+               function generateData() {
+                       var data = [];
+                       for (var i = 0; i < 7; i++) {
+                               data.push({
+                                       x: randomScalingFactor(),
+                                       y: randomScalingFactor()
+                               });
+                       }
+                       return data;
+               }
+
+               function createConfig(xPosition, yPosition, title) {
+                       var scatterChartData = {
+                               datasets: [{
+                                       label: 'My First dataset',
+                                       borderColor: window.chartColors.red,
+                                       backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
+                                       data: generateData()
+                               }, {
+                                       label: 'My Second dataset',
+                                       borderColor: window.chartColors.blue,
+                                       backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
+                                       data: generateData()
+                               }]
+                       };
+
+                       return {
+                               type: 'scatter',
+                               data: scatterChartData,
+                               options: {
+                                       responsive: true,
+                                       title: {
+                                               display: true,
+                                               text: title
+                                       },
+                                       scales: {
+                                               x: {
+                                                       position: xPosition,
+                                                       axis: 'x',
+                                                       min: -100,
+                                                       max: 100,
+                                               },
+                                               y: {
+                                                       position: yPosition,
+                                                       axis: 'y',
+                                                       min: -100,
+                                                       max: 100,
+                                               }
+                                       }
+                               }
+                       };
+               }
+
+               window.onload = function() {
+                       var container = document.querySelector('.container');
+
+                       [{
+                               title: 'Position: Vertical: left, Horizontal: bottom',
+                               xPosition: 'bottom',
+                               yPosition: 'left'
+                       }, {
+                               title: 'Position: Vertical: center, Horizontal: center',
+                               xPosition: 'center',
+                               yPosition: 'center'
+                       }, {
+                               title: 'Position: Vertical: x=-60, Horizontal: y=30',
+                               xPosition: {y: 30},
+                               yPosition: {x: -60}
+                       }].forEach(function(details) {
+                               var div = document.createElement('div');
+                               div.classList.add('chart-container');
+
+                               var canvas = document.createElement('canvas');
+                               div.appendChild(canvas);
+                               container.appendChild(div);
+
+                               var ctx = canvas.getContext('2d');
+                               var config = createConfig(details.xPosition, details.yPosition, details.title);
+                               new Chart(ctx, config);
+                       });
+               };
+       </script>
+</body>
+
+</html>
index 3ea05a925814d48c94343f836f6e49793242fad1..320049212115a0b440d5bb5c1a0f4c9a936ac300 100644 (file)
@@ -147,8 +147,9 @@ function updateConfig(chart) {
        chart.tooltip.initialize();
 }
 
-function positionIsHorizontal(position) {
-       return position === 'top' || position === 'bottom';
+const KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
+function positionIsHorizontal(position, axis) {
+       return position === 'top' || position === 'bottom' || (!KNOWN_POSITIONS.includes(position) && axis === 'x');
 }
 
 function compare2Level(l1, l2) {
@@ -341,7 +342,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
                        var id = scaleOptions.id;
                        var scaleType = valueOrDefault(scaleOptions.type, item.dtype);
 
-                       if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {
+                       if (scaleOptions.position === undefined || positionIsHorizontal(scaleOptions.position, scaleOptions.axis || id[0]) !== positionIsHorizontal(item.dposition)) {
                                scaleOptions.position = item.dposition;
                        }
 
index a166649bda9dc09823412b88deaff84bee5ef181..ac1b3eec9e9714810c3ad1a63f87286669fbf5cd 100644 (file)
@@ -5,10 +5,14 @@ var helpers = require('../helpers/index');
 
 var extend = helpers.extend;
 
+const STATIC_POSITIONS = ['left', 'top', 'right', 'bottom'];
+
 function filterByPosition(array, position) {
-       return helpers.where(array, function(v) {
-               return v.pos === position;
-       });
+       return helpers.where(array, v => v.pos === position);
+}
+
+function filterDynamicPositionByAxis(array, axis) {
+       return helpers.where(array, v => STATIC_POSITIONS.indexOf(v.pos) === -1 && v.box.axis === axis);
 }
 
 function sortByWeight(array, reverse) {
@@ -52,18 +56,20 @@ function setLayoutDims(layouts, params) {
 }
 
 function buildLayoutBoxes(boxes) {
-       var layoutBoxes = wrapBoxes(boxes);
-       var left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
-       var right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
-       var top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
-       var bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));
+       const layoutBoxes = wrapBoxes(boxes);
+       const left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
+       const right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
+       const top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
+       const bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));
+       const centerHorizontal = filterDynamicPositionByAxis(layoutBoxes, 'x');
+       const centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y');
 
        return {
                leftAndTop: left.concat(top),
-               rightAndBottom: right.concat(bottom),
+               rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal),
                chartArea: filterByPosition(layoutBoxes, 'chartArea'),
-               vertical: left.concat(right),
-               horizontal: top.concat(bottom)
+               vertical: left.concat(right).concat(centerVertical),
+               horizontal: top.concat(bottom).concat(centerHorizontal)
        };
 }
 
@@ -375,7 +381,9 @@ module.exports = {
                        left: chartArea.left,
                        top: chartArea.top,
                        right: chartArea.left + chartArea.w,
-                       bottom: chartArea.top + chartArea.h
+                       bottom: chartArea.top + chartArea.h,
+                       height: chartArea.h,
+                       width: chartArea.w,
                };
 
                // Finally update boxes in chartArea (radial scale for example)
index dfef9f448a0301f33114e2c45cc091d7d91e1bd9..6adce4a89ef99f7534751d8ab66beb1224a50279 100644 (file)
@@ -14,7 +14,6 @@ const resolve = helpers.options.resolve;
 
 defaults._set('scale', {
        display: true,
-       position: 'left',
        offset: false,
        reverse: false,
        beginAtZero: false,
@@ -669,7 +668,7 @@ class Scale extends Element {
                var scaleLabelOpts = opts.scaleLabel;
                var gridLineOpts = opts.gridLines;
                var display = me._isVisible();
-               var isBottom = opts.position === 'bottom';
+               var labelsBelowTicks = opts.position !== 'top' && me.axis === 'x';
                var isHorizontal = me.isHorizontal();
 
                // Width
@@ -717,10 +716,10 @@ class Scale extends Element {
                                // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned
                                // which means that the right padding is dominated by the font height
                                if (isRotated) {
-                                       paddingLeft = isBottom ?
+                                       paddingLeft = labelsBelowTicks ?
                                                cosRotation * firstLabelSize.width + sinRotation * firstLabelSize.offset :
                                                sinRotation * (firstLabelSize.height - firstLabelSize.offset);
-                                       paddingRight = isBottom ?
+                                       paddingRight = labelsBelowTicks ?
                                                sinRotation * (lastLabelSize.height - lastLabelSize.offset) :
                                                cosRotation * lastLabelSize.width + sinRotation * lastLabelSize.offset;
                                } else {
@@ -778,8 +777,8 @@ class Scale extends Element {
 
        // Shared Methods
        isHorizontal() {
-               var pos = this.options.position;
-               return pos === 'top' || pos === 'bottom';
+               const {axis, position} = this.options;
+               return position === 'top' || position === 'bottom' || axis === 'x';
        }
        isFullWidth() {
                return this.options.fullWidth;
@@ -965,10 +964,10 @@ class Scale extends Element {
         */
        _computeGridLineItems(chartArea) {
                var me = this;
+               const axis = me.axis;
                var chart = me.chart;
                var options = me.options;
-               var gridLines = options.gridLines;
-               var position = options.position;
+               const {gridLines, position} = options;
                var offsetGridLines = gridLines.offsetGridLines;
                var isHorizontal = me.isHorizontal();
                var ticks = me.ticks;
@@ -1006,12 +1005,38 @@ class Scale extends Element {
                        tx2 = borderValue - axisHalfWidth;
                        x1 = alignBorderValue(chartArea.left) + axisHalfWidth;
                        x2 = chartArea.right;
-               } else {
+               } else if (position === 'right') {
                        borderValue = alignBorderValue(me.left);
                        x1 = chartArea.left;
                        x2 = alignBorderValue(chartArea.right) - axisHalfWidth;
                        tx1 = borderValue + axisHalfWidth;
                        tx2 = me.left + tl;
+               } else if (axis === 'x') {
+                       if (position === 'center') {
+                               borderValue = alignBorderValue((chartArea.top + chartArea.bottom) / 2);
+                       } else if (helpers.isObject(position)) {
+                               const positionAxisID = Object.keys(position)[0];
+                               const value = position[positionAxisID];
+                               borderValue = alignBorderValue(me.chart.scales[positionAxisID].getPixelForValue(value));
+                       }
+
+                       y1 = chartArea.top;
+                       y2 = chartArea.bottom;
+                       ty1 = borderValue + axisHalfWidth;
+                       ty2 = ty1 + tl;
+               } else if (axis === 'y') {
+                       if (position === 'center') {
+                               borderValue = alignBorderValue((chartArea.left + chartArea.right) / 2);
+                       } else if (helpers.isObject(position)) {
+                               const positionAxisID = Object.keys(position)[0];
+                               const value = position[positionAxisID];
+                               borderValue = alignBorderValue(me.chart.scales[positionAxisID].getPixelForValue(value));
+                       }
+
+                       tx1 = borderValue - axisHalfWidth;
+                       tx2 = tx1 - tl;
+                       x1 = chartArea.left;
+                       x2 = chartArea.right;
                }
 
                for (i = 0; i < ticksLength; ++i) {
@@ -1067,20 +1092,20 @@ class Scale extends Element {
        /**
         * @private
         */
-       _computeLabelItems() {
-               var me = this;
-               var options = me.options;
-               var optionTicks = options.ticks;
-               var position = options.position;
-               var isMirrored = optionTicks.mirror;
-               var isHorizontal = me.isHorizontal();
-               var ticks = me.ticks;
-               var fonts = parseTickFontOptions(optionTicks);
-               var tickPadding = optionTicks.padding;
-               var tl = getTickMarkLength(options.gridLines);
-               var rotation = -helpers.toRadians(me.labelRotation);
-               var items = [];
-               var i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;
+       _computeLabelItems(chartArea) {
+               const me = this;
+               const axis = me.axis;
+               const options = me.options;
+               const {position, ticks: optionTicks} = options;
+               const isMirrored = optionTicks.mirror;
+               const isHorizontal = me.isHorizontal();
+               const ticks = me.ticks;
+               const fonts = parseTickFontOptions(optionTicks);
+               const tickPadding = optionTicks.padding;
+               const tl = getTickMarkLength(options.gridLines);
+               const rotation = -helpers.toRadians(me.labelRotation);
+               const items = [];
+               let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;
 
                if (position === 'top') {
                        y = me.bottom - tl - tickPadding;
@@ -1091,9 +1116,27 @@ class Scale extends Element {
                } else if (position === 'left') {
                        x = me.right - (isMirrored ? 0 : tl) - tickPadding;
                        textAlign = isMirrored ? 'left' : 'right';
-               } else {
+               } else if (position === 'right') {
                        x = me.left + (isMirrored ? 0 : tl) + tickPadding;
                        textAlign = isMirrored ? 'right' : 'left';
+               } else if (axis === 'x') {
+                       if (position === 'center') {
+                               y = ((chartArea.top + chartArea.bottom) / 2) + tl + tickPadding;
+                       } else if (helpers.isObject(position)) {
+                               const positionAxisID = Object.keys(position)[0];
+                               const value = position[positionAxisID];
+                               y = me.chart.scales[positionAxisID].getPixelForValue(value) + tl + tickPadding;
+                       }
+                       textAlign = !rotation ? 'center' : 'right';
+               } else if (axis === 'y') {
+                       if (position === 'center') {
+                               x = ((chartArea.left + chartArea.right) / 2) - tl - tickPadding;
+                       } else if (helpers.isObject(position)) {
+                               const positionAxisID = Object.keys(position)[0];
+                               const value = position[positionAxisID];
+                               x = me.chart.scales[positionAxisID].getPixelForValue(value);
+                       }
+                       textAlign = 'right';
                }
 
                for (i = 0, ilen = ticks.length; i < ilen; ++i) {
@@ -1214,7 +1257,7 @@ class Scale extends Element {
        /**
         * @private
         */
-       _drawLabels() {
+       _drawLabels(chartArea) {
                var me = this;
                var optionTicks = me.options.ticks;
 
@@ -1223,7 +1266,7 @@ class Scale extends Element {
                }
 
                var ctx = me.ctx;
-               var items = me._labelItems || (me._labelItems = me._computeLabelItems());
+               var items = me._labelItems || (me._labelItems = me._computeLabelItems(chartArea));
                var i, j, ilen, jlen, item, tickFont, label, y;
 
                for (i = 0, ilen = items.length; i < ilen; ++i) {
@@ -1335,7 +1378,7 @@ class Scale extends Element {
 
                me._drawGrid(chartArea);
                me._drawTitle();
-               me._drawLabels();
+               me._drawLabels(chartArea);
        }
 
        /**
index 147a42d3e1b0fd0d68b7695339d4ca3e30fcc862..15d1afc55d55d34b56a6f16857d894f388f18a83 100644 (file)
@@ -3,7 +3,6 @@
 import Scale from '../core/core.scale';
 
 const defaultConfig = {
-       position: 'bottom'
 };
 
 class CategoryScale extends Scale {
index 2670eb5131b42df3615959d006db5a9fa32af62b..a26db1332f8db97802fb24d40212f5f599055b66 100644 (file)
@@ -5,7 +5,6 @@ import LinearScaleBase from './scale.linearbase';
 import Ticks from '../core/core.ticks';
 
 const defaultConfig = {
-       position: 'left',
        ticks: {
                callback: Ticks.formatters.linear
        }
index a5ae779b8fe61fabddb7b3309f0be661dd669de1..d48ce5b64ae49e5909b9905f82b82cf79af279ee 100644 (file)
@@ -56,8 +56,6 @@ function generateTicks(generationOptions, dataRange) {
 }
 
 const defaultConfig = {
-       position: 'left',
-
        // label settings
        ticks: {
                callback: Ticks.formatters.logarithmic
index 4741bcfcb2607e3097670c5900cac95794137261..9e39e6a082c5f8bc36e379c5b8b8f4d1b6a776e8 100644 (file)
@@ -485,8 +485,6 @@ function filterBetween(timestamps, min, max) {
 }
 
 const defaultConfig = {
-       position: 'bottom',
-
        /**
         * Data distribution along the scale:
         * - 'linear': data are spread according to their time (distances can vary),
diff --git a/test/fixtures/core.scale/x-axis-position-center.json b/test/fixtures/core.scale/x-axis-position-center.json
new file mode 100644 (file)
index 0000000..94583f9
--- /dev/null
@@ -0,0 +1,57 @@
+{
+    "config": {
+        "type": "scatter",
+        "data": {
+            "datasets": [{
+                "data": [{
+                    "x": -20,
+                    "y": -30
+                }, {
+                    "x": 0,
+                    "y": 0
+                }, {
+                    "x": 20,
+                    "y": 15
+                }]
+            }]
+        },
+        "options": {
+            "legend": false,
+            "title": false,
+            "scales": {
+                "x": {
+                    "position": "center",
+                    "axis": "x",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                },
+                "y": {
+                    "position": "left",
+                    "axis": "y",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/core.scale/x-axis-position-center.png b/test/fixtures/core.scale/x-axis-position-center.png
new file mode 100644 (file)
index 0000000..c9ef8c8
Binary files /dev/null and b/test/fixtures/core.scale/x-axis-position-center.png differ
diff --git a/test/fixtures/core.scale/x-axis-position-dynamic.json b/test/fixtures/core.scale/x-axis-position-dynamic.json
new file mode 100644 (file)
index 0000000..84e8067
--- /dev/null
@@ -0,0 +1,59 @@
+{
+    "config": {
+        "type": "scatter",
+        "data": {
+            "datasets": [{
+                "data": [{
+                    "x": -20,
+                    "y": -30
+                }, {
+                    "x": 0,
+                    "y": 0
+                }, {
+                    "x": 20,
+                    "y": 15
+                }]
+            }]
+        },
+        "options": {
+            "legend": false,
+            "title": false,
+            "scales": {
+                "x": {
+                    "position": {
+                        "y": 30
+                    },
+                    "axis": "x",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                },
+                "y": {
+                    "position": "left",
+                    "axis": "y",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/core.scale/x-axis-position-dynamic.png b/test/fixtures/core.scale/x-axis-position-dynamic.png
new file mode 100644 (file)
index 0000000..0ac0a90
Binary files /dev/null and b/test/fixtures/core.scale/x-axis-position-dynamic.png differ
diff --git a/test/fixtures/core.scale/y-axis-position-center.json b/test/fixtures/core.scale/y-axis-position-center.json
new file mode 100644 (file)
index 0000000..76cc0db
--- /dev/null
@@ -0,0 +1,57 @@
+{
+    "config": {
+        "type": "scatter",
+        "data": {
+            "datasets": [{
+                "data": [{
+                    "x": -20,
+                    "y": -30
+                }, {
+                    "x": 0,
+                    "y": 0
+                }, {
+                    "x": 20,
+                    "y": 15
+                }]
+            }]
+        },
+        "options": {
+            "legend": false,
+            "title": false,
+            "scales": {
+                "x": {
+                    "position": "bottom",
+                    "axis": "x",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                },
+                "y": {
+                    "position": "center",
+                    "axis": "y",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/core.scale/y-axis-position-center.png b/test/fixtures/core.scale/y-axis-position-center.png
new file mode 100644 (file)
index 0000000..ce00ead
Binary files /dev/null and b/test/fixtures/core.scale/y-axis-position-center.png differ
diff --git a/test/fixtures/core.scale/y-axis-position-dynamic.json b/test/fixtures/core.scale/y-axis-position-dynamic.json
new file mode 100644 (file)
index 0000000..c0f9bc3
--- /dev/null
@@ -0,0 +1,59 @@
+{
+    "config": {
+        "type": "scatter",
+        "data": {
+            "datasets": [{
+                "data": [{
+                    "x": -20,
+                    "y": -30
+                }, {
+                    "x": 0,
+                    "y": 0
+                }, {
+                    "x": 20,
+                    "y": 15
+                }]
+            }]
+        },
+        "options": {
+            "legend": false,
+            "title": false,
+            "scales": {
+                "x": {
+                    "position": "bottom",
+                    "axis": "x",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                },
+                "y": {
+                    "position": {
+                        "x": -50
+                    },
+                    "axis": "y",
+                    "min": -100,
+                    "max": 100,
+                    "gridLines": {
+                        "color": "red",
+                        "drawOnChartArea": false
+                    },
+                    "ticks": {
+                        "display": false
+                    }
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/core.scale/y-axis-position-dynamic.png b/test/fixtures/core.scale/y-axis-position-dynamic.png
new file mode 100644 (file)
index 0000000..70f4efb
Binary files /dev/null and b/test/fixtures/core.scale/y-axis-position-dynamic.png differ
index 5485f137e016241f7999352ac5ee57fe42ecc5a1..daf69e7ffd047b0839e34ab1f7e2d58d9c99619f 100644 (file)
@@ -34,7 +34,6 @@ describe('Category scale tests', function() {
                                borderDash: [],
                                borderDashOffset: 0.0
                        },
-                       position: 'bottom',
                        offset: false,
                        scaleLabel: Chart.defaults.scale.scaleLabel,
                        ticks: {
@@ -68,6 +67,7 @@ describe('Category scale tests', function() {
                };
 
                var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
+               config.position = 'bottom';
                var Constructor = Chart.scaleService.getScaleConstructor('category');
                var scale = new Constructor({
                        ctx: {},
@@ -95,6 +95,7 @@ describe('Category scale tests', function() {
                };
 
                var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
+               config.position = 'bottom';
                var Constructor = Chart.scaleService.getScaleConstructor('category');
                var scale = new Constructor({
                        ctx: {},
index 459db671c5777214252180900111959c73d9f548..90a4f05fdf5afe94a52fc2163bea193feeb1c897 100644 (file)
@@ -25,7 +25,6 @@ describe('Linear Scale', function() {
                                borderDash: [],
                                borderDashOffset: 0.0
                        },
-                       position: 'left',
                        offset: false,
                        reverse: false,
                        beginAtZero: false,
index 599dfd38e5e3f25d31c5b31ae57e1766649e3ea2..5c0fa9cdc16095331573f78bec22f573a8f44dfc 100644 (file)
@@ -25,7 +25,6 @@ describe('Logarithmic Scale tests', function() {
                                borderDash: [],
                                borderDashOffset: 0.0
                        },
-                       position: 'left',
                        offset: false,
                        reverse: false,
                        beginAtZero: false,
index 09fc2ff0204aeb9b744bce58c57c90f8d6c3f877..465a7e0f48b3eede24c320bf5eea8c4a89f0502b 100755 (executable)
@@ -72,7 +72,6 @@ describe('Time scale tests', function() {
                                borderDash: [],
                                borderDashOffset: 0.0
                        },
-                       position: 'bottom',
                        offset: false,
                        reverse: false,
                        beginAtZero: false,