mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-06 12:19:08 +02:00
Adds different point styles
This commit is contained in:
parent
f6b18a5998
commit
655c1152eb
@ -209,6 +209,7 @@ line | - | - | -
|
||||
*line*.fill | Boolean | true |
|
||||
point | - | - | -
|
||||
*point*.radius | Number | 3 | Default point radius
|
||||
*point*.pointStyle | String | 'circle' | Default point style
|
||||
*point*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default point fill color
|
||||
*point*.borderWidth | Number | 1 | Default point stroke width
|
||||
*point*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default point stroke color
|
||||
|
@ -186,6 +186,7 @@
|
||||
// Appearance
|
||||
tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
|
||||
radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius),
|
||||
pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle),
|
||||
backgroundColor: this.getPointBackgroundColor(point, index),
|
||||
borderColor: this.getPointBorderColor(point, index),
|
||||
borderWidth: this.getPointBorderWidth(point, index),
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
Chart.defaults.global.elements.point = {
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
backgroundColor: Chart.defaults.global.defaultColor,
|
||||
borderWidth: 1,
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
@ -69,17 +70,88 @@
|
||||
|
||||
if (vm.radius > 0 || vm.borderWidth > 0) {
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
ctx.arc(vm.x, vm.y, vm.radius || Chart.defaults.global.elements.point.radius, 0, Math.PI * 2);
|
||||
ctx.closePath();
|
||||
|
||||
ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor;
|
||||
ctx.lineWidth = vm.borderWidth || Chart.defaults.global.elements.point.borderWidth;
|
||||
|
||||
ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor;
|
||||
|
||||
ctx.fill();
|
||||
var radius = vm.radius || Chart.defaults.global.elements.point.radius;
|
||||
|
||||
switch (vm.pointStyle) {
|
||||
case 'circle':
|
||||
default:
|
||||
ctx.beginPath();
|
||||
ctx.arc(vm.x, vm.y, radius, 0, Math.PI * 2);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
case 'triangle':
|
||||
ctx.beginPath();
|
||||
var edgeLength = 3 * radius / Math.sqrt(3);
|
||||
var height = edgeLength * Math.sqrt(3) / 2;
|
||||
ctx.moveTo(vm.x - edgeLength / 2, vm.y + height / 3);
|
||||
ctx.lineTo(vm.x + edgeLength / 2, vm.y + height / 3);
|
||||
ctx.lineTo(vm.x, vm.y - 2 * height / 3);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
case 'rect':
|
||||
ctx.fillRect(vm.x - radius, vm.y - radius, 2 * radius, 2 * radius);
|
||||
ctx.strokeRect(vm.x - radius, vm.y - radius, 2 * radius, 2 * radius);
|
||||
break;
|
||||
case 'rectRot':
|
||||
ctx.translate(vm.x, vm.y);
|
||||
ctx.rotate(Math.PI / 4);
|
||||
ctx.fillRect(-radius, -radius, 2 * radius, 2 * radius);
|
||||
ctx.strokeRect(-radius, -radius, 2 * radius, 2 * radius);
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
break;
|
||||
case 'cross':
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vm.x, vm.y + radius);
|
||||
ctx.lineTo(vm.x, vm.y - radius);
|
||||
ctx.moveTo(vm.x - radius, vm.y);
|
||||
ctx.lineTo(vm.x + radius, vm.y);
|
||||
ctx.closePath();
|
||||
break;
|
||||
case 'crossRot':
|
||||
ctx.beginPath();
|
||||
var xOffset = Math.cos(Math.PI / 4) * radius;
|
||||
var yOffset = Math.sin(Math.PI / 4) * radius;
|
||||
ctx.moveTo(vm.x - xOffset, vm.y - yOffset);
|
||||
ctx.lineTo(vm.x + xOffset, vm.y + yOffset);
|
||||
ctx.moveTo(vm.x - xOffset, vm.y + yOffset);
|
||||
ctx.lineTo(vm.x + xOffset, vm.y - yOffset);
|
||||
ctx.closePath();
|
||||
break;
|
||||
case 'star':
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vm.x, vm.y + radius);
|
||||
ctx.lineTo(vm.x, vm.y - radius);
|
||||
ctx.moveTo(vm.x - radius, vm.y);
|
||||
ctx.lineTo(vm.x + radius, vm.y);
|
||||
var xOffset = Math.cos(Math.PI / 4) * radius;
|
||||
var yOffset = Math.sin(Math.PI / 4) * radius;
|
||||
ctx.moveTo(vm.x - xOffset, vm.y - yOffset);
|
||||
ctx.lineTo(vm.x + xOffset, vm.y + yOffset);
|
||||
ctx.moveTo(vm.x - xOffset, vm.y + yOffset);
|
||||
ctx.lineTo(vm.x + xOffset, vm.y - yOffset);
|
||||
ctx.closePath();
|
||||
break;
|
||||
case 'line':
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vm.x - radius, vm.y);
|
||||
ctx.lineTo(vm.x + radius, vm.y);
|
||||
ctx.closePath();
|
||||
break;
|
||||
case 'dash':
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vm.x, vm.y);
|
||||
ctx.lineTo(vm.x + radius, vm.y);
|
||||
ctx.closePath();
|
||||
break;
|
||||
}
|
||||
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
@ -238,6 +238,7 @@ describe('Line controller tests', function() {
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle'
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
@ -281,6 +282,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0.1,
|
||||
|
||||
@ -301,6 +303,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0.1,
|
||||
|
||||
@ -321,6 +324,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0.1,
|
||||
|
||||
@ -341,6 +345,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: Chart.defaults.global.defaultColor,
|
||||
hitRadius: 1,
|
||||
radius: 3,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0.1,
|
||||
|
||||
@ -397,6 +402,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: 'rgb(56, 57, 58)',
|
||||
hitRadius: 3.3,
|
||||
radius: 22,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0,
|
||||
|
||||
@ -417,6 +423,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: 'rgb(56, 57, 58)',
|
||||
hitRadius: 3.3,
|
||||
radius: 22,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0,
|
||||
|
||||
@ -437,6 +444,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: 'rgb(56, 57, 58)',
|
||||
hitRadius: 3.3,
|
||||
radius: 22,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0,
|
||||
|
||||
@ -457,6 +465,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: 'rgb(56, 57, 58)',
|
||||
hitRadius: 3.3,
|
||||
radius: 22,
|
||||
pointStyle: 'circle',
|
||||
skip: false,
|
||||
tension: 0,
|
||||
|
||||
@ -519,6 +528,7 @@ describe('Line controller tests', function() {
|
||||
borderColor: 'rgb(4, 6, 8)',
|
||||
hitRadius: 5,
|
||||
radius: 2.2,
|
||||
pointStyle: 'circle',
|
||||
skip: true,
|
||||
tension: 0.15,
|
||||
|
||||
|
@ -77,6 +77,7 @@ describe('Point element tests', function() {
|
||||
// Attach a view object as if we were the controller
|
||||
point._view = {
|
||||
radius: 2,
|
||||
pointStyle: 'circle',
|
||||
hitRadius: 3,
|
||||
borderColor: 'rgba(1, 2, 3, 1)',
|
||||
borderWidth: 6,
|
||||
@ -89,15 +90,6 @@ describe('Point element tests', function() {
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 15, 2, 0, 2 * Math.PI]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
@ -106,6 +98,15 @@ describe('Point element tests', function() {
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 15, 2, 0, 2 * Math.PI]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
@ -113,6 +114,280 @@ describe('Point element tests', function() {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'triangle';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - 3 * 2 / Math.sqrt(3) / 2, 15 + 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + 3 * 2 / Math.sqrt(3) / 2, 15 + 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 15 - 2 * 3 * 2 / Math.sqrt(3) * Math.sqrt(3) / 2 / 3],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'rect';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'fillRect',
|
||||
args: [8, 13, 4, 4]
|
||||
}, {
|
||||
name: 'strokeRect',
|
||||
args: [8, 13, 4, 4]
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'rectRot';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'translate',
|
||||
args: [10, 15]
|
||||
}, {
|
||||
name: 'rotate',
|
||||
args: [Math.PI / 4]
|
||||
}, {
|
||||
name: 'fillRect',
|
||||
args: [-2, -2, 4, 4],
|
||||
}, {
|
||||
name: 'strokeRect',
|
||||
args: [-2, -2, 4, 4],
|
||||
}, {
|
||||
name: 'setTransform',
|
||||
args: [1, 0, 0, 1, 0, 0],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'cross';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10, 17]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 13],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 15],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
},{
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'crossRot';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'star';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10, 17]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10, 13],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 15],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
},{
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10 - Math.cos(Math.PI / 4) * 2, 15 + Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [10 + Math.cos(Math.PI / 4) * 2, 15 - Math.sin(Math.PI / 4) * 2],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'line';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [8, 15]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
mockContext.resetCalls();
|
||||
point._view.pointStyle = 'dash';
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(1, 2, 3, 1)']
|
||||
}, {
|
||||
name: 'setLineWidth',
|
||||
args: [6]
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0, 255, 0)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'moveTo',
|
||||
args: [10, 15]
|
||||
}, {
|
||||
name: 'lineTo',
|
||||
args: [12, 15],
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'stroke',
|
||||
args: []
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
it ('should draw correctly with default settings if necessary', function() {
|
||||
@ -137,15 +412,6 @@ describe('Point element tests', function() {
|
||||
point.draw();
|
||||
|
||||
expect(mockContext.getCalls()).toEqual([{
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 15, 2, 0, 2 * Math.PI]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'setStrokeStyle',
|
||||
args: ['rgba(0,0,0,0.1)']
|
||||
}, {
|
||||
@ -154,6 +420,15 @@ describe('Point element tests', function() {
|
||||
}, {
|
||||
name: 'setFillStyle',
|
||||
args: ['rgba(0,0,0,0.1)']
|
||||
}, {
|
||||
name: 'beginPath',
|
||||
args: []
|
||||
}, {
|
||||
name: 'arc',
|
||||
args: [10, 15, 2, 0, 2 * Math.PI]
|
||||
}, {
|
||||
name: 'closePath',
|
||||
args: [],
|
||||
}, {
|
||||
name: 'fill',
|
||||
args: [],
|
||||
|
@ -82,7 +82,9 @@
|
||||
save: function() {},
|
||||
setLineDash: function() {},
|
||||
stroke: function() {},
|
||||
translate: function() {},
|
||||
strokeRect: function(x, y, w, h) {},
|
||||
setTransform: function(a, b, c, d, e, f) {},
|
||||
translate: function(x, y) {},
|
||||
};
|
||||
|
||||
// attach methods to the class itself
|
||||
|
Loading…
Reference in New Issue
Block a user