From 5f8d6899d229ffd8b466d8fca02c00bf67cbad3c Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Wed, 7 Feb 2024 19:35:19 +0100 Subject: [PATCH] Plot legends expand by default when enabled (#7453) * expanded legend showing, but malformed * fix legends * add e2e test and aria labels for controls * fix tests * remove focused test * make plot legend items dynamic * expand legend immediately when changing default * Ensure stacked plots show cumulative legend (#7481) * simplify config loading logic * wip * fixed stacked plot legend issue * fix legend * remove console.debugs * remove extraneous prop * add test * fix legend * use props --- .cspell.json | 2 +- .../plugins/plot/overlayPlot.e2e.spec.js | 60 ++++++++++ .../plugins/plot/stackedPlot.e2e.spec.js | 50 ++++++++ src/plugins/persistence/couch/plugin.js | 12 +- src/plugins/plot/configuration/XAxisModel.js | 2 +- .../plot/inspector/PlotOptionsBrowse.vue | 22 ++-- .../plot/inspector/PlotOptionsItem.vue | 3 +- .../plot/inspector/forms/LegendForm.vue | 23 +++- .../plot/inspector/forms/SeriesForm.vue | 3 +- src/plugins/plot/legend/PlotLegend.vue | 47 +++++++- .../plot/legend/PlotLegendItemCollapsed.vue | 85 +++++++++---- .../plot/legend/PlotLegendItemExpanded.vue | 88 ++++++++++---- src/plugins/plot/pluginSpec.js | 1 + .../plot/stackedPlot/StackedPlotItem.vue | 112 +++++++++--------- src/plugins/plot/stackedPlot/pluginSpec.js | 4 +- src/styles/_legacy-plots.scss | 7 -- 16 files changed, 380 insertions(+), 141 deletions(-) diff --git a/.cspell.json b/.cspell.json index 7769756a3d..9afde5db7c 100644 --- a/.cspell.json +++ b/.cspell.json @@ -493,7 +493,7 @@ "WCAG", "stackedplot", "Andale", - "unnnormalized", + "unnormalized", "checksnapshots", "specced", "composables", diff --git a/e2e/tests/functional/plugins/plot/overlayPlot.e2e.spec.js b/e2e/tests/functional/plugins/plot/overlayPlot.e2e.spec.js index 7a6c2a5808..54c76aae97 100644 --- a/e2e/tests/functional/plugins/plot/overlayPlot.e2e.spec.js +++ b/e2e/tests/functional/plugins/plot/overlayPlot.e2e.spec.js @@ -63,6 +63,66 @@ test.describe('Overlay Plot', () => { await expect(seriesColorSwatch).toHaveCSS('background-color', 'rgb(255, 166, 61)'); }); + test('Plot legend expands by default', async ({ page }) => { + test.info().annotations.push({ + type: 'issue', + description: 'https://github.com/nasa/openmct/issues/7403' + }); + const overlayPlot = await createDomainObjectWithDefaults(page, { + type: 'Overlay Plot' + }); + + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: overlayPlot.uuid + }); + + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: overlayPlot.uuid + }); + + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: overlayPlot.uuid + }); + + await page.goto(overlayPlot.url); + + await page.getByRole('tab', { name: 'Config' }).click(); + + // Assert that the legend is collapsed by default + await expect(page.getByLabel('Plot Legend Collapsed')).toBeVisible(); + await expect(page.getByLabel('Plot Legend Expanded')).toBeHidden(); + await expect(page.getByLabel('Expand by Default')).toHaveText('No'); + + expect(await page.getByLabel('Plot Legend Item').count()).toBe(3); + + // Change the legend to expand by default + await page.getByLabel('Edit Object').click(); + await page.getByLabel('Expand By Default').check(); + await page.getByLabel('Save').click(); + await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); + // Assert that the legend is now open + await expect(page.getByLabel('Plot Legend Collapsed')).toBeHidden(); + await expect(page.getByLabel('Plot Legend Expanded')).toBeVisible(); + await expect(page.getByRole('cell', { name: 'Name' })).toBeVisible(); + await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible(); + await expect(page.getByRole('cell', { name: 'Value' })).toBeVisible(); + await expect(page.getByLabel('Expand by Default')).toHaveText('Yes'); + await expect(page.getByLabel('Plot Legend Item')).toHaveCount(3); + + // Assert that the legend is expanded on page load + await page.reload(); + await expect(page.getByLabel('Plot Legend Collapsed')).toBeHidden(); + await expect(page.getByLabel('Plot Legend Expanded')).toBeVisible(); + await expect(page.getByRole('cell', { name: 'Name' })).toBeVisible(); + await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible(); + await expect(page.getByRole('cell', { name: 'Value' })).toBeVisible(); + await expect(page.getByLabel('Expand by Default')).toHaveText('Yes'); + await expect(page.getByLabel('Plot Legend Item')).toHaveCount(3); + }); + test('Limit lines persist when series is moved to another Y Axis and on refresh', async ({ page }) => { diff --git a/e2e/tests/functional/plugins/plot/stackedPlot.e2e.spec.js b/e2e/tests/functional/plugins/plot/stackedPlot.e2e.spec.js index 81458e8154..3cffb3b28c 100644 --- a/e2e/tests/functional/plugins/plot/stackedPlot.e2e.spec.js +++ b/e2e/tests/functional/plugins/plot/stackedPlot.e2e.spec.js @@ -257,6 +257,56 @@ test.describe('Stacked Plot', () => { await assertAggregateLegendIsVisible(page); }); + + test('can toggle between aggregate and per child legends', async ({ page }) => { + // make some an overlay plot + const overlayPlot = await createDomainObjectWithDefaults(page, { + type: 'Overlay Plot', + parent: stackedPlot.uuid + }); + + // make some SWGs for the overlay plot + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: overlayPlot.uuid + }); + await createDomainObjectWithDefaults(page, { + type: 'Sine Wave Generator', + parent: overlayPlot.uuid + }); + + await page.goto(stackedPlot.url); + await page.getByLabel('Edit Object').click(); + await page.getByRole('tab', { name: 'Config' }).click(); + await page.getByLabel('Inspector Views').getByRole('checkbox').uncheck(); + await page.getByLabel('Expand By Default').check(); + await page.getByLabel('Save').click(); + await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); + await expect(page.getByLabel('Plot Legend Expanded')).toHaveCount(1); + await expect(page.getByLabel('Plot Legend Item')).toHaveCount(5); + + // reload and ensure the legend is still expanded + await page.reload(); + await expect(page.getByLabel('Plot Legend Expanded')).toHaveCount(1); + await expect(page.getByLabel('Plot Legend Item')).toHaveCount(5); + + // change to collapsed by default + await page.getByLabel('Edit Object').click(); + await page.getByLabel('Expand By Default').uncheck(); + await page.getByLabel('Save').click(); + await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); + await expect(page.getByLabel('Plot Legend Collapsed')).toHaveCount(1); + await expect(page.getByLabel('Plot Legend Item')).toHaveCount(5); + + // change it to individual legends + await page.getByLabel('Edit Object').click(); + await page.getByRole('tab', { name: 'Config' }).click(); + await page.getByLabel('Show Legends For Children').check(); + await page.getByLabel('Save').click(); + await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); + await expect(page.getByLabel('Plot Legend Collapsed')).toHaveCount(4); + await expect(page.getByLabel('Plot Legend Item')).toHaveCount(5); + }); }); /** diff --git a/src/plugins/persistence/couch/plugin.js b/src/plugins/persistence/couch/plugin.js index a1c7f6c661..09f5c7306f 100644 --- a/src/plugins/persistence/couch/plugin.js +++ b/src/plugins/persistence/couch/plugin.js @@ -28,9 +28,9 @@ const DEFAULT_NAMESPACE = ''; const LEGACY_SPACE = 'mct'; export default function CouchPlugin(options) { - function normalizeOptions(unnnormalizedOptions) { + function normalizeOptions(unnormalizedOptions) { const normalizedOptions = {}; - if (typeof unnnormalizedOptions === 'string') { + if (typeof unnormalizedOptions === 'string') { normalizedOptions.databases = [ { url: options, @@ -41,19 +41,19 @@ export default function CouchPlugin(options) { indicator: true } ]; - } else if (!unnnormalizedOptions.databases) { + } else if (!unnormalizedOptions.databases) { normalizedOptions.databases = [ { - url: unnnormalizedOptions.url, + url: unnormalizedOptions.url, namespace: DEFAULT_NAMESPACE, additionalNamespaces: [LEGACY_SPACE], readOnly: false, - useDesignDocuments: unnnormalizedOptions.useDesignDocuments, + useDesignDocuments: unnormalizedOptions.useDesignDocuments, indicator: true } ]; } else { - normalizedOptions.databases = unnnormalizedOptions.databases; + normalizedOptions.databases = unnormalizedOptions.databases; } // final sanity check, ensure we have all options diff --git a/src/plugins/plot/configuration/XAxisModel.js b/src/plugins/plot/configuration/XAxisModel.js index e1811ff15a..ff1b2b088b 100644 --- a/src/plugins/plot/configuration/XAxisModel.js +++ b/src/plugins/plot/configuration/XAxisModel.js @@ -94,7 +94,7 @@ export default class XAxisModel extends Model { */ defaultModel(options) { const bounds = options.openmct.time.bounds(); - const timeSystem = options.openmct.time.timeSystem(); + const timeSystem = options.openmct.time.getTimeSystem(); const format = options.openmct.telemetry.getFormatter(timeSystem.timeFormat); /** @type {XAxisModelType} */ diff --git a/src/plugins/plot/inspector/PlotOptionsBrowse.vue b/src/plugins/plot/inspector/PlotOptionsBrowse.vue index 2f17db9417..68fe0e9462 100644 --- a/src/plugins/plot/inspector/PlotOptionsBrowse.vue +++ b/src/plugins/plot/inspector/PlotOptionsBrowse.vue @@ -79,7 +79,7 @@
{{ showLegendsForChildren ? 'Yes' : 'No' }}
-
  • +
  • {{ position }}
  • -
  • +
  • Hide when plot small
    {{ hideLegendWhenSmall ? 'Yes' : 'No' }}
  • -
  • +
  • Expand by Default
    -
    {{ expandByDefault ? 'Yes' : 'No' }}
    +
    + {{ expandByDefault ? 'Yes' : 'No' }} +
  • -
  • +
  • Show when collapsed:
    {{ valueToShowWhenCollapsed.replace('nearest', '') }}
  • -
  • +
  • Show when expanded:
    @@ -164,6 +166,11 @@ export default { pathObjIndex === 0 && pathObject.type === 'telemetry.plot.stacked' ); }, + showLegendDetails() { + return ( + !this.isStackedPlotObject || (this.isStackedPlotObject && !this.showLegendsForChildren) + ); + }, yAxesWithSeries() { return this.yAxes.filter((yAxis) => yAxis.seriesCount > 0); } @@ -174,9 +181,8 @@ export default { if (!this.isStackedPlotObject) { this.initYAxesConfiguration(); this.registerListeners(); - } else { - this.initLegendConfiguration(); } + this.initLegendConfiguration(); this.loaded = true; }, diff --git a/src/plugins/plot/inspector/PlotOptionsItem.vue b/src/plugins/plot/inspector/PlotOptionsItem.vue index c4b9ae00a5..ecfac6c35e 100644 --- a/src/plugins/plot/inspector/PlotOptionsItem.vue +++ b/src/plugins/plot/inspector/PlotOptionsItem.vue @@ -132,7 +132,8 @@ export default { }, data() { return { - expanded: false + expanded: false, + status: null }; }, computed: { diff --git a/src/plugins/plot/inspector/forms/LegendForm.vue b/src/plugins/plot/inspector/forms/LegendForm.vue index 92c4070e91..8099c731db 100644 --- a/src/plugins/plot/inspector/forms/LegendForm.vue +++ b/src/plugins/plot/inspector/forms/LegendForm.vue @@ -26,12 +26,13 @@
  • -
  • +
  • -
  • +
  • Hide when plot small
    @@ -59,15 +60,20 @@ />
  • -
  • +
  • Expand by default
    - +
  • -
  • +
  • When collapsed show
    @@ -82,7 +88,7 @@
  • -
  • +
  • When expanded show
    @@ -169,6 +175,11 @@ export default { (pathObject, pathObjIndex) => pathObjIndex === 0 && pathObject?.type === 'telemetry.plot.stacked' ); + }, + showLegendDetails() { + return ( + !this.isStackedPlotObject || (this.isStackedPlotObject && !this.showLegendsForChildren) + ); } }, mounted() { diff --git a/src/plugins/plot/inspector/forms/SeriesForm.vue b/src/plugins/plot/inspector/forms/SeriesForm.vue index 47707cab9f..031116c5ae 100644 --- a/src/plugins/plot/inspector/forms/SeriesForm.vue +++ b/src/plugins/plot/inspector/forms/SeriesForm.vue @@ -157,7 +157,8 @@ export default { limitLines: this.series.get('limitLines'), markerSize: this.series.get('markerSize'), validation: {}, - swatchActive: false + swatchActive: false, + status: null }; }, computed: { diff --git a/src/plugins/plot/legend/PlotLegend.vue b/src/plugins/plot/legend/PlotLegend.vue index 91ef69903d..e87325170e 100644 --- a/src/plugins/plot/legend/PlotLegend.vue +++ b/src/plugins/plot/legend/PlotLegend.vue @@ -30,12 +30,17 @@
    -
    +
    -
    +
    { + return series.keyString === keyStringToFind; + }); + return foundSeries; + }, + toggleLegend() { this.isLegendExpanded = !this.isLegendExpanded; this.legend.set('expanded', this.isLegendExpanded); this.$emit('expanded', this.isLegendExpanded); diff --git a/src/plugins/plot/legend/PlotLegendItemCollapsed.vue b/src/plugins/plot/legend/PlotLegendItemCollapsed.vue index ccb3cf2098..e45dbe0ba4 100644 --- a/src/plugins/plot/legend/PlotLegendItemCollapsed.vue +++ b/src/plugins/plot/legend/PlotLegendItemCollapsed.vue @@ -22,6 +22,7 @@