diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 3f1559c3003..be29a6e3cff 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -47,17 +47,36 @@ defaults._set('global', { generateLabels: function(chart) { var data = chart.data; return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) { + var type = chart.getDatasetMeta(i).type; + var options = chart.options; + var legendOpts = options.legend; + + var usePointStyle = legendOpts && legendOpts.labels && legendOpts.labels.usePointStyle; + var backgroundColor = usePointStyle ? dataset.pointBackgroundColor : dataset.backgroundColor; + var borderWidth = usePointStyle ? dataset.pointBorderWidth : dataset.borderWidth; + var borderColor = usePointStyle ? dataset.pointBorderColor : dataset.borderColor; + + var useLineStyles = (type === 'line' || type === 'radar') && !usePointStyle; + var borderCapStyle = useLineStyles ? dataset.borderCapStyle : 'butt'; + var borderDash = useLineStyles ? dataset.borderDash : []; + var borderDashOffset = useLineStyles ? dataset.borderDashOffset : 0; + var borderJoinStyle = useLineStyles ? dataset.borderJoinStyle : 'miter'; + + var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; + var valueOrDefault = helpers.valueOrDefault; + var elementOpts = options.elements[useLineStyles ? 'line' : type === 'bar' ? 'rectangle' : 'point']; + return { text: dataset.label, - fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]), + fillStyle: valueAtIndexOrDefault(backgroundColor, 0, elementOpts.backgroundColor), hidden: !chart.isDatasetVisible(i), - lineCap: dataset.borderCapStyle, - lineDash: dataset.borderDash, - lineDashOffset: dataset.borderDashOffset, - lineJoin: dataset.borderJoinStyle, - lineWidth: dataset.borderWidth, - strokeStyle: dataset.borderColor, - pointStyle: dataset.pointStyle, + lineCap: valueOrDefault(borderCapStyle, elementOpts.borderCapStyle), + lineDash: valueOrDefault(borderDash, elementOpts.borderDash), + lineDashOffset: valueOrDefault(borderDashOffset, elementOpts.borderDashOffset), + lineJoin: valueOrDefault(borderJoinStyle, elementOpts.borderJoinStyle), + lineWidth: valueAtIndexOrDefault(borderWidth, 0, elementOpts.borderWidth), + strokeStyle: valueAtIndexOrDefault(borderColor, 0, elementOpts.borderColor), + pointStyle: valueAtIndexOrDefault(dataset.pointStyle, 0, elementOpts.pointStyle), // Below is extra data used for toggling the datasets datasetIndex: i @@ -383,10 +402,10 @@ var Legend = Element.extend({ helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY); } else { // Draw box as legend symbol + ctx.fillRect(x, y, boxWidth, fontSize); if (!isLineWidthZero) { ctx.strokeRect(x, y, boxWidth, fontSize); } - ctx.fillRect(x, y, boxWidth, fontSize); } ctx.restore(); diff --git a/test/specs/plugin.legend.tests.js b/test/specs/plugin.legend.tests.js index 5b75069aaea..04c886ca88a 100644 --- a/test/specs/plugin.legend.tests.js +++ b/test/specs/plugin.legend.tests.js @@ -20,21 +20,21 @@ describe('Legend block tests', function() { }); }); - it('should update correctly', function() { + it('should update bar chart correctly', function() { var chart = window.acquireChart({ type: 'bar', data: { datasets: [{ label: 'dataset1', backgroundColor: '#f31', - borderCapStyle: 'butt', + borderCapStyle: 'round', borderDash: [2, 2], borderDashOffset: 5.5, data: [] }, { label: 'dataset2', hidden: true, - borderJoinStyle: 'miter', + borderJoinStyle: 'round', data: [] }, { label: 'dataset3', @@ -52,33 +52,99 @@ describe('Legend block tests', function() { fillStyle: '#f31', hidden: false, lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 0, + strokeStyle: 'rgba(0,0,0,0.1)', + pointStyle: undefined, + datasetIndex: 0 + }, { + text: 'dataset2', + fillStyle: 'rgba(0,0,0,0.1)', + hidden: true, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 0, + strokeStyle: 'rgba(0,0,0,0.1)', + pointStyle: undefined, + datasetIndex: 1 + }, { + text: 'dataset3', + fillStyle: 'rgba(0,0,0,0.1)', + hidden: false, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 10, + strokeStyle: 'green', + pointStyle: 'crossRot', + datasetIndex: 2 + }]); + }); + + it('should update line chart correctly', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'dataset1', + backgroundColor: '#f31', + borderCapStyle: 'round', + borderDash: [2, 2], + borderDashOffset: 5.5, + data: [] + }, { + label: 'dataset2', + hidden: true, + borderJoinStyle: 'round', + data: [] + }, { + label: 'dataset3', + borderWidth: 10, + borderColor: 'green', + pointStyle: 'crossRot', + data: [] + }], + labels: [] + } + }); + + expect(chart.legend.legendItems).toEqual([{ + text: 'dataset1', + fillStyle: '#f31', + hidden: false, + lineCap: 'round', lineDash: [2, 2], lineDashOffset: 5.5, - lineJoin: undefined, - lineWidth: undefined, - strokeStyle: undefined, + lineJoin: 'miter', + lineWidth: 3, + strokeStyle: 'rgba(0,0,0,0.1)', pointStyle: undefined, datasetIndex: 0 }, { text: 'dataset2', - fillStyle: undefined, + fillStyle: 'rgba(0,0,0,0.1)', hidden: true, - lineCap: undefined, - lineDash: undefined, - lineDashOffset: undefined, - lineJoin: 'miter', - lineWidth: undefined, - strokeStyle: undefined, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'round', + lineWidth: 3, + strokeStyle: 'rgba(0,0,0,0.1)', pointStyle: undefined, datasetIndex: 1 }, { text: 'dataset3', - fillStyle: undefined, + fillStyle: 'rgba(0,0,0,0.1)', hidden: false, - lineCap: undefined, - lineDash: undefined, - lineDashOffset: undefined, - lineJoin: undefined, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', lineWidth: 10, strokeStyle: 'green', pointStyle: 'crossRot', @@ -93,14 +159,14 @@ describe('Legend block tests', function() { datasets: [{ label: 'dataset1', backgroundColor: '#f31', - borderCapStyle: 'butt', + borderCapStyle: 'round', borderDash: [2, 2], borderDashOffset: 5.5, data: [] }, { label: 'dataset2', hidden: true, - borderJoinStyle: 'miter', + borderJoinStyle: 'round', data: [], legendHidden: true }, { @@ -129,21 +195,21 @@ describe('Legend block tests', function() { fillStyle: '#f31', hidden: false, lineCap: 'butt', - lineDash: [2, 2], - lineDashOffset: 5.5, - lineJoin: undefined, - lineWidth: undefined, - strokeStyle: undefined, + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 0, + strokeStyle: 'rgba(0,0,0,0.1)', pointStyle: undefined, datasetIndex: 0 }, { text: 'dataset3', - fillStyle: undefined, + fillStyle: 'rgba(0,0,0,0.1)', hidden: false, - lineCap: undefined, - lineDash: undefined, - lineDashOffset: undefined, - lineJoin: undefined, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', lineWidth: 10, strokeStyle: 'green', pointStyle: 'crossRot', @@ -159,7 +225,7 @@ describe('Legend block tests', function() { datasets: [{ label: 'dataset1', backgroundColor: '#f31', - borderCapStyle: 'butt', + borderCapStyle: 'round', borderDash: [2, 2], borderDashOffset: 5.5, data: [] @@ -183,14 +249,14 @@ describe('Legend block tests', function() { datasets: [{ label: 'dataset1', backgroundColor: '#f31', - borderCapStyle: 'butt', + borderCapStyle: 'round', borderDash: [2, 2], borderDashOffset: 5.5, data: [] }, { label: 'dataset2', hidden: true, - borderJoinStyle: 'miter', + borderJoinStyle: 'round', data: [] }, { label: 'dataset3', @@ -262,33 +328,30 @@ describe('Legend block tests', function() { "args": ["butt"] }, { "name": "setLineDashOffset", - "args": [5.5] + "args": [0] }, { "name": "setLineJoin", "args": ["miter"] }, { "name": "setLineWidth", - "args": [3] + "args": [0] }, { "name": "setStrokeStyle", "args": ["rgba(0,0,0,0.1)"] }, { "name": "setLineDash", "args": [ - [2, 2] + [] ] - }, { - "name": "strokeRect", - "args": [114, 110, 40, 12] }, { "name": "fillRect", - "args": [114, 110, 40, 12] + "args": [52, 10, 40, 12] }, { "name": "restore", "args": [] }, { "name": "fillText", - "args": ["dataset1", 160, 110] + "args": ["dataset1", 98, 16] }, { "name": "measureText", "args": ["dataset2"] @@ -309,7 +372,7 @@ describe('Legend block tests', function() { "args": ["miter"] }, { "name": "setLineWidth", - "args": [3] + "args": [0] }, { "name": "setStrokeStyle", "args": ["rgba(0,0,0,0.1)"] @@ -318,18 +381,15 @@ describe('Legend block tests', function() { "args": [ [] ] - }, { - "name": "strokeRect", - "args": [250, 110, 40, 12] }, { "name": "fillRect", - "args": [250, 110, 40, 12] + "args": [188, 10, 40, 12] }, { "name": "restore", "args": [] }, { "name": "fillText", - "args": ["dataset2", 296, 110] + "args": ["dataset2", 234, 16] }, { "name": "beginPath", "args": [] @@ -338,10 +398,10 @@ describe('Legend block tests', function() { "args": [2] }, { "name": "moveTo", - "args": [296, 116] + "args": [234, 16] }, { "name": "lineTo", - "args": [376, 116] + "args": [314, 16] }, { "name": "stroke", "args": [] @@ -374,21 +434,98 @@ describe('Legend block tests', function() { "args": [ [] ] - }, { - "name": "strokeRect", - "args": [182, 132, 40, 12] }, { "name": "fillRect", - "args": [182, 132, 40, 12] + "args": [324, 10, 40, 12] + }, { + "name": "strokeRect", + "args": [324, 10, 40, 12] }, { "name": "restore", "args": [] }, { "name": "fillText", - "args": ["dataset3", 228, 132] + "args": ["dataset3", 370, 16] }]);*/ }); + it('should pick up the first item when the propertiy is an array', function() { + var chart = window.acquireChart({ + type: 'bar', + data: { + datasets: [{ + label: 'dataset1', + backgroundColor: ['#f31', '#666', '#14e'], + borderWidth: [5, 10, 15], + borderColor: ['red', 'green', 'blue'], + pointStyle: ['crossRot', 'triangle', 'star'], + data: [] + }], + labels: [] + } + }); + + expect(chart.legend.legendItems).toEqual([{ + text: 'dataset1', + fillStyle: '#f31', + hidden: false, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 5, + strokeStyle: 'red', + pointStyle: 'crossRot', + datasetIndex: 0 + }]); + }); + + it('should draw correctly when usePointStyle is true', function() { + var chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'dataset1', + backgroundColor: '#f31', + hidden: false, + borderCapStyle: 'round', + borderDash: [2, 2], + borderDashOffset: 5.5, + borderJoinStyle: 'round', + borderWidth: 0, + borderColor: '#f31', + pointStyle: 'crossRot', + pointBackgroundColor: 'rgba(0,0,0,0.1)', + pointBorderWidth: 5, + pointBorderColor: 'green', + data: [] + }], + labels: [] + }, + options: { + legend: { + labels: { + usePointStyle: true + } + } + } + }); + + expect(chart.legend.legendItems).toEqual([{ + text: 'dataset1', + fillStyle: 'rgba(0,0,0,0.1)', + hidden: false, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 5, + strokeStyle: 'green', + pointStyle: 'crossRot', + datasetIndex: 0 + }]); + }); + describe('config update', function() { it ('should update the options', function() { var chart = acquireChart({