From: Akihiko Kusanagi Date: Mon, 26 Nov 2018 07:57:31 +0000 (+0800) Subject: Add support for gridLines/angleLines borderDash for polarArea/radar charts (#5850) X-Git-Tag: v2.8.0-rc.1~107 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0351a88a631cc6b964af203d2ed92fe2e48f9d99;p=thirdparty%2FChart.js.git Add support for gridLines/angleLines borderDash for polarArea/radar charts (#5850) --- diff --git a/docs/axes/radial/linear.md b/docs/axes/radial/linear.md index d59b62251..d1edd18be 100644 --- a/docs/axes/radial/linear.md +++ b/docs/axes/radial/linear.md @@ -95,6 +95,8 @@ The following options are used to configure angled lines that radiate from the c | `display` | `Boolean` | `true` | if true, angle lines are shown. | `color` | `Color` | `rgba(0, 0, 0, 0.1)` | Color of angled lines. | `lineWidth` | `Number` | `1` | Width of angled lines. +| `borderDash` | `Number[]` | `[]` | Length and spacing of dashes on angled lines. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash). +| `borderDashOffset` | `Number` | `0.0` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). ## Point Label Options diff --git a/docs/axes/styling.md b/docs/axes/styling.md index 80a7a2e66..7184bc96f 100644 --- a/docs/axes/styling.md +++ b/docs/axes/styling.md @@ -12,7 +12,7 @@ The grid line configuration is nested under the scale configuration in the `grid | `circular` | `Boolean` | `false` | If true, gridlines are circular (on radar chart only). | `color` | `Color/Color[]` | `'rgba(0, 0, 0, 0.1)'` | The color of the grid lines. If specified as an array, the first color applies to the first grid line, the second to the second grid line and so on. | `borderDash` | `Number[]` | `[]` | Length and spacing of dashes on grid lines. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash). -| `borderDashOffset` | `Number` | `0` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). +| `borderDashOffset` | `Number` | `0.0` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). | `lineWidth` | `Number/Number[]` | `1` | Stroke width of grid lines. | `drawBorder` | `Boolean` | `true` | If true, draw border at the edge between the axis and the chart area. | `drawOnChartArea` | `Boolean` | `true` | If true, draw lines on the chart area inside the axis lines. This is useful when there are multiple axes and you need to control which grid lines are drawn. @@ -21,7 +21,7 @@ The grid line configuration is nested under the scale configuration in the `grid | `zeroLineWidth` | `Number` | `1` | Stroke width of the grid line for the first index (index 0). | `zeroLineColor` | Color | `'rgba(0, 0, 0, 0.25)'` | Stroke color of the grid line for the first index (index 0). | `zeroLineBorderDash` | `Number[]` | `[]` | Length and spacing of dashes of the grid line for the first index (index 0). See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash). -| `zeroLineBorderDashOffset` | `Number` | `0` | Offset for line dashes of the grid line for the first index (index 0). See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). +| `zeroLineBorderDashOffset` | `Number` | `0.0` | Offset for line dashes of the grid line for the first index (index 0). See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). | `offsetGridLines` | `Boolean` | `false` | If true, grid lines will be shifted to be between labels. This is set to `true` for a category scale in a bar chart by default. ## Tick Configuration diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 28211b7f4..e3a797944 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -728,13 +728,13 @@ module.exports = Element.extend({ // Draw the first index specially lineWidth = gridLines.zeroLineWidth; lineColor = gridLines.zeroLineColor; - borderDash = gridLines.zeroLineBorderDash; - borderDashOffset = gridLines.zeroLineBorderDashOffset; + borderDash = gridLines.zeroLineBorderDash || []; + borderDashOffset = gridLines.zeroLineBorderDashOffset || 0.0; } else { lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index); lineColor = helpers.valueAtIndexOrDefault(gridLines.color, index); - borderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash); - borderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset); + borderDash = gridLines.borderDash || []; + borderDashOffset = gridLines.borderDashOffset || 0.0; } // Common properties @@ -825,10 +825,13 @@ module.exports = Element.extend({ // Draw all of the tick labels, tick marks, and grid lines at the correct places helpers.each(itemsToDraw, function(itemToDraw) { - if (gridLines.display) { + var glWidth = itemToDraw.glWidth; + var glColor = itemToDraw.glColor; + + if (gridLines.display && glWidth && glColor) { context.save(); - context.lineWidth = itemToDraw.glWidth; - context.strokeStyle = itemToDraw.glColor; + context.lineWidth = glWidth; + context.strokeStyle = glColor; if (context.setLineDash) { context.setLineDash(itemToDraw.glBorderDash); context.lineDashOffset = itemToDraw.glBorderDashOffset; diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index b580e1da7..90ac22f0d 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -19,7 +19,9 @@ module.exports = function(Chart) { angleLines: { display: true, color: 'rgba(0, 0, 0, 0.1)', - lineWidth: 1 + lineWidth: 1, + borderDash: [], + borderDashOffset: 0.0 }, gridLines: { @@ -240,26 +242,34 @@ module.exports = function(Chart) { var ctx = scale.ctx; var opts = scale.options; var angleLineOpts = opts.angleLines; + var gridLineOpts = opts.gridLines; var pointLabelOpts = opts.pointLabels; - - ctx.lineWidth = angleLineOpts.lineWidth; - ctx.strokeStyle = angleLineOpts.color; + var lineWidth = helpers.valueOrDefault(angleLineOpts.lineWidth, gridLineOpts.lineWidth); + var lineColor = helpers.valueOrDefault(angleLineOpts.color, gridLineOpts.color); + + ctx.save(); + ctx.lineWidth = lineWidth; + ctx.strokeStyle = lineColor; + if (ctx.setLineDash) { + ctx.setLineDash(helpers.valueOrDefault(angleLineOpts.borderDash, gridLineOpts.borderDash) || []); + ctx.lineDashOffset = helpers.valueOrDefault(angleLineOpts.borderDashOffset, gridLineOpts.borderDashOffset) || 0.0; + } var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max); // Point Label Font var plFont = getPointLabelFontOptions(scale); + ctx.font = plFont.font; ctx.textBaseline = 'top'; for (var i = getValueCount(scale) - 1; i >= 0; i--) { - if (angleLineOpts.display) { + if (angleLineOpts.display && lineWidth && lineColor) { var outerPosition = scale.getPointPosition(i, outerDistance); ctx.beginPath(); ctx.moveTo(scale.xCenter, scale.yCenter); ctx.lineTo(outerPosition.x, outerPosition.y); ctx.stroke(); - ctx.closePath(); } if (pointLabelOpts.display) { @@ -268,7 +278,6 @@ module.exports = function(Chart) { // Keep this in loop since we may support array properties here var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor); - ctx.font = plFont.font; ctx.fillStyle = pointLabelFontColor; var angleRadians = scale.getIndexAngle(i); @@ -278,39 +287,46 @@ module.exports = function(Chart) { fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size); } } + ctx.restore(); } function drawRadiusLine(scale, gridLineOpts, radius, index) { var ctx = scale.ctx; - ctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1); - ctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1); + var circular = gridLineOpts.circular; + var valueCount = getValueCount(scale); + var lineColor = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1); + var lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1); + var pointPosition; - if (scale.options.gridLines.circular) { + if ((!circular && !valueCount) || !lineColor || !lineWidth) { + return; + } + + ctx.save(); + ctx.strokeStyle = lineColor; + ctx.lineWidth = lineWidth; + if (ctx.setLineDash) { + ctx.setLineDash(gridLineOpts.borderDash || []); + ctx.lineDashOffset = gridLineOpts.borderDashOffset || 0.0; + } + + ctx.beginPath(); + if (circular) { // Draw circular arcs between the points - ctx.beginPath(); ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2); - ctx.closePath(); - ctx.stroke(); } else { // Draw straight lines connecting each index - var valueCount = getValueCount(scale); - - if (valueCount === 0) { - return; - } - - ctx.beginPath(); - var pointPosition = scale.getPointPosition(0, radius); + pointPosition = scale.getPointPosition(0, radius); ctx.moveTo(pointPosition.x, pointPosition.y); for (var i = 1; i < valueCount; i++) { pointPosition = scale.getPointPosition(i, radius); ctx.lineTo(pointPosition.x, pointPosition.y); } - - ctx.closePath(); - ctx.stroke(); } + ctx.closePath(); + ctx.stroke(); + ctx.restore(); } function numberOrZero(param) { diff --git a/test/fixtures/scale.radialLinear/border-dash.json b/test/fixtures/scale.radialLinear/border-dash.json new file mode 100644 index 000000000..5a28ffab0 --- /dev/null +++ b/test/fixtures/scale.radialLinear/border-dash.json @@ -0,0 +1,33 @@ +{ + "config": { + "type": "radar", + "data": { + "labels": ["A", "B", "C", "D", "E"] + }, + "options": { + "responsive": false, + "legend": false, + "title": false, + "scale": { + "gridLines": { + "color": "rgba(0, 0, 255, 0.5)", + "lineWidth": 1, + "borderDash": [4, 2], + "borderDashOffset": 2 + }, + "angleLines": { + "color": "rgba(0, 0, 255, 0.5)", + "lineWidth": 1, + "borderDash": [4, 2], + "borderDashOffset": 2 + }, + "pointLabels": { + "display": false + }, + "ticks": { + "display": false + } + } + } + } +} diff --git a/test/fixtures/scale.radialLinear/border-dash.png b/test/fixtures/scale.radialLinear/border-dash.png new file mode 100644 index 000000000..eea0db5ff Binary files /dev/null and b/test/fixtures/scale.radialLinear/border-dash.png differ diff --git a/test/fixtures/scale.radialLinear/circular-border-dash.json b/test/fixtures/scale.radialLinear/circular-border-dash.json new file mode 100644 index 000000000..b69250de9 --- /dev/null +++ b/test/fixtures/scale.radialLinear/circular-border-dash.json @@ -0,0 +1,34 @@ +{ + "config": { + "type": "radar", + "data": { + "labels": ["A", "B", "C", "D", "E"] + }, + "options": { + "responsive": false, + "legend": false, + "title": false, + "scale": { + "gridLines": { + "circular": true, + "color": "rgba(0, 0, 255, 0.5)", + "lineWidth": 1, + "borderDash": [4, 2], + "borderDashOffset": 2 + }, + "angleLines": { + "color": "rgba(0, 0, 255, 0.5)", + "lineWidth": 1, + "borderDash": [4, 2], + "borderDashOffset": 2 + }, + "pointLabels": { + "display": false + }, + "ticks": { + "display": false + } + } + } + } +} diff --git a/test/fixtures/scale.radialLinear/circular-border-dash.png b/test/fixtures/scale.radialLinear/circular-border-dash.png new file mode 100644 index 000000000..fedb709e9 Binary files /dev/null and b/test/fixtures/scale.radialLinear/circular-border-dash.png differ diff --git a/test/fixtures/scale.radialLinear/indexable-gridlines.json b/test/fixtures/scale.radialLinear/indexable-gridlines.json new file mode 100644 index 000000000..d1ffb619c --- /dev/null +++ b/test/fixtures/scale.radialLinear/indexable-gridlines.json @@ -0,0 +1,40 @@ +{ + "config": { + "type": "radar", + "data": { + "labels": ["A", "B", "C", "D", "E"] + }, + "options": { + "responsive": false, + "legend": false, + "title": false, + "scale": { + "gridLines": { + "color": [ + "rgba(0, 0, 0, 0.5)", + "rgba(255, 255, 255, 0.5)", + false, + "", + "rgba(255, 0, 0, 0.5)", + "rgba(0, 255, 0, 0.5)", + "rgba(0, 0, 255, 0.5)", + "rgba(255, 255, 0, 0.5)", + "rgba(255, 0, 255, 0.5)", + "rgba(0, 255, 255, 0.5)" + ], + "lineWidth": [false, 0, 1, 2, 1, 2, 1, 2, 1, 2] + }, + "angleLines": { + "color": "rgba(255, 255, 255, 0.5)", + "lineWidth": 2 + }, + "pointLabels": { + "display": false + }, + "ticks": { + "display": false + } + } + } + } +} diff --git a/test/fixtures/scale.radialLinear/indexable-gridlines.png b/test/fixtures/scale.radialLinear/indexable-gridlines.png new file mode 100644 index 000000000..c6b9d87e8 Binary files /dev/null and b/test/fixtures/scale.radialLinear/indexable-gridlines.png differ diff --git a/test/specs/scale.radialLinear.tests.js b/test/specs/scale.radialLinear.tests.js index 707ce0b7c..5390ef77d 100644 --- a/test/specs/scale.radialLinear.tests.js +++ b/test/specs/scale.radialLinear.tests.js @@ -1,5 +1,7 @@ // Tests for the radial linear scale used by the polar area and radar charts describe('Test the radial linear scale', function() { + describe('auto', jasmine.fixture.specs('scale.radialLinear')); + it('Should register the constructor with the scale service', function() { var Constructor = Chart.scaleService.getScaleConstructor('radialLinear'); expect(Constructor).not.toBe(undefined); @@ -12,7 +14,9 @@ describe('Test the radial linear scale', function() { angleLines: { display: true, color: 'rgba(0, 0, 0, 0.1)', - lineWidth: 1 + lineWidth: 1, + borderDash: [], + borderDashOffset: 0.0 }, animate: true, display: true,