From 09d50e774ad7968530b34088d35585a06136cefd Mon Sep 17 00:00:00 2001 From: Anthony Hendrickx Date: Fri, 27 Sep 2024 09:42:05 +0200 Subject: [PATCH 1/2] [IMP] charts: allow to reorder data series Task Description This task aims to add the possibility to reorder the ranges in the selection input, allowing then the user to change the order of the data series. Related Task Task: 3994495 --- src/components/icons/icons.xml | 7 +++ .../selection_input/selection_input.ts | 45 +++++++++++++++++++ .../selection_input/selection_input.xml | 10 ++++- .../bar_chart/bar_chart_config_panel.xml | 1 + .../data_series/data_series.ts | 2 + .../data_series/data_series.xml | 1 + .../generic_side_panel/config_panel.ts | 25 +++++++---- .../generic_side_panel/config_panel.xml | 1 + .../line_chart/line_chart_config_panel.xml | 1 + .../scatter_chart_config_panel.xml | 1 + tests/figures/chart/charts_component.test.ts | 39 ++++++++++++++++ .../spreadsheet_pivot_side_panel.test.ts.snap | 2 + .../__snapshots__/data_series.test.ts.snap | 1 + .../__snapshots__/label_range.test.ts.snap | 2 + 14 files changed, 128 insertions(+), 10 deletions(-) diff --git a/src/components/icons/icons.xml b/src/components/icons/icons.xml index 4305754246..cfe6394ced 100644 --- a/src/components/icons/icons.xml +++ b/src/components/icons/icons.xml @@ -841,6 +841,13 @@ + + + + + + + void; + onSelectionReordered?: (indexes: number[]) => void; onSelectionConfirmed?: () => void; colors?: Color[]; } @@ -73,13 +78,16 @@ export class SelectionInput extends Component { class: { type: String, optional: true }, onSelectionChanged: { type: Function, optional: true }, onSelectionConfirmed: { type: Function, optional: true }, + onSelectionReordered: { type: Function, optional: true }, colors: { type: Array, optional: true, default: [] }, }; private state: State = useState({ isMissing: false, mode: "select-range", }); + private dragAndDrop = useDragAndDropListItems(); private focusedInput = useRef("focusedInput"); + private selectionRef = useRef("o-selection"); private store!: Store; get ranges(): SelectionRange[] { @@ -126,6 +134,43 @@ export class SelectionInput extends Component { }); } + startDragAndDrop(rangeId: number, event: MouseEvent) { + if (event.button !== 0 || (event.target as HTMLElement).tagName === "SELECT") { + return; + } + + const rects = this.getRangeElementsRects(); + const draggableIds = this.ranges.map((range) => range.id); + const draggableItems = draggableIds.map((id, index) => ({ + id: id.toString(), + size: rects[index].height, + position: rects[index].y, + })); + this.dragAndDrop.start("vertical", { + draggedItemId: rangeId.toString(), + initialMousePosition: event.clientY, + items: draggableItems, + containerEl: this.selectionRef.el!, + onDragEnd: (dimensionName, finalIndex) => { + const originalIndex = draggableIds.findIndex((id) => id === rangeId); + if (originalIndex === finalIndex) { + return; + } + const draggedItems = [...draggableIds]; + draggedItems.splice(originalIndex, 1); + draggedItems.splice(finalIndex, 0, rangeId); + this.props.onSelectionReordered?.( + this.store.selectionInputs.map((range) => draggedItems.indexOf(range.id)) + ); + this.props.onSelectionConfirmed?.(); + }, + }); + } + + getRangeElementsRects() { + return Array.from(this.selectionRef.el!.children).map((el) => el.getBoundingClientRect()); + } + getColor(range: SelectionRange) { if (!range.color) { return ""; diff --git a/src/components/selection_input/selection_input.xml b/src/components/selection_input/selection_input.xml index f4e109640c..839bdd8330 100644 --- a/src/components/selection_input/selection_input.xml +++ b/src/components/selection_input/selection_input.xml @@ -1,12 +1,20 @@ -
+
+ + +
void; + onSelectionReordered?: (indexes: number[]) => void; onSelectionConfirmed: () => void; } @@ -18,6 +19,7 @@ export class ChartDataSeries extends Component { ranges: Array, hasSingleRange: { type: Boolean, optional: true }, onSelectionChanged: Function, + onSelectionReordered: { type: Function, optional: true }, onSelectionConfirmed: Function, }; diff --git a/src/components/side_panel/chart/building_blocks/data_series/data_series.xml b/src/components/side_panel/chart/building_blocks/data_series/data_series.xml index e520373a44..a80ab6fe00 100644 --- a/src/components/side_panel/chart/building_blocks/data_series/data_series.xml +++ b/src/components/side_panel/chart/building_blocks/data_series/data_series.xml @@ -7,6 +7,7 @@ hasSingleRange="props.hasSingleRange" onSelectionChanged="(ranges) => props.onSelectionChanged(ranges)" onSelectionConfirmed="() => props.onSelectionConfirmed()" + onSelectionReordered="(indexes) => props.onSelectionReordered(indexes)" colors="colors" /> diff --git a/src/components/side_panel/chart/building_blocks/generic_side_panel/config_panel.ts b/src/components/side_panel/chart/building_blocks/generic_side_panel/config_panel.ts index e330a55bb1..c4bebbd042 100644 --- a/src/components/side_panel/chart/building_blocks/generic_side_panel/config_panel.ts +++ b/src/components/side_panel/chart/building_blocks/generic_side_panel/config_panel.ts @@ -53,13 +53,13 @@ export class GenericChartConfigPanel extends Component ({ - ...this.dataSeriesRanges?.[i], + this.dataSets = ranges.map((dataRange, i) => ({ + ...this.dataSets?.[i], dataRange, })); this.state.datasetDispatchResult = this.props.canUpdateChart(this.props.figureId, { - dataSets: this.dataSeriesRanges, + dataSets: this.dataSets, + }); + } + + onDataSeriesReordered(indexes: number[]) { + this.dataSets = indexes.map((i) => this.dataSets[i]); + this.state.datasetDispatchResult = this.props.updateChart(this.props.figureId, { + dataSets: this.dataSets, }); } onDataSeriesConfirmed() { - this.dataSeriesRanges = spreadRange(this.env.model.getters, this.dataSeriesRanges); + this.dataSets = spreadRange(this.env.model.getters, this.dataSets); this.state.datasetDispatchResult = this.props.updateChart(this.props.figureId, { - dataSets: this.dataSeriesRanges, + dataSets: this.dataSets, }); } getDataSeriesRanges() { - return this.dataSeriesRanges; + return this.dataSets; } /** @@ -169,7 +176,7 @@ export class GenericChartConfigPanel extends Component { } }); + test("can reorder ranges in chart panel", async () => { + mockGetBoundingClientRect({ + "o-selection-input": (el: HTMLElement) => ({ + y: Array.from(el.parentElement!.children).indexOf(el) * 100, + height: 100, + }), + "o-selection": (el: HTMLElement) => ({ + y: 0, + height: 200, + }), + }); + createChart( + model, + { + dataSets: [ + { dataRange: "B1:B4", label: "serie_1" }, + { dataRange: "C1:C4", label: "serie_2" }, + ], + labelRange: "A2:A4", + type: "line", + }, + chartId + ); + await mountSpreadsheet(); + await openChartConfigSidePanel(model, env, chartId); + await dragElement( + fixture.querySelectorAll(".o-selection-input")[0], + { x: 0, y: 150 }, + undefined, + true + ); + const definition = model.getters.getChartDefinition(chartId) as LineChartDefinition; + expect(definition.dataSets).toMatchObject([ + { dataRange: "C1:C4", label: "serie_2" }, + { dataRange: "B1:B4", label: "serie_1" }, + ]); + }); + test("drawing of chart will receive new data after update", async () => { createTestChart("basicChart"); await mountSpreadsheet(); diff --git a/tests/pivots/spreadsheet_pivot/__snapshots__/spreadsheet_pivot_side_panel.test.ts.snap b/tests/pivots/spreadsheet_pivot/__snapshots__/spreadsheet_pivot_side_panel.test.ts.snap index f9e085fc70..94eb5e3331 100644 --- a/tests/pivots/spreadsheet_pivot/__snapshots__/spreadsheet_pivot_side_panel.test.ts.snap +++ b/tests/pivots/spreadsheet_pivot/__snapshots__/spreadsheet_pivot_side_panel.test.ts.snap @@ -113,6 +113,7 @@ exports[`Spreadsheet pivot side panel It should correctly be displayed 1`] = `
+
@@ -327,6 +328,7 @@ exports[`Spreadsheet pivot side panel It should display only the selection input
+
diff --git a/tests/side_panels/building_blocks/__snapshots__/data_series.test.ts.snap b/tests/side_panels/building_blocks/__snapshots__/data_series.test.ts.snap index f9d615adda..ac49172e45 100644 --- a/tests/side_panels/building_blocks/__snapshots__/data_series.test.ts.snap +++ b/tests/side_panels/building_blocks/__snapshots__/data_series.test.ts.snap @@ -19,6 +19,7 @@ exports[`Data Series Can render a data series component 1`] = `
+
diff --git a/tests/side_panels/building_blocks/__snapshots__/label_range.test.ts.snap b/tests/side_panels/building_blocks/__snapshots__/label_range.test.ts.snap index 9eaa90800a..1d0a21252b 100644 --- a/tests/side_panels/building_blocks/__snapshots__/label_range.test.ts.snap +++ b/tests/side_panels/building_blocks/__snapshots__/label_range.test.ts.snap @@ -19,6 +19,7 @@ exports[`Label range Can add options to the label range component 1`] = `
+
@@ -78,6 +79,7 @@ exports[`Label range Can render a label range component 1`] = `
+
From b76a39028b6ba765b3809f99ab8f44784969ebfe Mon Sep 17 00:00:00 2001 From: Anthony Hendrickx Date: Fri, 27 Sep 2024 10:18:55 +0200 Subject: [PATCH 2/2] [REM] charts: remove unused combo chart config panel Task: 3994495 --- .../combo_chart/combo_chart_config_panel.ts | 5 ----- .../combo_chart/combo_chart_config_panel.xml | 20 ------------------- 2 files changed, 25 deletions(-) delete mode 100644 src/components/side_panel/chart/combo_chart/combo_chart_config_panel.ts delete mode 100644 src/components/side_panel/chart/combo_chart/combo_chart_config_panel.xml diff --git a/src/components/side_panel/chart/combo_chart/combo_chart_config_panel.ts b/src/components/side_panel/chart/combo_chart/combo_chart_config_panel.ts deleted file mode 100644 index b2a0eb2235..0000000000 --- a/src/components/side_panel/chart/combo_chart/combo_chart_config_panel.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { GenericChartConfigPanel } from "../building_blocks/generic_side_panel/config_panel"; - -export class ComboChartConfigPanel extends GenericChartConfigPanel { - static template = "o-spreadsheet-ComboChartConfigPanel"; -} diff --git a/src/components/side_panel/chart/combo_chart/combo_chart_config_panel.xml b/src/components/side_panel/chart/combo_chart/combo_chart_config_panel.xml deleted file mode 100644 index 62663949d4..0000000000 --- a/src/components/side_panel/chart/combo_chart/combo_chart_config_panel.xml +++ /dev/null @@ -1,20 +0,0 @@ - - -
- - - - -
-
-