Skip to content

Commit

Permalink
Add support for gridLines/angleLines borderDash for polarArea/radar c…
Browse files Browse the repository at this point in the history
…harts (chartjs#5850)
  • Loading branch information
nagix authored and simonbrunel committed Nov 26, 2018
1 parent ddc59a6 commit 947c23f
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 34 deletions.
2 changes: 2 additions & 0 deletions docs/axes/radial/linear.md
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions docs/axes/styling.md
Expand Up @@ -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.
Expand All @@ -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
Expand Down
17 changes: 10 additions & 7 deletions src/core/core.scale.js
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
64 changes: 40 additions & 24 deletions src/scales/scale.radialLinear.js
Expand Up @@ -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: {
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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) {
Expand Down
33 changes: 33 additions & 0 deletions 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
}
}
}
}
}
Binary file added test/fixtures/scale.radialLinear/border-dash.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions 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
}
}
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions 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
}
}
}
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion 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);
Expand All @@ -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,
Expand Down

0 comments on commit 947c23f

Please sign in to comment.