-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Discrete Event Visualization in Timeline #7967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 59 commits
3159de0
680b095
7b22cf3
7af3996
944634d
55bed6a
2776cc8
5b006b6
8b5e2f4
3b236cc
0db301d
e9f120a
d046ad1
052129b
6f26add
aaec052
96d8870
3829295
3d3f093
64bd625
781d834
d97f7c3
cda7cc9
d048af1
62b4975
20247bb
20426fe
6bda108
aaa2e43
2ba6bc9
3af9083
36d3197
72ff0bc
f4ec532
49a106b
cba7c7f
2ae1fe1
b865d8c
27af030
099153b
546714b
51d9654
68fc317
531ef3e
638b03c
601fc33
8c72e4a
65b1f02
3c24205
5312458
bb4fea7
5b28086
9522040
6cafa7a
cfa2129
e6cb940
f163034
0933d27
15b674f
0e940b2
32a0e15
9e68514
1ced12d
3ad64f0
aa5fa46
74a5d7e
157bde8
8be969f
14a5c47
88b4331
b171f82
af6f327
bbae9c6
55d15ca
8545dde
2e35212
c1f7243
8a7d0db
065ba2f
f39e7d0
c131fe8
adb2f20
a4a596a
ba69bb4
12f76b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/***************************************************************************** | ||
* 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. | ||
*****************************************************************************/ | ||
|
||
import { createDomainObjectWithDefaults, setTimeConductorBounds } from '../../../../appActions.js'; | ||
import { expect, test } from '../../../../pluginFixtures.js'; | ||
|
||
test.describe('Event Timeline View', () => { | ||
let eventTimelineView; | ||
let eventGenerator1; | ||
|
||
test.beforeEach(async ({ page }) => { | ||
await page.goto('./', { waitUntil: 'domcontentloaded' }); | ||
|
||
eventTimelineView = await createDomainObjectWithDefaults(page, { | ||
type: 'Time Strip' | ||
}); | ||
|
||
await createDomainObjectWithDefaults(page, { | ||
type: 'Sine Wave Generator', | ||
parent: eventTimelineView.uuid | ||
}); | ||
|
||
eventGenerator1 = await createDomainObjectWithDefaults(page, { | ||
type: 'Event Message Generator', | ||
parent: eventTimelineView.uuid | ||
}); | ||
|
||
await createDomainObjectWithDefaults(page, { | ||
type: 'Event Message Generator with Acknowledge', | ||
parent: eventTimelineView.uuid | ||
}); | ||
|
||
await setTimeConductorBounds(page, { | ||
startDate: '2024-01-01', | ||
endDate: '2024-01-01', | ||
startTime: '01:01:00', | ||
endTime: '01:04:00' | ||
}); | ||
}); | ||
|
||
test('Ensure we can build a Time Strip with event', async ({ page }) => { | ||
await page.goto(eventTimelineView.url); | ||
|
||
// click on an event | ||
await page | ||
.getByLabel(eventTimelineView.name) | ||
.getByLabel(/PROGRAM ALARM/) | ||
.click(); | ||
|
||
// click on the event inspector tab | ||
await page.getByRole('tab', { name: 'Event' }).click(); | ||
|
||
// ensure the event inspector has the the same event | ||
await expect(page.getByText(/PROGRAM ALARM/)).toBeVisible(); | ||
|
||
// count the event lines | ||
const eventWrappersContainer = page.locator('.c-events-tsv__container'); | ||
const eventWrappers = eventWrappersContainer.locator('.c-events-tsv__event-line'); | ||
const expectedEventWrappersCount = 25; | ||
await expect(eventWrappers).toHaveCount(expectedEventWrappersCount); | ||
scottbell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// click on another event | ||
await page | ||
.getByLabel(eventTimelineView.name) | ||
.getByLabel(/pegged/) | ||
.click(); | ||
|
||
// ensure the tooltip shows up | ||
await expect( | ||
page.getByRole('tooltip').getByText(/pegged on horizontal velocity/) | ||
).toBeVisible(); | ||
|
||
// and that event appears in the inspector | ||
await expect( | ||
page.getByLabel('Inspector Views').getByText(/pegged on horizontal velocity/) | ||
).toBeVisible(); | ||
|
||
// turn on extended lines | ||
await page | ||
.getByLabel(eventTimelineView.name) | ||
scottbell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.getByRole('button', { | ||
name: `Toggle extended event lines overlay for ${eventGenerator1.name}` | ||
}) | ||
.click(); | ||
|
||
// count the extended lines | ||
const overlayLinesContainer = page.locator('.c-timeline__overlay-lines'); | ||
const extendedLines = overlayLinesContainer.locator('.c-timeline__event-line--extended'); | ||
const expectedCount = 25; | ||
await expect(extendedLines).toHaveCount(expectedCount); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/***************************************************************************** | ||
* 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. | ||
*****************************************************************************/ | ||
|
||
export const SEVERITY_CSS = { | ||
WATCH: 'is-event--yellow', | ||
WARNING: 'is-event--yellow', | ||
DISTRESS: 'is-event--red', | ||
CRITICAL: 'is-event--red', | ||
SEVERE: 'is-event--purple' | ||
}; | ||
|
||
const NOMINAL_SEVERITY = { | ||
cssClass: 'is-event--no-style', | ||
name: 'NOMINAL' | ||
}; | ||
|
||
/** | ||
* @typedef {Object} EvaluationResult | ||
* @property {string} cssClass CSS class information | ||
* @property {string} name a severity name | ||
*/ | ||
export default class EventLimitProvider { | ||
constructor(openmct) { | ||
this.openmct = openmct; | ||
} | ||
|
||
getLimitEvaluator(domainObject) { | ||
const self = this; | ||
|
||
return { | ||
/** | ||
* Evaluates a telemetry datum for severity. | ||
* | ||
* @param {Datum} datum the telemetry datum from the historical or realtime plugin ({@link Datum}) | ||
* @param {object} valueMetadata metadata about the telemetry datum | ||
* | ||
* @returns {EvaluationResult} ({@link EvaluationResult}) | ||
*/ | ||
evaluate: function (datum, valueMetadata) { | ||
// prevent applying the class to the tr, only to td | ||
if (!valueMetadata) { | ||
return; | ||
} | ||
|
||
if (datum.severity in SEVERITY_CSS) { | ||
return self.getSeverity(datum, valueMetadata); | ||
} | ||
|
||
return NOMINAL_SEVERITY; | ||
} | ||
}; | ||
} | ||
getSeverity(datum, valueMetadata) { | ||
if (!valueMetadata) { | ||
return; | ||
} | ||
|
||
const severityValue = datum.severity; | ||
|
||
return { | ||
cssClass: SEVERITY_CSS[severityValue], | ||
name: severityValue | ||
}; | ||
} | ||
|
||
supportsLimits(domainObject) { | ||
return domainObject.type === 'eventGenerator'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,7 +113,8 @@ | |
creatable: true | ||
}) | ||
); | ||
openmct.install(openmct.plugins.Timeline()); | ||
const timeLinePlugin = openmct.plugins.Timeline(); | ||
openmct.install(timeLinePlugin); | ||
openmct.install(openmct.plugins.Hyperlink()); | ||
openmct.install(openmct.plugins.UTCTimeSystem()); | ||
openmct.install( | ||
|
@@ -234,6 +235,7 @@ | |
openmct.install(openmct.plugins.Timelist()); | ||
openmct.install(openmct.plugins.BarChart()); | ||
openmct.install(openmct.plugins.ScatterPlot()); | ||
openmct.install(openmct.plugins.EventTimestripPlugin(timeLinePlugin.extendedLinesBus)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need to decide if we want this to be the default plugin in core. Traditionally, we don't add new plugins for e2e tests and run the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, will defer this to @charlesh88 or @akhenry |
||
document.addEventListener('DOMContentLoaded', function () { | ||
openmct.start(); | ||
}); | ||
|
Uh oh!
There was an error while loading. Please reload this page.