| Name | Type | Description
| ---- | ---- | -----------
-| `backgroundColor` | `Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
-| `borderColor` | `Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
-| `borderWidth` | `Number[]` | The border width of the arcs in the dataset.
-| `hoverBackgroundColor` | `Color[]` | The fill colour of the arcs when hovered.
-| `hoverBorderColor` | `Color[]` | The stroke colour of the arcs when hovered.
-| `hoverBorderWidth` | `Number[]` | The stroke width of the arcs when hovered.
+| `backgroundColor` | `Color/Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
+| `borderColor` | `Color/Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
+| `borderWidth` | `Number/Number[]` | The border width of the arcs in the dataset.
+| `borderAlign` | `String/String[]` | The border alignment of the arcs in the dataset. [more...](#border-alignment)
+| `hoverBackgroundColor` | `Color/Color[]` | The fill colour of the arcs when hovered.
+| `hoverBorderColor` | `Color/Color[]` | The stroke colour of the arcs when hovered.
+| `hoverBorderWidth` | `Number/Number[]` | The stroke width of the arcs when hovered.
+
+### Border Alignment
+
+The following values are supported for `borderAlign`.
+* `'center'` (default)
+* `'inner'`
+
+When `'center'` is set, the borders of arcs next to each other will overlap. When `'inner'` is set, it is guaranteed that all the borders are not overlap.
## Config Options
| Name | Type | Description
| ---- | ---- | -----------
-| `backgroundColor` | `Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
-| `borderColor` | `Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
-| `borderWidth` | `Number[]` | The border width of the arcs in the dataset.
-| `hoverBackgroundColor` | `Color[]` | The fill colour of the arcs when hovered.
-| `hoverBorderColor` | `Color[]` | The stroke colour of the arcs when hovered.
-| `hoverBorderWidth` | `Number[]` | The stroke width of the arcs when hovered.
+| `backgroundColor` | `Color/Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
+| `borderColor` | `Color/Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
+| `borderWidth` | `Number/Number[]` | The border width of the arcs in the dataset.
+| `borderAlign` | `String/String[]` | The border alignment of the arcs in the dataset. [more...](#border-alignment)
+| `hoverBackgroundColor` | `Color/Color[]` | The fill colour of the arcs when hovered.
+| `hoverBorderColor` | `Color/Color[]` | The stroke colour of the arcs when hovered.
+| `hoverBorderWidth` | `Number/Number[]` | The stroke width of the arcs when hovered.
+
+### Border Alignment
+
+The following values are supported for `borderAlign`.
+* `'center'` (default)
+* `'inner'`
+
+When `'center'` is set, the borders of arcs next to each other will overlap. When `'inner'` is set, it is guaranteed that all the borders are not overlap.
## Config Options
var chart = me.chart;
var chartArea = chart.chartArea;
var opts = chart.options;
- var arcOpts = opts.elements.arc;
- var availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth;
- var availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth;
+ var availableWidth = chartArea.right - chartArea.left;
+ var availableHeight = chartArea.bottom - chartArea.top;
var minSize = Math.min(availableWidth, availableHeight);
var offset = {x: 0, y: 0};
var meta = me.getMeta();
+ var arcs = meta.data;
var cutoutPercentage = opts.cutoutPercentage;
var circumference = opts.circumference;
+ var i, ilen;
// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
if (circumference < Math.PI * 2.0) {
offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
}
- chart.borderWidth = me.getMaxBorderWidth(meta.data);
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ arcs[i]._options = me._resolveElementOptions(arcs[i], i, reset);
+ }
+
+ chart.borderWidth = me.getMaxBorderWidth();
chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
- helpers.each(meta.data, function(arc, index) {
- me.updateElement(arc, index, reset);
- });
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ me.updateElement(arcs[i], i, reset);
+ }
},
updateElement: function(arc, index, reset) {
var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI));
var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
- var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+ var options = arc._options || {};
helpers.extend(arc, {
// Utility
// Desired view properties
_model: {
+ backgroundColor: options.backgroundColor,
+ borderColor: options.borderColor,
+ borderWidth: options.borderWidth,
+ borderAlign: options.borderAlign,
x: centerX + chart.offsetX,
y: centerY + chart.offsetY,
startAngle: startAngle,
circumference: circumference,
outerRadius: outerRadius,
innerRadius: innerRadius,
- label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
+ label: helpers.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])
}
});
var model = arc._model;
- // Resets the visual styles
- var custom = arc.custom || {};
- var valueOrDefault = helpers.valueAtIndexOrDefault;
- var elementOpts = this.chart.options.elements.arc;
- model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
- model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
- model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
-
// Set correct angles if not resetting
if (!reset || !animationOpts.animateRotate) {
if (index === 0) {
// gets the max border or hover width to properly scale pie charts
getMaxBorderWidth: function(arcs) {
+ var me = this;
var max = 0;
- var index = this.index;
- var length = arcs.length;
- var borderWidth;
- var hoverWidth;
+ var chart = me.chart;
+ var i, ilen, meta, arc, controller, options, borderWidth, hoverWidth;
+
+ if (!arcs) {
+ // Find the outmost visible dataset
+ for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {
+ if (chart.isDatasetVisible(i)) {
+ meta = chart.getDatasetMeta(i);
+ arcs = meta.data;
+ if (i !== me.index) {
+ controller = meta.controller;
+ }
+ break;
+ }
+ }
+ }
+
+ if (!arcs) {
+ return 0;
+ }
- for (var i = 0; i < length; i++) {
- borderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0;
- hoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
+ for (i = 0, ilen = arcs.length; i < ilen; ++i) {
+ arc = arcs[i];
+ options = controller ? controller._resolveElementOptions(arc, i) : arc._options;
+ if (options.borderAlign !== 'inner') {
+ borderWidth = options.borderWidth;
+ hoverWidth = options.hoverBorderWidth;
- max = borderWidth > max ? borderWidth : max;
- max = hoverWidth > max ? hoverWidth : max;
+ max = borderWidth > max ? borderWidth : max;
+ max = hoverWidth > max ? hoverWidth : max;
+ }
}
return max;
+ },
+
+ /**
+ * @private
+ */
+ _resolveElementOptions: function(arc, index) {
+ var me = this;
+ var dataset = me.getDataset();
+ var custom = arc.custom || {};
+ var options = me.chart.options.elements.arc;
+ var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault;
+
+ return {
+ backgroundColor: custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(dataset.backgroundColor, index, options.backgroundColor),
+ borderColor: custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(dataset.borderColor, index, options.borderColor),
+ borderWidth: custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(dataset.borderWidth, index, options.borderWidth),
+ borderAlign: custom.borderAlign ? custom.borderAlign : valueAtIndexOrDefault(dataset.borderAlign, index, options.borderAlign)
+ };
}
});
var chart = me.chart;
var chartArea = chart.chartArea;
var opts = chart.options;
- var arcOpts = opts.elements.arc;
var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
- chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0);
+ chart.outerRadius = Math.max(minSize / 2, 0);
chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);
chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor);
model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth);
+ model.borderAlign = custom.borderAlign ? custom.borderAlign : valueOrDefault(dataset.borderAlign, index, elementOpts.borderAlign);
arc.pivot();
},
arc: {
backgroundColor: defaults.global.defaultColor,
borderColor: '#fff',
- borderWidth: 2
+ borderWidth: 2,
+ borderAlign: 'center'
}
}
});
var vm = this._view;
var sA = vm.startAngle;
var eA = vm.endAngle;
+ var pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0;
+ var angleMargin;
- ctx.beginPath();
+ ctx.save();
- ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
+ ctx.beginPath();
+ ctx.arc(vm.x, vm.y, vm.outerRadius - pixelMargin, sA, eA);
ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
-
ctx.closePath();
- ctx.strokeStyle = vm.borderColor;
- ctx.lineWidth = vm.borderWidth;
ctx.fillStyle = vm.backgroundColor;
-
ctx.fill();
- ctx.lineJoin = 'bevel';
if (vm.borderWidth) {
+ if (vm.borderAlign === 'inner') {
+ // Draw an inner border by cliping the arc and drawing a double-width border
+ // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders
+ ctx.beginPath();
+ angleMargin = pixelMargin / vm.outerRadius;
+ ctx.arc(vm.x, vm.y, vm.outerRadius, sA - angleMargin, eA + angleMargin);
+ if (vm.innerRadius > pixelMargin) {
+ angleMargin = pixelMargin / vm.innerRadius;
+ ctx.arc(vm.x, vm.y, vm.innerRadius - pixelMargin, eA + angleMargin, sA - angleMargin, true);
+ } else {
+ ctx.arc(vm.x, vm.y, pixelMargin, eA + Math.PI / 2, sA - Math.PI / 2);
+ }
+ ctx.closePath();
+ ctx.clip();
+
+ ctx.beginPath();
+ ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA);
+ ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true);
+ ctx.closePath();
+
+ ctx.lineWidth = vm.borderWidth * 2;
+ ctx.lineJoin = 'round';
+ } else {
+ ctx.lineWidth = vm.borderWidth;
+ ctx.lineJoin = 'bevel';
+ }
+
+ ctx.strokeStyle = vm.borderColor;
ctx.stroke();
}
+
+ ctx.restore();
}
});
beginPath: function() {},
bezierCurveTo: function() {},
clearRect: function() {},
+ clip: function() {},
closePath: function() {},
fill: function() {},
fillRect: function() {},
--- /dev/null
+{
+ "config": {
+ "type": "doughnut",
+ "data": {
+ "labels": ["A", "B", "C", "D", "E"],
+ "datasets": [{
+ "data": [1, 5, 10, 50, 100],
+ "backgroundColor": [
+ "rgba(255, 99, 132, 0.8)",
+ "rgba(54, 162, 235, 0.8)",
+ "rgba(255, 206, 86, 0.8)",
+ "rgba(75, 192, 192, 0.8)",
+ "rgba(153, 102, 255, 0.8)"
+ ],
+ "borderWidth": 20,
+ "borderColor": [
+ "rgb(255, 99, 132)",
+ "rgb(54, 162, 235)",
+ "rgb(255, 206, 86)",
+ "rgb(75, 192, 192)",
+ "rgb(153, 102, 255)"
+ ]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "legend": false,
+ "title": false
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "doughnut",
+ "data": {
+ "labels": ["A", "B", "C", "D", "E"],
+ "datasets": [{
+ "data": [1, 5, 10, 50, 100],
+ "backgroundColor": [
+ "rgba(255, 99, 132, 0.8)",
+ "rgba(54, 162, 235, 0.8)",
+ "rgba(255, 206, 86, 0.8)",
+ "rgba(75, 192, 192, 0.8)",
+ "rgba(153, 102, 255, 0.8)"
+ ],
+ "borderWidth": 20,
+ "borderColor": [
+ "rgb(255, 99, 132)",
+ "rgb(54, 162, 235)",
+ "rgb(255, 206, 86)",
+ "rgb(75, 192, 192)",
+ "rgb(153, 102, 255)"
+ ],
+ "borderAlign": "inner"
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "legend": false,
+ "title": false
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "pie",
+ "data": {
+ "labels": ["A", "B", "C", "D", "E"],
+ "datasets": [{
+ "data": [1, 5, 10, 50, 100],
+ "backgroundColor": [
+ "rgba(255, 99, 132, 0.8)",
+ "rgba(54, 162, 235, 0.8)",
+ "rgba(255, 206, 86, 0.8)",
+ "rgba(75, 192, 192, 0.8)",
+ "rgba(153, 102, 255, 0.8)"
+ ],
+ "borderWidth": 20,
+ "borderColor": [
+ "rgb(255, 99, 132)",
+ "rgb(54, 162, 235)",
+ "rgb(255, 206, 86)",
+ "rgb(75, 192, 192)",
+ "rgb(153, 102, 255)"
+ ]
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "legend": false,
+ "title": false
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "pie",
+ "data": {
+ "labels": ["A", "B", "C", "D", "E"],
+ "datasets": [{
+ "data": [1, 5, 10, 50, 100],
+ "backgroundColor": [
+ "rgba(255, 99, 132, 0.8)",
+ "rgba(54, 162, 235, 0.8)",
+ "rgba(255, 206, 86, 0.8)",
+ "rgba(75, 192, 192, 0.8)",
+ "rgba(153, 102, 255, 0.8)"
+ ],
+ "borderWidth": 20,
+ "borderColor": [
+ "rgb(255, 99, 132)",
+ "rgb(54, 162, 235)",
+ "rgb(255, 206, 86)",
+ "rgb(75, 192, 192)",
+ "rgb(153, 102, 255)"
+ ],
+ "borderAlign": "inner"
+ }]
+ },
+ "options": {
+ "responsive": false,
+ "legend": false,
+ "title": false
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "polarArea",
+ "data": {
+ "labels": ["A", "B", "C", "D", "E"],
+ "datasets": [{
+ "data": [11, 16, 21, 1, 10],
+ "backgroundColor": [
+ "rgba(255, 99, 132, 0.8)",
+ "rgba(54, 162, 235, 0.8)",
+ "rgba(255, 206, 86, 0.8)",
+ "rgba(75, 192, 192, 0.8)",
+ "rgba(153, 102, 255, 0.8)"
+ ],
+ "borderWidth": 20,
+ "borderColor": [
+ "rgb(255, 99, 132)",
+ "rgb(54, 162, 235)",
+ "rgb(255, 206, 86)",
+ "rgb(75, 192, 192)",
+ "rgb(153, 102, 255)"
+ ]
+ }]
+ },
+ "options": {
+ "elements": {
+ "arc": {
+ "angle": [
+ 0.0378, 0.1892, 0.3786, 1.8925, 3.7849
+ ]
+ }
+ },
+ "responsive": false,
+ "legend": false,
+ "title": false,
+ "scale": {
+ "display": false
+ }
+ }
+ }
+}
--- /dev/null
+{
+ "config": {
+ "type": "polarArea",
+ "data": {
+ "labels": ["A", "B", "C", "D", "E"],
+ "datasets": [{
+ "data": [11, 16, 21, 1, 10],
+ "backgroundColor": [
+ "rgba(255, 99, 132, 0.8)",
+ "rgba(54, 162, 235, 0.8)",
+ "rgba(255, 206, 86, 0.8)",
+ "rgba(75, 192, 192, 0.8)",
+ "rgba(153, 102, 255, 0.8)"
+ ],
+ "borderWidth": 20,
+ "borderColor": [
+ "rgb(255, 99, 132)",
+ "rgb(54, 162, 235)",
+ "rgb(255, 206, 86)",
+ "rgb(75, 192, 192)",
+ "rgb(153, 102, 255)"
+ ],
+ "borderAlign": "inner"
+ }]
+ },
+ "options": {
+ "elements": {
+ "arc": {
+ "angle": [
+ 0.0378, 0.1892, 0.3786, 1.8925, 3.7849
+ ]
+ }
+ },
+ "responsive": false,
+ "legend": false,
+ "title": false,
+ "scale": {
+ "display": false
+ }
+ }
+ }
+}
describe('Chart.controllers.doughnut', function() {
+ describe('auto', jasmine.fixture.specs('controller.doughnut'));
+
it('should be registered as dataset controller', function() {
expect(typeof Chart.controllers.doughnut).toBe('function');
expect(Chart.controllers.doughnut).toBe(Chart.controllers.pie);
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
expect(meta.data[i]._model.y).toBeCloseToPixel(256);
- expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(254);
- expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(190);
+ expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(256);
+ expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(192);
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
startAngle: Math.PI * -0.5,
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
expect(meta.data[i]._model.y).toBeCloseToPixel(256);
- expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(254);
- expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(190);
+ expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(256);
+ expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(192);
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
{c: Math.PI / 8, s: Math.PI, e: Math.PI + Math.PI / 8},
{c: 3 * Math.PI / 8, s: Math.PI + Math.PI / 8, e: Math.PI + Math.PI / 2}
].forEach(function(expected, i) {
- expect(meta.data[i]._model.x).toBeCloseToPixel(511);
- expect(meta.data[i]._model.y).toBeCloseToPixel(511);
- expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(510);
- expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(382);
+ expect(meta.data[i]._model.x).toBeCloseToPixel(512);
+ expect(meta.data[i]._model.y).toBeCloseToPixel(512);
+ expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(512);
+ expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(384);
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
expect(arc._model.borderWidth).toBe(3.14159);
});
+
+ it ('should calculate radiuses based on the border widths of the visible outermost dataset', function() {
+ var chart = window.acquireChart({
+ type: 'doughnut',
+ data: {
+ datasets: [{
+ data: [2, 4],
+ borderWidth: 4,
+ hidden: true
+ }, {
+ data: [1, 3],
+ borderWidth: 8
+ }, {
+ data: [1, 0],
+ borderWidth: 12
+ }],
+ labels: ['label0', 'label1']
+ },
+ options: {
+ legend: false,
+ title: false
+ }
+ });
+
+ chart.update();
+
+ expect(chart.chartArea.bottom - chart.chartArea.top).toBe(512);
+ expect(chart.borderWidth).toBe(8);
+ expect(chart.outerRadius).toBe(252);
+ expect(chart.innerRadius).toBe(126);
+ expect(chart.radiusLength).toBe(63);
+
+ var controller = chart.getDatasetMeta(0).controller;
+ expect(controller.getMaxBorderWidth()).toBe(8);
+ expect(controller.outerRadius).toBe(252);
+ expect(controller.innerRadius).toBe(189);
+
+ controller = chart.getDatasetMeta(1).controller;
+ expect(controller.getMaxBorderWidth()).toBe(8);
+ expect(controller.outerRadius).toBe(252);
+ expect(controller.innerRadius).toBe(189);
+
+ controller = chart.getDatasetMeta(2).controller;
+ expect(controller.getMaxBorderWidth()).toBe(8);
+ expect(controller.outerRadius).toBe(189);
+ expect(controller.innerRadius).toBe(126);
+ });
+
});
if (model.width <= chart.width) {
expect(model.x + model.width).toBeLessThanOrEqual(chart.width);
}
- expect(model.caretX).toBe(tooltipPosition.x);
+ expect(model.caretX).toBeCloseToPixel(tooltipPosition.x);
// if tooltip is longer than chart area then all tests done
if (model.width > chart.width) {
break;
arc.draw();
expect(mockContext.getCalls()).toEqual([{
+ name: 'save',
+ args: []
+ }, {
name: 'beginPath',
args: []
}, {
}, {
name: 'closePath',
args: []
- }, {
- name: 'setStrokeStyle',
- args: ['rgb(255, 0, 0)']
- }, {
- name: 'setLineWidth',
- args: [undefined]
}, {
name: 'setFillStyle',
args: ['rgb(0, 0, 255)']
name: 'fill',
args: []
}, {
- name: 'setLineJoin',
- args: ['bevel']
+ name: 'restore',
+ args: []
}]);
});
arc.draw();
expect(mockContext.getCalls()).toEqual([{
+ name: 'save',
+ args: []
+ }, {
name: 'beginPath',
args: []
}, {
name: 'closePath',
args: []
}, {
- name: 'setStrokeStyle',
- args: ['rgb(255, 0, 0)']
+ name: 'setFillStyle',
+ args: ['rgb(0, 0, 255)']
+ }, {
+ name: 'fill',
+ args: []
}, {
name: 'setLineWidth',
args: [5]
+ }, {
+ name: 'setLineJoin',
+ args: ['bevel']
+ }, {
+ name: 'setStrokeStyle',
+ args: ['rgb(255, 0, 0)']
+ }, {
+ name: 'stroke',
+ args: []
+ }, {
+ name: 'restore',
+ args: []
+ }]);
+ });
+
+ it ('should draw correctly with an inner border', function() {
+ var mockContext = window.createMockContext();
+ var arc = new Chart.elements.Arc({
+ _datasetIndex: 2,
+ _index: 1,
+ _chart: {
+ ctx: mockContext,
+ }
+ });
+
+ // Mock out the view as if the controller put it there
+ arc._view = {
+ startAngle: 0,
+ endAngle: Math.PI / 2,
+ x: 10,
+ y: 5,
+ innerRadius: 1,
+ outerRadius: 3,
+
+ backgroundColor: 'rgb(0, 0, 255)',
+ borderColor: 'rgb(255, 0, 0)',
+ borderWidth: 5,
+ borderAlign: 'inner'
+ };
+
+ arc.draw();
+
+ expect(mockContext.getCalls()).toEqual([{
+ name: 'save',
+ args: []
+ }, {
+ name: 'beginPath',
+ args: []
+ }, {
+ name: 'arc',
+ args: [10, 5, 2.67, 0, Math.PI / 2]
+ }, {
+ name: 'arc',
+ args: [10, 5, 1, Math.PI / 2, 0, true]
+ }, {
+ name: 'closePath',
+ args: []
}, {
name: 'setFillStyle',
args: ['rgb(0, 0, 255)']
}, {
name: 'fill',
args: []
+ }, {
+ name: 'beginPath',
+ args: []
+ }, {
+ name: 'arc',
+ args: [10, 5, 3, -0.11, Math.PI / 2 + 0.11]
+ }, {
+ name: 'arc',
+ args: [10, 5, 1 - 0.33, Math.PI / 2 + 0.33, -0.33, true]
+ }, {
+ name: 'closePath',
+ args: []
+ }, {
+ name: 'clip',
+ args: []
+ }, {
+ name: 'beginPath',
+ args: []
+ }, {
+ name: 'arc',
+ args: [10, 5, 3, 0, Math.PI / 2]
+ }, {
+ name: 'arc',
+ args: [10, 5, 1, Math.PI / 2, 0, true]
+ }, {
+ name: 'closePath',
+ args: []
+ }, {
+ name: 'setLineWidth',
+ args: [10]
}, {
name: 'setLineJoin',
- args: ['bevel']
+ args: ['round']
+ }, {
+ name: 'setStrokeStyle',
+ args: ['rgb(255, 0, 0)']
}, {
name: 'stroke',
args: []
+ }, {
+ name: 'restore',
+ args: []
}]);
});
});