From: Evert Timberg Date: Tue, 6 Oct 2020 02:15:38 +0000 (-0400) Subject: Enable custom sorting of the legend items (#7851) X-Git-Tag: v3.0.0-beta.4~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=168965fa3899a19fc6acbb8863d8ac100b817b8e;p=thirdparty%2FChart.js.git Enable custom sorting of the legend items (#7851) --- diff --git a/docs/docs/configuration/legend.md b/docs/docs/configuration/legend.md index 3c6c897e0..ff6791d78 100644 --- a/docs/docs/configuration/legend.md +++ b/docs/docs/configuration/legend.md @@ -54,6 +54,7 @@ The legend label configuration is nested below the legend configuration using th | `padding` | `number` | `10` | Padding between rows of colored boxes. | `generateLabels` | `function` | | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. See [Legend Item](#legend-item-interface) for details. | `filter` | `function` | `null` | Filters legend items out of the legend. Receives 2 parameters, a [Legend Item](#legend-item-interface) and the chart data. +| `sort` | `function` | `null` | Sorts legend items. Receives 3 parameters, two [Legend Items](#legend-item-interface) and the chart data. | `usePointStyle` | `boolean` | `false` | Label style will match corresponding point style (size is based on the mimimum value between boxWidth and font.size). ## Legend Title Configuration diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 0bd8d1d1a..ac3902094 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -160,6 +160,10 @@ export class Legend extends Element { legendItems = legendItems.filter((item) => labelOpts.filter(item, me.chart.data)); } + if (labelOpts.sort) { + legendItems = legendItems.sort((a, b) => labelOpts.sort(a, b, me.chart.data)); + } + if (me.options.reverse) { legendItems.reverse(); } diff --git a/test/specs/plugin.legend.tests.js b/test/specs/plugin.legend.tests.js index bb1121f87..738e85167 100644 --- a/test/specs/plugin.legend.tests.js +++ b/test/specs/plugin.legend.tests.js @@ -311,6 +311,85 @@ describe('Legend block tests', function() { }]); }); + it('should sort items', 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', + fill: false, + data: [] + }], + labels: [] + }, + options: { + legend: { + labels: { + sort: function(a, b) { + return b.datasetIndex > a.datasetIndex ? 1 : -1; + } + } + } + } + }); + + expect(chart.legend.legendItems).toEqual([{ + text: 'dataset3', + fillStyle: 'rgba(0,0,0,0.1)', + hidden: false, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'miter', + lineWidth: 10, + strokeStyle: 'green', + pointStyle: undefined, + rotation: undefined, + datasetIndex: 2 + }, { + text: 'dataset2', + fillStyle: 'rgba(0,0,0,0.1)', + hidden: true, + lineCap: 'butt', + lineDash: [], + lineDashOffset: 0, + lineJoin: 'round', + lineWidth: 3, + strokeStyle: 'rgba(0,0,0,0.1)', + pointStyle: undefined, + rotation: undefined, + datasetIndex: 1 + }, { + text: 'dataset1', + fillStyle: '#f31', + hidden: false, + lineCap: 'round', + lineDash: [2, 2], + lineDashOffset: 5.5, + lineJoin: 'miter', + lineWidth: 3, + strokeStyle: 'rgba(0,0,0,0.1)', + pointStyle: undefined, + rotation: undefined, + datasetIndex: 0 + }]); + }); + it('should not throw when the label options are missing', function() { var makeChart = function() { window.acquireChart({ diff --git a/types/plugins/index.d.ts b/types/plugins/index.d.ts index efa0eda00..414d3f907 100644 --- a/types/plugins/index.d.ts +++ b/types/plugins/index.d.ts @@ -165,6 +165,11 @@ export interface ILegendOptions { */ filter(item: ILegendItem, data: IChartData): boolean; + /** + * Sorts the legend items + */ + sort(a: ILegendItem, b: ILegendItem, data: IChartData): number; + /** * Label style will match corresponding point style (size is based on the mimimum value between boxWidth and font.size). * @default false