mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
Plots correctly use configuration set on the parent if they can't their own (#7770)
* For telemetry that cannot have it's own configuration, ensure that it is correct initialized by the parent. * stacked plot test checks that config properties for immutable telemetry points are applied correctly * add tab navigation to inspector tabs * add accessibility metadata to this component * Update title to be on the correct component. Add expand/collapse logic * clean up test * refactor: better a11y for plot forms, fix "expand by default" test, refactor out `plotActions.js` * a11y: aria label for plotOptionsItem * refactor(a11y): PlotOptionsBrowse structure to have better a11y * fixed tests * address comment * reverted to match previous commit --------- Co-authored-by: Hill, John (ARC-TI)[KBR Wyle Services, LLC] <john.c.hill@nasa.gov> Co-authored-by: Jesse Mazzella <jesse.d.mazzella@nasa.gov> Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
This commit is contained in:
parent
6983148aba
commit
db808b4d54
@ -26,7 +26,6 @@ Testsuite for plot autoscale.
|
|||||||
|
|
||||||
import { createDomainObjectWithDefaults } from '../../../../appActions.js';
|
import { createDomainObjectWithDefaults } from '../../../../appActions.js';
|
||||||
import { expect, test } from '../../../../pluginFixtures.js';
|
import { expect, test } from '../../../../pluginFixtures.js';
|
||||||
import { setUserDefinedMinAndMax, turnOffAutoscale } from './plotActions.js';
|
|
||||||
test.use({
|
test.use({
|
||||||
viewport: {
|
viewport: {
|
||||||
width: 1280,
|
width: 1280,
|
||||||
@ -62,9 +61,12 @@ test.describe('Autoscale', () => {
|
|||||||
await page.getByLabel('Edit Object').click();
|
await page.getByLabel('Edit Object').click();
|
||||||
|
|
||||||
await page.getByRole('tab', { name: 'Config' }).click();
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
await turnOffAutoscale(page);
|
|
||||||
|
|
||||||
await setUserDefinedMinAndMax(page, '-2', '2');
|
// turn off autoscale
|
||||||
|
await page.getByRole('checkbox', { name: 'Auto scale' }).uncheck();
|
||||||
|
|
||||||
|
await page.getByLabel('Y Axis 1 Minimum value').fill('-2');
|
||||||
|
await page.getByLabel('Y Axis 1 Maximum value').fill('2');
|
||||||
|
|
||||||
// save
|
// save
|
||||||
await page.click('button[title="Save"]');
|
await page.click('button[title="Save"]');
|
||||||
|
@ -91,7 +91,7 @@ test.describe('Overlay Plot', () => {
|
|||||||
// Assert that the legend is collapsed by default
|
// Assert that the legend is collapsed by default
|
||||||
await expect(page.getByLabel('Plot Legend Collapsed')).toBeVisible();
|
await expect(page.getByLabel('Plot Legend Collapsed')).toBeVisible();
|
||||||
await expect(page.getByLabel('Plot Legend Expanded')).toBeHidden();
|
await expect(page.getByLabel('Plot Legend Expanded')).toBeHidden();
|
||||||
await expect(page.getByLabel('Expand by Default')).toHaveText('No');
|
await expect(page.getByLabel('Expand by Default')).toHaveText(/No/);
|
||||||
|
|
||||||
expect(await page.getByLabel('Plot Legend Item').count()).toBe(3);
|
expect(await page.getByLabel('Plot Legend Item').count()).toBe(3);
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ test.describe('Overlay Plot', () => {
|
|||||||
await expect(page.getByRole('cell', { name: 'Name' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Name' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Value' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Value' })).toBeVisible();
|
||||||
await expect(page.getByLabel('Expand by Default')).toHaveText('Yes');
|
await expect(page.getByLabel('Expand by Default')).toHaveText(/Yes/);
|
||||||
await expect(page.getByLabel('Plot Legend Item')).toHaveCount(3);
|
await expect(page.getByLabel('Plot Legend Item')).toHaveCount(3);
|
||||||
|
|
||||||
// Assert that the legend is expanded on page load
|
// Assert that the legend is expanded on page load
|
||||||
@ -116,7 +116,7 @@ test.describe('Overlay Plot', () => {
|
|||||||
await expect(page.getByRole('cell', { name: 'Name' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Name' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Value' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Value' })).toBeVisible();
|
||||||
await expect(page.getByLabel('Expand by Default')).toHaveText('Yes');
|
await expect(page.getByLabel('Expand by Default')).toHaveText(/Yes/);
|
||||||
await expect(page.getByLabel('Plot Legend Item')).toHaveCount(3);
|
await expect(page.getByLabel('Plot Legend Item')).toHaveCount(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -144,15 +144,8 @@ test.describe('Overlay Plot', () => {
|
|||||||
|
|
||||||
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
||||||
await page.getByRole('tab', { name: 'Config' }).click();
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
await page
|
await page.getByLabel('Expand Sine Wave Generator:').click();
|
||||||
.getByRole('list', { name: 'Plot Series Properties' })
|
await page.getByLabel('Limit lines').check();
|
||||||
.locator('span')
|
|
||||||
.first()
|
|
||||||
.click();
|
|
||||||
await page
|
|
||||||
.getByRole('list', { name: 'Plot Series Properties' })
|
|
||||||
.locator('[title="Display limit lines"]~div input')
|
|
||||||
.check();
|
|
||||||
|
|
||||||
await assertLimitLinesExistAndAreVisible(page);
|
await assertLimitLinesExistAndAreVisible(page);
|
||||||
|
|
||||||
@ -215,21 +208,13 @@ test.describe('Overlay Plot', () => {
|
|||||||
|
|
||||||
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
// Expand the "Sine Wave Generator" plot series options and enable limit lines
|
||||||
await page.getByRole('tab', { name: 'Config' }).click();
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
await page
|
await page.getByLabel('Expand Sine Wave Generator:').click();
|
||||||
.getByRole('list', { name: 'Plot Series Properties' })
|
await page.getByLabel('Limit lines').check();
|
||||||
.locator('span')
|
|
||||||
.first()
|
|
||||||
.click();
|
|
||||||
await page
|
|
||||||
.getByRole('list', { name: 'Plot Series Properties' })
|
|
||||||
.getByRole('checkbox', { name: 'Limit lines' })
|
|
||||||
.check();
|
|
||||||
|
|
||||||
await assertLimitLinesExistAndAreVisible(page);
|
await assertLimitLinesExistAndAreVisible(page);
|
||||||
|
|
||||||
// Save (exit edit mode)
|
await page.getByRole('button', { name: 'Save' }).click();
|
||||||
await page.locator('button[title="Save"]').click();
|
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||||
await page.locator('li[title="Save and Finish Editing"]').click();
|
|
||||||
|
|
||||||
const initialCoords = await assertLimitLinesExistAndAreVisible(page);
|
const initialCoords = await assertLimitLinesExistAndAreVisible(page);
|
||||||
// Resize the chart container by showing the snapshot pane.
|
// Resize the chart container by showing the snapshot pane.
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2024, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
/**
|
|
||||||
* @param {import('@playwright/test').Page} page
|
|
||||||
*/
|
|
||||||
async function turnOffAutoscale(page) {
|
|
||||||
// uncheck autoscale
|
|
||||||
await page.getByRole('checkbox', { name: 'Auto scale' }).uncheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {import('@playwright/test').Page} page
|
|
||||||
* @param {string} min
|
|
||||||
* @param {string} max
|
|
||||||
*/
|
|
||||||
async function setUserDefinedMinAndMax(page, min, max) {
|
|
||||||
// set minimum value
|
|
||||||
await page.getByRole('spinbutton').first().fill(min);
|
|
||||||
// set maximum value
|
|
||||||
await page.getByRole('spinbutton').nth(1).fill(max);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { setUserDefinedMinAndMax, turnOffAutoscale };
|
|
@ -33,7 +33,6 @@ import {
|
|||||||
setStartOffset
|
setStartOffset
|
||||||
} from '../../../../appActions.js';
|
} from '../../../../appActions.js';
|
||||||
import { expect, test } from '../../../../pluginFixtures.js';
|
import { expect, test } from '../../../../pluginFixtures.js';
|
||||||
import { setUserDefinedMinAndMax, turnOffAutoscale } from './plotActions.js';
|
|
||||||
|
|
||||||
test.describe('Plot Controls', () => {
|
test.describe('Plot Controls', () => {
|
||||||
let overlayPlot;
|
let overlayPlot;
|
||||||
@ -78,9 +77,12 @@ test.describe('Plot Controls', () => {
|
|||||||
await page.getByLabel('Edit Object').click();
|
await page.getByLabel('Edit Object').click();
|
||||||
|
|
||||||
await page.getByRole('tab', { name: 'Config' }).click();
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
await turnOffAutoscale(page);
|
|
||||||
|
|
||||||
await setUserDefinedMinAndMax(page, '-1', '1');
|
// turn off autoscale
|
||||||
|
await page.getByRole('checkbox', { name: 'Auto scale' }).uncheck();
|
||||||
|
|
||||||
|
await page.getByLabel('Y Axis 1 Minimum value').fill('-1');
|
||||||
|
await page.getByLabel('Y Axis 1 Maximum value').fill('1');
|
||||||
|
|
||||||
// save
|
// save
|
||||||
await page.click('button[title="Save"]');
|
await page.click('button[title="Save"]');
|
||||||
|
@ -39,19 +39,23 @@ test.describe('Stacked Plot', () => {
|
|||||||
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
await page.goto('./', { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
stackedPlot = await createDomainObjectWithDefaults(page, {
|
stackedPlot = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Stacked Plot'
|
type: 'Stacked Plot',
|
||||||
|
name: 'Stacked Plot'
|
||||||
});
|
});
|
||||||
|
|
||||||
swgA = await createDomainObjectWithDefaults(page, {
|
swgA = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
|
name: 'Sine Wave Generator A',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
swgB = await createDomainObjectWithDefaults(page, {
|
swgB = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
|
name: 'Sine Wave Generator B',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
swgC = await createDomainObjectWithDefaults(page, {
|
swgC = await createDomainObjectWithDefaults(page, {
|
||||||
type: 'Sine Wave Generator',
|
type: 'Sine Wave Generator',
|
||||||
|
name: 'Sine Wave Generator C',
|
||||||
parent: stackedPlot.uuid
|
parent: stackedPlot.uuid
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -151,40 +155,80 @@ test.describe('Stacked Plot', () => {
|
|||||||
await page.getByRole('tab', { name: 'Config' }).click();
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
|
|
||||||
// Click on the 1st plot
|
// Click on the 1st plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"] canvas`).nth(1).click();
|
await page
|
||||||
|
.getByLabel('Stacked Plot Item Sine Wave Generator A')
|
||||||
|
.getByLabel('Plot Canvas')
|
||||||
|
.click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgA
|
// Assert that the inspector shows the Y Axis properties for swgA
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
await expect(page.getByRole('heading', { name: 'Plot Series' })).toBeVisible();
|
||||||
'Plot Series'
|
|
||||||
);
|
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
page.getByLabel('Inspector Views').getByText('Sine Wave Generator A', { exact: true })
|
||||||
).toContainText(swgA.name);
|
).toBeVisible();
|
||||||
|
|
||||||
// Click on the 2nd plot
|
// Click on the 2nd plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"] canvas`).nth(1).click();
|
await page
|
||||||
|
.getByLabel('Stacked Plot Item Sine Wave Generator B')
|
||||||
|
.getByLabel('Plot Canvas')
|
||||||
|
.click();
|
||||||
// Assert that the inspector shows the Y Axis properties for swgB
|
// Assert that the inspector shows the Y Axis properties for swgB
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
await expect(page.getByRole('heading', { name: 'Plot Series' })).toBeVisible();
|
||||||
'Plot Series'
|
|
||||||
);
|
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
page.getByLabel('Inspector Views').getByText('Sine Wave Generator B', { exact: true })
|
||||||
).toContainText(swgB.name);
|
).toBeVisible();
|
||||||
|
|
||||||
// Click on the 3rd plot
|
// Click on the 3rd plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"] canvas`).nth(1).click();
|
await page
|
||||||
|
.getByLabel('Stacked Plot Item Sine Wave Generator C')
|
||||||
// Assert that the inspector shows the Y Axis properties for swgC
|
.getByLabel('Plot Canvas')
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
.click();
|
||||||
'Plot Series'
|
// Assert that the inspector shows the Y Axis properties for swgB
|
||||||
);
|
await expect(page.getByRole('heading', { name: 'Plot Series' })).toBeVisible();
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
page.getByLabel('Inspector Views').getByText('Sine Wave Generator C', { exact: true })
|
||||||
).toContainText(swgC.name);
|
).toBeVisible();
|
||||||
|
|
||||||
|
// Go into edit mode
|
||||||
|
await page.getByLabel('Edit Object').click();
|
||||||
|
|
||||||
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
|
|
||||||
|
// Click on the 1st plot
|
||||||
|
await page.getByLabel('Stacked Plot Item Sine Wave Generator A').click();
|
||||||
|
|
||||||
|
// Assert that the inspector shows the Y Axis properties for swgA
|
||||||
|
await expect(page.getByRole('heading', { name: 'Plot Series' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.getByLabel('Inspector Views').getByText('Sine Wave Generator A', { exact: true })
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
// Click on the 2nd plot
|
||||||
|
await page.getByLabel('Stacked Plot Item Sine Wave Generator B').click();
|
||||||
|
|
||||||
|
// Assert that the inspector shows the Y Axis properties for swgB
|
||||||
|
await expect(page.getByRole('heading', { name: 'Plot Series' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.getByLabel('Inspector Views').getByText('Sine Wave Generator B', { exact: true })
|
||||||
|
).toBeVisible();
|
||||||
|
|
||||||
|
// Click on the 3rd plot
|
||||||
|
await page.getByLabel('Stacked Plot Item Sine Wave Generator C').click();
|
||||||
|
|
||||||
|
// Assert that the inspector shows the Y Axis properties for swgC
|
||||||
|
await expect(page.getByRole('heading', { name: 'Plot Series' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
page.getByLabel('Inspector Views').getByText('Sine Wave Generator C', { exact: true })
|
||||||
|
).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Changing properties of an immutable child plot are applied correctly', async ({ page }) => {
|
||||||
|
await page.goto(stackedPlot.url);
|
||||||
|
|
||||||
// Go into edit mode
|
// Go into edit mode
|
||||||
await page.getByLabel('Edit Object').click();
|
await page.getByLabel('Edit Object').click();
|
||||||
@ -192,40 +236,35 @@ test.describe('Stacked Plot', () => {
|
|||||||
await page.getByRole('tab', { name: 'Config' }).click();
|
await page.getByRole('tab', { name: 'Config' }).click();
|
||||||
|
|
||||||
// Click on canvas for the 1st plot
|
// Click on canvas for the 1st plot
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgA.name}"]`).click();
|
await page.getByLabel(`Stacked Plot Item ${swgA.name}`).click();
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgA
|
// Expand config for the series
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
await page.getByLabel('Expand Sine Wave Generator').click();
|
||||||
'Plot Series'
|
|
||||||
);
|
// turn off alarm markers
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
await page.getByLabel('Alarm Markers').uncheck();
|
||||||
|
|
||||||
|
// save
|
||||||
|
await page.getByRole('button', { name: 'Save' }).click();
|
||||||
|
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
|
||||||
|
|
||||||
|
// reload page and waitForPlotsToRender
|
||||||
|
await page.reload();
|
||||||
|
await waitForPlotsToRender(page);
|
||||||
|
|
||||||
|
// Click on canvas for the 1st plot
|
||||||
|
await page.getByLabel(`Stacked Plot Item ${swgA.name}`).click();
|
||||||
|
|
||||||
|
// Expand config for the series
|
||||||
|
//TODO Fix this locator
|
||||||
|
await page.getByLabel('Expand Sine Wave Generator A generator').click();
|
||||||
|
|
||||||
|
// Assert that alarm markers are still turned off
|
||||||
await expect(
|
await expect(
|
||||||
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
page
|
||||||
).toContainText(swgA.name);
|
.getByTitle('Display markers visually denoting points in alarm.')
|
||||||
|
.getByRole('cell', { name: 'Disabled' })
|
||||||
//Click on canvas for the 2nd plot
|
).toBeVisible();
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgB.name}"]`).click();
|
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgB
|
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
|
||||||
'Plot Series'
|
|
||||||
);
|
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
|
||||||
await expect(
|
|
||||||
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
|
||||||
).toContainText(swgB.name);
|
|
||||||
|
|
||||||
//Click on canvas for the 3rd plot
|
|
||||||
await page.locator(`[aria-label="Stacked Plot Item ${swgC.name}"]`).click();
|
|
||||||
|
|
||||||
// Assert that the inspector shows the Y Axis properties for swgC
|
|
||||||
await expect(page.locator('[aria-label="Plot Series Properties"] >> h2')).toContainText(
|
|
||||||
'Plot Series'
|
|
||||||
);
|
|
||||||
await expect(page.getByRole('heading', { name: 'Y Axis' })).toBeVisible();
|
|
||||||
await expect(
|
|
||||||
page.locator('[aria-label="Plot Series Properties"] .c-object-label')
|
|
||||||
).toContainText(swgC.name);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('the legend toggles between aggregate and per child', async ({ page }) => {
|
test('the legend toggles between aggregate and per child', async ({ page }) => {
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="c-tree__item menus-to-left" :class="aliasCss">
|
<li class="c-tree__item menus-to-left" :class="aliasCss" role="treeitem">
|
||||||
<span
|
<span
|
||||||
class="c-disclosure-triangle is-enabled flex-elem"
|
class="c-disclosure-triangle is-enabled flex-elem"
|
||||||
:class="expandedCssClass"
|
:class="expandedCssClass"
|
||||||
|
@ -20,109 +20,55 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div v-if="loaded" class="js-plot-options-browse">
|
<ul v-if="loaded" class="js-plot-options-browse" aria-label="Plot Configuration">
|
||||||
<ul v-if="!isStackedPlotObject" class="c-tree" aria-label="Plot Series Properties">
|
<li v-if="showPlotSeries" class="c-tree" aria-labelledby="plot-series-header">
|
||||||
<h2 class="--first" title="Plot series display properties in this object">Plot Series</h2>
|
<h2 id="plot-series-header" class="--first">Plot Series</h2>
|
||||||
<PlotOptionsItem v-for="series in plotSeries" :key="series.keyString" :series="series" />
|
<ul aria-label="Plot Series Items" class="l-inspector-part">
|
||||||
</ul>
|
<PlotOptionsItem v-for="series in plotSeries" :key="series.keyString" :series="series" />
|
||||||
<div v-if="plotSeries.length && !isStackedPlotObject" class="grid-properties">
|
</ul>
|
||||||
<ul
|
</li>
|
||||||
|
<ul v-if="showYAxisProperties" aria-label="Y Axes" class="l-inspector-part js-yaxis-properties">
|
||||||
|
<li
|
||||||
v-for="(yAxis, index) in yAxesWithSeries"
|
v-for="(yAxis, index) in yAxesWithSeries"
|
||||||
:key="`yAxis-${index}`"
|
:key="`yAxis-${index}`"
|
||||||
class="l-inspector-part js-yaxis-properties"
|
:aria-labelledby="getYAxisHeaderId(index)"
|
||||||
:aria-label="
|
|
||||||
yAxesWithSeries.length > 1 ? `Y Axis ${yAxis.id} Properties` : 'Y Axis Properties'
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<h2 title="Y axis settings for this object">
|
<h2 :id="getYAxisHeaderId(index)">
|
||||||
Y Axis {{ yAxesWithSeries.length > 1 ? yAxis.id : '' }}
|
Y Axis {{ yAxesWithSeries.length > 1 ? yAxis.id : '' }}
|
||||||
</h2>
|
</h2>
|
||||||
<li class="grid-row">
|
<ul class="grid-properties" :aria-label="`Y Axis ${yAxis.id} Properties`">
|
||||||
<div class="grid-cell label" title="Manually override how the Y axis is labeled.">
|
<li
|
||||||
Label
|
v-for="(prop, key) in yAxisProperties(yAxis)"
|
||||||
</div>
|
:key="key"
|
||||||
<div class="grid-cell value">{{ yAxis.label ? yAxis.label : 'Not defined' }}</div>
|
:aria-labelledby="getYAxisPropId(index, prop.label)"
|
||||||
</li>
|
class="grid-row"
|
||||||
<li class="grid-row">
|
role="grid"
|
||||||
<div class="grid-cell label" title="Enable log mode.">Log mode</div>
|
|
||||||
<div class="grid-cell value">
|
|
||||||
{{ yAxis.logMode ? 'Enabled' : 'Disabled' }}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="grid-row">
|
|
||||||
<div
|
|
||||||
class="grid-cell label"
|
|
||||||
title="Automatically scale the Y axis to keep all values in view."
|
|
||||||
>
|
>
|
||||||
Auto scale
|
<div
|
||||||
</div>
|
:id="getYAxisPropId(index, prop.label)"
|
||||||
<div class="grid-cell value">
|
class="grid-cell label"
|
||||||
{{ yAxis.autoscale ? 'Enabled: ' + yAxis.autoscalePadding : 'Disabled' }}
|
:title="prop.title"
|
||||||
</div>
|
role="gridcell"
|
||||||
</li>
|
>
|
||||||
<li v-if="!yAxis.autoscale && yAxis.rangeMin !== ''" class="grid-row">
|
{{ prop.label }}
|
||||||
<div class="grid-cell label" title="Minimum Y axis value.">Minimum value</div>
|
</div>
|
||||||
<div class="grid-cell value">{{ yAxis.rangeMin }}</div>
|
<div class="grid-cell value" role="gridcell">{{ prop.value }}</div>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="!yAxis.autoscale && yAxis.rangeMax !== ''" class="grid-row">
|
</ul>
|
||||||
<div class="grid-cell label" title="Maximum Y axis value.">Maximum value</div>
|
</li>
|
||||||
<div class="grid-cell value">{{ yAxis.rangeMax }}</div>
|
</ul>
|
||||||
</li>
|
<li v-if="showLegendProperties" class="grid-properties" aria-label="Legend Configuration">
|
||||||
</ul>
|
<ul class="l-inspector-part js-legend-properties" aria-labelledby="legend-header">
|
||||||
</div>
|
<h2 id="legend-header" class="--first">Legend</h2>
|
||||||
<div v-if="isStackedPlotObject || !isNestedWithinAStackedPlot" class="grid-properties">
|
<li v-for="(prop, key) in legendProperties" :key="key" class="grid-row">
|
||||||
<ul class="l-inspector-part js-legend-properties">
|
<div class="u-contents" :aria-label="prop.label">
|
||||||
<h2 class="--first" title="Legend settings for this object">Legend</h2>
|
<div class="grid-cell label" :title="prop.title">{{ prop.label }}</div>
|
||||||
<li v-if="isStackedPlotObject" class="grid-row">
|
<div class="grid-cell value" :class="prop.class">{{ prop.value }}</div>
|
||||||
<div class="grid-cell label" title="Display legends per sub plot.">
|
|
||||||
Show legend per plot
|
|
||||||
</div>
|
|
||||||
<div class="grid-cell value">{{ showLegendsForChildren ? 'Yes' : 'No' }}</div>
|
|
||||||
</li>
|
|
||||||
<li v-if="showLegendDetails" class="grid-row">
|
|
||||||
<div
|
|
||||||
class="grid-cell label"
|
|
||||||
title="The position of the legend relative to the plot display area."
|
|
||||||
>
|
|
||||||
Position
|
|
||||||
</div>
|
|
||||||
<div class="grid-cell value capitalize">{{ position }}</div>
|
|
||||||
</li>
|
|
||||||
<li v-if="showLegendDetails" class="grid-row">
|
|
||||||
<div class="grid-cell label" title="Hide the legend when the plot is small">
|
|
||||||
Hide when plot small
|
|
||||||
</div>
|
|
||||||
<div class="grid-cell value">{{ hideLegendWhenSmall ? 'Yes' : 'No' }}</div>
|
|
||||||
</li>
|
|
||||||
<li v-if="showLegendDetails" class="grid-row">
|
|
||||||
<div class="grid-cell label" title="Show the legend expanded by default">
|
|
||||||
Expand by Default
|
|
||||||
</div>
|
|
||||||
<div aria-label="Expand by Default" class="grid-cell value">
|
|
||||||
{{ expandByDefault ? 'Yes' : 'No' }}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li v-if="showLegendDetails" class="grid-row">
|
|
||||||
<div class="grid-cell label" title="What to display in the legend when it's collapsed.">
|
|
||||||
Show when collapsed:
|
|
||||||
</div>
|
|
||||||
<div class="grid-cell value">{{ valueToShowWhenCollapsed.replace('nearest', '') }}</div>
|
|
||||||
</li>
|
|
||||||
<li v-if="showLegendDetails" class="grid-row">
|
|
||||||
<div class="grid-cell label" title="What to display in the legend when it's expanded.">
|
|
||||||
Show when expanded:
|
|
||||||
</div>
|
|
||||||
<div class="grid-cell value comma-list">
|
|
||||||
<span v-if="showTimestampWhenExpanded">Timestamp</span>
|
|
||||||
<span v-if="showValueWhenExpanded">Value</span>
|
|
||||||
<span v-if="showMinimumWhenExpanded">Min</span>
|
|
||||||
<span v-if="showMaximumWhenExpanded">Max</span>
|
|
||||||
<span v-if="showUnitsWhenExpanded">Unit</span>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -173,6 +119,60 @@ export default {
|
|||||||
},
|
},
|
||||||
yAxesWithSeries() {
|
yAxesWithSeries() {
|
||||||
return this.yAxes.filter((yAxis) => yAxis.seriesCount > 0);
|
return this.yAxes.filter((yAxis) => yAxis.seriesCount > 0);
|
||||||
|
},
|
||||||
|
showPlotSeries() {
|
||||||
|
return !this.isStackedPlotObject;
|
||||||
|
},
|
||||||
|
showYAxisProperties() {
|
||||||
|
return this.plotSeries.length && !this.isStackedPlotObject;
|
||||||
|
},
|
||||||
|
showLegendProperties() {
|
||||||
|
return this.isStackedPlotObject || !this.isNestedWithinAStackedPlot;
|
||||||
|
},
|
||||||
|
legendProperties() {
|
||||||
|
const props = {};
|
||||||
|
|
||||||
|
if (this.isStackedPlotObject) {
|
||||||
|
props.showLegendsForChildren = {
|
||||||
|
label: 'Show legend per plot',
|
||||||
|
title: 'Display legends per sub plot.',
|
||||||
|
value: this.showLegendsForChildren ? 'Yes' : 'No'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.showLegendDetails) {
|
||||||
|
Object.assign(props, {
|
||||||
|
position: {
|
||||||
|
label: 'Position',
|
||||||
|
title: 'The position of the legend relative to the plot display area.',
|
||||||
|
value: this.position,
|
||||||
|
class: 'capitalize'
|
||||||
|
},
|
||||||
|
hideLegendWhenSmall: {
|
||||||
|
label: 'Hide when plot small',
|
||||||
|
title: 'Hide the legend when the plot is small',
|
||||||
|
value: this.hideLegendWhenSmall ? 'Yes' : 'No'
|
||||||
|
},
|
||||||
|
expandByDefault: {
|
||||||
|
label: 'Expand by Default',
|
||||||
|
title: 'Show the legend expanded by default',
|
||||||
|
value: this.expandByDefault ? 'Yes' : 'No'
|
||||||
|
},
|
||||||
|
valueToShowWhenCollapsed: {
|
||||||
|
label: 'Show when collapsed:',
|
||||||
|
title: "What to display in the legend when it's collapsed.",
|
||||||
|
value: this.valueToShowWhenCollapsed.replace('nearest', '')
|
||||||
|
},
|
||||||
|
expandedValues: {
|
||||||
|
label: 'Show when expanded:',
|
||||||
|
title: "What to display in the legend when it's expanded.",
|
||||||
|
value: this.getExpandedValues(),
|
||||||
|
class: 'comma-list'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -282,6 +282,76 @@ export default {
|
|||||||
if (foundYAxis) {
|
if (foundYAxis) {
|
||||||
foundYAxis.seriesCount = foundYAxis.seriesCount + updateCount;
|
foundYAxis.seriesCount = foundYAxis.seriesCount + updateCount;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
getYAxisHeaderId(index) {
|
||||||
|
return `yAxis-${index}-header`;
|
||||||
|
},
|
||||||
|
|
||||||
|
getYAxisPropId(index, label) {
|
||||||
|
return `y-axis-${index}-${label.toLowerCase().replace(' ', '-')}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
yAxisAriaLabel(yAxis) {
|
||||||
|
return this.yAxesWithSeries.length > 1
|
||||||
|
? `Y Axis ${yAxis.id} Properties`
|
||||||
|
: 'Y Axis Properties';
|
||||||
|
},
|
||||||
|
yAxisProperties(yAxis) {
|
||||||
|
const props = {
|
||||||
|
label: {
|
||||||
|
label: 'Label',
|
||||||
|
title: 'Manually override how the Y axis is labeled.',
|
||||||
|
value: yAxis.label ? yAxis.label : 'Not defined'
|
||||||
|
},
|
||||||
|
logMode: {
|
||||||
|
label: 'Log mode',
|
||||||
|
title: 'Enable log mode.',
|
||||||
|
value: yAxis.logMode ? 'Enabled' : 'Disabled'
|
||||||
|
},
|
||||||
|
autoscale: {
|
||||||
|
label: 'Auto scale',
|
||||||
|
title: 'Automatically scale the Y axis to keep all values in view.',
|
||||||
|
value: yAxis.autoscale ? `Enabled: ${yAxis.autoscalePadding}` : 'Disabled'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!yAxis.autoscale) {
|
||||||
|
if (yAxis.rangeMin !== '') {
|
||||||
|
props.rangeMin = {
|
||||||
|
label: 'Minimum value',
|
||||||
|
title: 'Minimum Y axis value.',
|
||||||
|
value: yAxis.rangeMin
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (yAxis.rangeMax !== '') {
|
||||||
|
props.rangeMax = {
|
||||||
|
label: 'Maximum value',
|
||||||
|
title: 'Maximum Y axis value.',
|
||||||
|
value: yAxis.rangeMax
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
},
|
||||||
|
getExpandedValues() {
|
||||||
|
const values = [];
|
||||||
|
if (this.showTimestampWhenExpanded) {
|
||||||
|
values.push('Timestamp');
|
||||||
|
}
|
||||||
|
if (this.showValueWhenExpanded) {
|
||||||
|
values.push('Value');
|
||||||
|
}
|
||||||
|
if (this.showMinimumWhenExpanded) {
|
||||||
|
values.push('Min');
|
||||||
|
}
|
||||||
|
if (this.showMaximumWhenExpanded) {
|
||||||
|
values.push('Max');
|
||||||
|
}
|
||||||
|
if (this.showUnitsWhenExpanded) {
|
||||||
|
values.push('Unit');
|
||||||
|
}
|
||||||
|
return values.join(', ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div v-if="loaded" class="js-plot-options-edit">
|
<div v-if="loaded" class="js-plot-options-edit">
|
||||||
<ul v-if="!isStackedPlotObject" class="c-tree" aria-label="Plot Series Properties">
|
<ul v-if="!isStackedPlotObject" class="c-tree" role="tree">
|
||||||
<h2 class="--first" title="Display properties for this object">Plot Series</h2>
|
<h2 class="--first" title="Display properties for this Plot Series object">Plot Series</h2>
|
||||||
<li v-for="series in plotSeries" :key="series.keyString">
|
<li v-for="series in plotSeries" :key="series.keyString">
|
||||||
<series-form :series="series" @series-updated="updateSeriesConfigForObject" />
|
<series-form :series="series" @series-updated="updateSeriesConfigForObject" />
|
||||||
</li>
|
</li>
|
||||||
@ -33,15 +33,18 @@
|
|||||||
:key="`yAxis-${index}`"
|
:key="`yAxis-${index}`"
|
||||||
class="grid-properties js-yaxis-grid-properties"
|
class="grid-properties js-yaxis-grid-properties"
|
||||||
:y-axis="config.yAxis"
|
:y-axis="config.yAxis"
|
||||||
|
role="group"
|
||||||
|
aria-labelledby="y-axis-group"
|
||||||
@series-updated="updateSeriesConfigForObject"
|
@series-updated="updateSeriesConfigForObject"
|
||||||
/>
|
/>
|
||||||
<ul
|
<ul
|
||||||
v-if="isStackedPlotObject || !isStackedPlotNestedObject"
|
v-if="isStackedPlotObject || !isStackedPlotNestedObject"
|
||||||
class="l-inspector-part"
|
class="l-inspector-part"
|
||||||
aria-label="Legend Properties"
|
aria-label="Legend Properties"
|
||||||
|
role="tree"
|
||||||
>
|
>
|
||||||
<h2 class="--first" title="Legend options">Legend</h2>
|
<h2 class="--first" title="Legend options">Legend</h2>
|
||||||
<legend-form class="grid-properties" :legend="config.legend" />
|
<legend-form role="treeitem" tabindex="0" class="grid-properties" :legend="config.legend" />
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -83,7 +86,10 @@ export default {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
yAxesIds() {
|
yAxesIds() {
|
||||||
return !this.isStackedPlotObject && this.yAxes.filter((yAxis) => yAxis.seriesCount > 0);
|
if (this.isStackedPlotObject) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.yAxes.filter((yAxis) => yAxis.seriesCount > 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -20,98 +20,93 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ul>
|
<li class="c-tree__item menus-to-left" :class="isAliasClass" :aria-label="ariaLabel">
|
||||||
<li class="c-tree__item menus-to-left" :class="isAliasClass">
|
<span
|
||||||
<span
|
class="c-disclosure-triangle is-enabled flex-elem"
|
||||||
class="c-disclosure-triangle is-enabled flex-elem"
|
:class="expandedCssClass"
|
||||||
:class="expandedCssClass"
|
role="button"
|
||||||
@click="toggleExpanded"
|
:aria-label="ariaLabelExpandCollapse"
|
||||||
>
|
tabindex="0"
|
||||||
</span>
|
@click="toggleExpanded"
|
||||||
<div class="c-object-label" :class="statusClass">
|
@keydown.enter="toggleExpanded"
|
||||||
<div class="c-object-label__type-icon" :class="getSeriesClass">
|
></span>
|
||||||
<span class="is-status__indicator" title="This item is missing or suspect"></span>
|
<div class="c-object-label" :class="statusClass">
|
||||||
</div>
|
<div class="c-object-label__type-icon" :class="getSeriesClass">
|
||||||
<div class="c-object-label__name">{{ series.domainObject.name }}</div>
|
<span class="is-status__indicator" title="This item is missing or suspect"></span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
<div class="c-object-label__name">{{ series.domainObject.name }}</div>
|
||||||
<li v-show="expanded" class="c-tree__item menus-to-left" role="table">
|
</div>
|
||||||
<ul class="grid-properties js-plot-options-browse-properties" role="rowgroup">
|
</li>
|
||||||
<li class="grid-row" role="row">
|
<li v-show="expanded" class="c-tree__item menus-to-left" role="table">
|
||||||
<div
|
<ul class="grid-properties js-plot-options-browse-properties" role="rowgroup">
|
||||||
class="grid-cell label"
|
<li class="grid-row" role="row">
|
||||||
title="The field to be plotted as a value for this series."
|
<div
|
||||||
role="cell"
|
class="grid-cell label"
|
||||||
>
|
title="The field to be plotted as a value for this series."
|
||||||
Value
|
role="cell"
|
||||||
</div>
|
>
|
||||||
<div class="grid-cell value" role="cell">
|
Value
|
||||||
{{ yKey }}
|
</div>
|
||||||
</div>
|
<div class="grid-cell value" role="cell">
|
||||||
</li>
|
{{ yKey }}
|
||||||
<li class="grid-row" role="row">
|
</div>
|
||||||
<div
|
</li>
|
||||||
class="grid-cell label"
|
<li class="grid-row" role="row">
|
||||||
title="The rendering method to join lines for this series."
|
<div
|
||||||
role="cell"
|
class="grid-cell label"
|
||||||
>
|
title="The rendering method to join lines for this series."
|
||||||
Line Method
|
role="cell"
|
||||||
</div>
|
>
|
||||||
<div class="grid-cell value" role="cell">
|
Line Method
|
||||||
{{
|
</div>
|
||||||
{
|
<div class="grid-cell value" role="cell">
|
||||||
none: 'None',
|
{{
|
||||||
linear: 'Linear interpolation',
|
{
|
||||||
stepAfter: 'Step After'
|
none: 'None',
|
||||||
}[interpolate]
|
linear: 'Linear interpolation',
|
||||||
}}
|
stepAfter: 'Step After'
|
||||||
</div>
|
}[interpolate]
|
||||||
</li>
|
}}
|
||||||
<li class="grid-row" role="row">
|
</div>
|
||||||
<div
|
</li>
|
||||||
class="grid-cell label"
|
<li class="grid-row" role="row">
|
||||||
title="Whether markers are displayed, and their size."
|
<div
|
||||||
role="cell"
|
class="grid-cell label"
|
||||||
>
|
title="Whether markers are displayed, and their size."
|
||||||
Markers
|
role="cell"
|
||||||
</div>
|
>
|
||||||
<div class="grid-cell value" role="cell">
|
Markers
|
||||||
{{ markerOptionsDisplayText }}
|
</div>
|
||||||
</div>
|
<div class="grid-cell value" role="cell">
|
||||||
</li>
|
{{ markerOptionsDisplayText }}
|
||||||
<li class="grid-row" role="row">
|
</div>
|
||||||
<div
|
</li>
|
||||||
class="grid-cell label"
|
<li class="grid-row" role="row" title="Display markers visually denoting points in alarm.">
|
||||||
title="Display markers visually denoting points in alarm."
|
<div class="grid-cell label" role="cell">Alarm Markers</div>
|
||||||
role="cell"
|
<div class="grid-cell value" role="cell">
|
||||||
>
|
{{ alarmMarkers ? 'Enabled' : 'Disabled' }}
|
||||||
Alarm Markers
|
</div>
|
||||||
</div>
|
</li>
|
||||||
<div class="grid-cell value" role="cell">
|
<li class="grid-row" role="row">
|
||||||
{{ alarmMarkers ? 'Enabled' : 'Disabled' }}
|
<div
|
||||||
</div>
|
class="grid-cell label"
|
||||||
</li>
|
title="Display lines visually denoting alarm limits."
|
||||||
<li class="grid-row" role="row">
|
role="cell"
|
||||||
<div
|
>
|
||||||
class="grid-cell label"
|
Limit Lines
|
||||||
title="Display lines visually denoting alarm limits."
|
</div>
|
||||||
role="cell"
|
<div class="grid-cell value" role="cell">
|
||||||
>
|
{{ limitLines ? 'Enabled' : 'Disabled' }}
|
||||||
Limit Lines
|
</div>
|
||||||
</div>
|
</li>
|
||||||
<div class="grid-cell value" role="cell">
|
<ColorSwatch
|
||||||
{{ limitLines ? 'Enabled' : 'Disabled' }}
|
:current-color="seriesHexColor"
|
||||||
</div>
|
edit-title="Manually set the plot line and marker color for this series."
|
||||||
</li>
|
view-title="The plot line and marker color for this series."
|
||||||
<ColorSwatch
|
short-label="Color"
|
||||||
:current-color="seriesHexColor"
|
/>
|
||||||
edit-title="Manually set the plot line and marker color for this series."
|
</ul>
|
||||||
view-title="The plot line and marker color for this series."
|
</li>
|
||||||
short-label="Color"
|
|
||||||
/>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -137,6 +132,15 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
ariaLabel() {
|
||||||
|
return this.series?.domainObject?.name ?? '';
|
||||||
|
},
|
||||||
|
ariaLabelExpandCollapse() {
|
||||||
|
const name = this.series.domainObject.name ? ` ${this.series.domainObject.name}` : '';
|
||||||
|
const type = this.series.domainObject.type ? ` ${this.series.domainObject.type}` : '';
|
||||||
|
|
||||||
|
return `${this.expanded ? 'Collapse' : 'Expand'}${name}${type}`;
|
||||||
|
},
|
||||||
isAliasClass() {
|
isAliasClass() {
|
||||||
let cssClass = '';
|
let cssClass = '';
|
||||||
const domainObjectPath = [this.series.domainObject, ...this.path];
|
const domainObjectPath = [this.series.domainObject, ...this.path];
|
||||||
|
@ -21,15 +21,19 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="c-tree__item menus-to-left" :class="isAliasCss">
|
<li class="c-tree__item menus-to-left" :class="isAliasCss" role="treeitem">
|
||||||
<span
|
<span
|
||||||
class="c-disclosure-triangle is-enabled flex-elem"
|
class="c-disclosure-triangle is-enabled flex-elem"
|
||||||
:class="expandedCssClass"
|
:class="expandedCssClass"
|
||||||
|
role="button"
|
||||||
|
:aria-label="ariaLabelValue"
|
||||||
|
tabindex="0"
|
||||||
@click="toggleExpanded"
|
@click="toggleExpanded"
|
||||||
|
@keydown.enter="toggleExpanded"
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
<div :class="objectLabelCss">
|
<div :class="objectLabelCss">
|
||||||
<div class="c-object-label__type-icon" :class="[seriesCss]">
|
<div class="c-object-label__type-icon" :class="seriesCss">
|
||||||
<span class="is-status__indicator" title="This item is missing or suspect"></span>
|
<span class="is-status__indicator" title="This item is missing or suspect"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-object-label__name">{{ series.domainObject.name }}</div>
|
<div class="c-object-label__name">{{ series.domainObject.name }}</div>
|
||||||
@ -43,12 +47,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<select v-model="yKey" @change="updateForm('yKey')">
|
<select v-model="yKey" @change="updateForm('yKey')">
|
||||||
<option
|
<option v-for="option in yKeyOptions" :key="option.value" :value="option.value">
|
||||||
v-for="option in yKeyOptions"
|
|
||||||
:key="option.value"
|
|
||||||
:value="option.value"
|
|
||||||
:selected="option.value == yKey"
|
|
||||||
>
|
|
||||||
{{ option.name }}
|
{{ option.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@ -84,10 +83,15 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
<div class="grid-cell label" title="Display markers visually denoting points in alarm.">
|
<div class="grid-cell label" title="Display markers visually denoting points in alarm.">
|
||||||
Alarm Markers
|
<label for="alarm-markers-checkbox">Alarm Markers</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<input v-model="alarmMarkers" type="checkbox" @change="updateForm('alarmMarkers')" />
|
<input
|
||||||
|
id="alarm-markers-checkbox"
|
||||||
|
v-model="alarmMarkers"
|
||||||
|
type="checkbox"
|
||||||
|
@change="updateForm('alarmMarkers')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
@ -169,18 +173,24 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
ariaLabelValue() {
|
||||||
|
const name = this.series.domainObject.name ? ` ${this.series.domainObject.name}` : '';
|
||||||
|
const type = this.series.domainObject.type ? ` ${this.series.domainObject.type}` : '';
|
||||||
|
|
||||||
|
return `${this.expanded ? 'Collapse' : 'Expand'}${name}${type}`;
|
||||||
|
},
|
||||||
colorPalette() {
|
colorPalette() {
|
||||||
return this.series.collection.palette.groups();
|
return this.series.collection.palette.groups();
|
||||||
},
|
},
|
||||||
objectLabelCss() {
|
objectLabelCss() {
|
||||||
return this.status ? `c-object-label is-status--${this.status}'` : 'c-object-label';
|
return this.status ? `c-object-label is-status--${this.status}` : 'c-object-label';
|
||||||
},
|
},
|
||||||
seriesCss() {
|
seriesCss() {
|
||||||
let type = this.openmct.types.get(this.series.domainObject.type);
|
const type = this.openmct.types.get(this.series.domainObject.type);
|
||||||
|
const baseClass = 'c-object-label__type-icon';
|
||||||
|
const typeClass = type.definition.cssClass || '';
|
||||||
|
|
||||||
return type.definition.cssClass
|
return `${baseClass} ${typeClass}`.trim();
|
||||||
? `c-object-label__type-icon ${type.definition.cssClass}`
|
|
||||||
: `c-object-label__type-icon`;
|
|
||||||
},
|
},
|
||||||
isAliasCss() {
|
isAliasCss() {
|
||||||
let cssClass = '';
|
let cssClass = '';
|
||||||
|
@ -31,25 +31,36 @@
|
|||||||
Label
|
Label
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<input v-model="label" class="c-input--flex" type="text" @change="updateForm('label')" />
|
<label :for="`y-axis-${id}-label`" class="visually-hidden">Y Axis {{ id }} Label</label>
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="grid-row">
|
|
||||||
<div id="log-mode-checkbox" class="grid-cell label" title="Enable log mode.">Log mode</div>
|
|
||||||
<div class="grid-cell value">
|
|
||||||
<!-- eslint-disable-next-line vue/html-self-closing -->
|
|
||||||
<input
|
<input
|
||||||
v-model="logMode"
|
:id="`y-axis-${id}-label`"
|
||||||
class="js-log-mode-input"
|
v-model="label"
|
||||||
aria-labelledby="log-mode-checkbox"
|
class="c-input--flex"
|
||||||
type="checkbox"
|
type="text"
|
||||||
@change="updateForm('logMode')"
|
@change="updateForm('label')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="grid-row">
|
||||||
|
<div :id="`log-mode-checkbox-${id}`" class="grid-cell label" title="Enable log mode.">
|
||||||
|
Log mode
|
||||||
|
</div>
|
||||||
|
<div class="grid-cell value">
|
||||||
|
<input
|
||||||
|
:id="`log-mode-input-${id}`"
|
||||||
|
v-model="logMode"
|
||||||
|
class="js-log-mode-input"
|
||||||
|
type="checkbox"
|
||||||
|
@change="updateForm('logMode')"
|
||||||
|
/>
|
||||||
|
<label :for="`log-mode-input-${id}`" class="visually-hidden"
|
||||||
|
>Y Axis {{ id }} Log mode</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
<div
|
<div
|
||||||
id="autoscale-checkbox"
|
:id="`autoscale-checkbox-${id}`"
|
||||||
class="grid-cell label"
|
class="grid-cell label"
|
||||||
title="Automatically scale the Y axis to keep all values in view."
|
title="Automatically scale the Y axis to keep all values in view."
|
||||||
>
|
>
|
||||||
@ -57,11 +68,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<input
|
<input
|
||||||
|
:id="`autoscale-input-${id}`"
|
||||||
v-model="autoscale"
|
v-model="autoscale"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
aria-labelledby="autoscale-checkbox"
|
|
||||||
@change="updateForm('autoscale')"
|
@change="updateForm('autoscale')"
|
||||||
/>
|
/>
|
||||||
|
<label :for="`autoscale-input-${id}`" class="visually-hidden"
|
||||||
|
>Y Axis {{ id }} Auto scale</label
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li v-show="autoscale" class="grid-row">
|
<li v-show="autoscale" class="grid-row">
|
||||||
@ -72,7 +86,11 @@
|
|||||||
Padding
|
Padding
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
|
<label :for="`autoscale-padding-${id}`" class="visually-hidden"
|
||||||
|
>Y Axis {{ id }} Autoscale Padding</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
|
:id="`autoscale-padding-${id}`"
|
||||||
v-model="autoscalePadding"
|
v-model="autoscalePadding"
|
||||||
class="c-input--flex"
|
class="c-input--flex"
|
||||||
type="text"
|
type="text"
|
||||||
@ -88,8 +106,12 @@
|
|||||||
<li class="grid-row force-border">
|
<li class="grid-row force-border">
|
||||||
<div class="grid-cell label" title="Minimum Y axis value.">Minimum Value</div>
|
<div class="grid-cell label" title="Minimum Y axis value.">Minimum Value</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
|
<label :for="`range-min-${id}`" class="visually-hidden"
|
||||||
|
>Y Axis {{ id }} Minimum value</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
v-model.lazy="rangeMin"
|
:id="`range-min-${id}`"
|
||||||
|
v-model="rangeMin"
|
||||||
class="c-input--flex"
|
class="c-input--flex"
|
||||||
type="number"
|
type="number"
|
||||||
@change="updateForm('range')"
|
@change="updateForm('range')"
|
||||||
@ -99,8 +121,12 @@
|
|||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
<div class="grid-cell label" title="Maximum Y axis value.">Maximum Value</div>
|
<div class="grid-cell label" title="Maximum Y axis value.">Maximum Value</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
|
<label :for="`range-max-${id}`" class="visually-hidden"
|
||||||
|
>Y Axis {{ id }} Maximum value</label
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
v-model.lazy="rangeMax"
|
:id="`range-max-${id}`"
|
||||||
|
v-model="rangeMax"
|
||||||
class="c-input--flex"
|
class="c-input--flex"
|
||||||
type="number"
|
type="number"
|
||||||
@change="updateForm('range')"
|
@change="updateForm('range')"
|
||||||
|
@ -122,8 +122,11 @@ export default {
|
|||||||
'grid-lines',
|
'grid-lines',
|
||||||
'plot-y-tick-width'
|
'plot-y-tick-width'
|
||||||
],
|
],
|
||||||
mounted() {
|
beforeMount() {
|
||||||
|
// We must do this before mounted to use any series configuration options set at the stacked plot level
|
||||||
this.updateView();
|
this.updateView();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
this.isEditing = this.openmct.editor.isEditing();
|
this.isEditing = this.openmct.editor.isEditing();
|
||||||
this.openmct.editor.on('isEditing', this.setEditState);
|
this.openmct.editor.on('isEditing', this.setEditState);
|
||||||
this.setupClockChangedEvent((domainObject) => {
|
this.setupClockChangedEvent((domainObject) => {
|
||||||
|
@ -28,8 +28,10 @@
|
|||||||
role="tab"
|
role="tab"
|
||||||
class="c-inspector__tab c-tab"
|
class="c-inspector__tab c-tab"
|
||||||
:class="{ 'is-current': isSelected(tab) }"
|
:class="{ 'is-current': isSelected(tab) }"
|
||||||
|
tabindex="0"
|
||||||
:title="tab.name"
|
:title="tab.name"
|
||||||
@click="selectTab(tab)"
|
@click="selectTab(tab)"
|
||||||
|
@keydown.enter="selectTab(tab)"
|
||||||
>
|
>
|
||||||
<span class="c-inspector__tab-name c-tab__name">{{ tab.name }}</span>
|
<span class="c-inspector__tab-name c-tab__name">{{ tab.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user