mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 20:57:53 +00:00
Merge branch '7936-add-discrete-event-visualization' of github.com:nasa/openmct into 7936-add-discrete-event-visualization
This commit is contained in:
commit
68fc3172a0
@ -74,7 +74,7 @@ test.describe('Event Timeline View', () => {
|
||||
|
||||
// count the event lines
|
||||
const eventWrappersContainer = page.locator('.c-events-tsv__container');
|
||||
const eventWrappers = eventWrappersContainer.locator('.c-events-tsv__event-wrapper');
|
||||
const eventWrappers = eventWrappersContainer.locator('.c-events-tsv__event-line');
|
||||
const expectedEventWrappersCount = 25;
|
||||
await expect(eventWrappers).toHaveCount(expectedEventWrappersCount);
|
||||
|
||||
@ -104,7 +104,7 @@ test.describe('Event Timeline View', () => {
|
||||
|
||||
// count the extended lines
|
||||
const overlayLinesContainer = page.locator('.c-timeline__overlay-lines');
|
||||
const extendedLines = overlayLinesContainer.locator('.c-timeline__extended-line');
|
||||
const extendedLines = overlayLinesContainer.locator('.c-timeline__event-line--extended');
|
||||
const expectedCount = 25;
|
||||
await expect(extendedLines).toHaveCount(expectedCount);
|
||||
});
|
||||
|
@ -25,7 +25,7 @@ export const SEVERITY_CSS = {
|
||||
WARNING: 'is-event--yellow',
|
||||
DISTRESS: 'is-event--red',
|
||||
CRITICAL: 'is-event--red',
|
||||
SEVERE: 'is-event--red'
|
||||
SEVERE: 'is-event--purple'
|
||||
};
|
||||
|
||||
const NOMINAL_SEVERITY = {
|
||||
|
@ -27,6 +27,8 @@
|
||||
import { SEVERITY_CSS } from './EventLimitProvider.js';
|
||||
import messages from './transcript.json';
|
||||
|
||||
const DUR_MIN = 1000;
|
||||
const DUR_MAX = 10000;
|
||||
class EventTelemetryProvider {
|
||||
constructor() {
|
||||
this.defaultSize = 25;
|
||||
@ -34,12 +36,17 @@ class EventTelemetryProvider {
|
||||
|
||||
generateData(firstObservedTime, count, startTime, duration, name) {
|
||||
const millisecondsSinceStart = startTime - firstObservedTime;
|
||||
const utc = startTime + count * duration;
|
||||
const randStartDelay = Math.max(DUR_MIN, Math.random() * DUR_MAX);
|
||||
const utc = startTime + randStartDelay + count * duration;
|
||||
const ind = count % messages.length;
|
||||
const message = messages[ind] + ' - [' + millisecondsSinceStart + ']';
|
||||
// pick a random severity level + 1 for an undefined level so we can do nominal
|
||||
const severity =
|
||||
Object.keys(SEVERITY_CSS)[Math.floor(Math.random() * Object.keys(SEVERITY_CSS).length + 1)];
|
||||
Math.random() > 0.4
|
||||
? Object.keys(SEVERITY_CSS)[
|
||||
Math.floor(Math.random() * Object.keys(SEVERITY_CSS).length + 1)
|
||||
]
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
name,
|
||||
@ -58,7 +65,7 @@ class EventTelemetryProvider {
|
||||
}
|
||||
|
||||
subscribe(domainObject, callback) {
|
||||
const duration = domainObject.telemetry.duration * 1000;
|
||||
const duration = domainObject.telemetry.duration * DUR_MIN;
|
||||
const firstObservedTime = Date.now();
|
||||
let count = 0;
|
||||
|
||||
@ -83,7 +90,7 @@ class EventTelemetryProvider {
|
||||
request(domainObject, options) {
|
||||
let start = options.start;
|
||||
const end = Math.min(Date.now(), options.end); // no future values
|
||||
const duration = domainObject.telemetry.duration * 1000;
|
||||
const duration = domainObject.telemetry.duration * DUR_MIN;
|
||||
const size = options.size ? options.size : this.defaultSize;
|
||||
const data = [];
|
||||
const firstObservedTime = options.start;
|
||||
|
@ -38,7 +38,7 @@ import eventData from '../mixins/eventData.js';
|
||||
const PADDING = 1;
|
||||
const CONTAINER_CLASS = 'c-events-tsv__container';
|
||||
const NO_ITEMS_CLASS = 'c-events-tsv__no-items';
|
||||
const EVENT_WRAPPER_CLASS = 'c-events-tsv__event-wrapper';
|
||||
const EVENT_WRAPPER_CLASS = 'c-events-tsv__event-line';
|
||||
const ID_PREFIX = 'wrapper-';
|
||||
const AXES_PADDING = 20;
|
||||
|
||||
@ -403,6 +403,10 @@ export default {
|
||||
}
|
||||
this.openmct.selection.select(selection, true);
|
||||
},
|
||||
getLimitClass(event) {
|
||||
const limitEvaluation = this.limitEvaluator.evaluate(event, this.valueMetadata);
|
||||
return limitEvaluation?.cssClass;
|
||||
},
|
||||
createEventWrapper(event) {
|
||||
const id = `${ID_PREFIX}${event.time}`;
|
||||
const eventWrapper = document.createElement('div');
|
||||
@ -413,7 +417,7 @@ export default {
|
||||
const textToShow = event[this.titleKey];
|
||||
eventWrapper.ariaLabel = textToShow;
|
||||
eventWrapper.addEventListener('mouseover', () => {
|
||||
this.showToolTip(textToShow, eventWrapper);
|
||||
this.showToolTip(textToShow, eventWrapper, event);
|
||||
this.extendedLinesBus.updateHoverExtendEventLine(this.keyString, event.time);
|
||||
});
|
||||
eventWrapper.addEventListener('mouseleave', () => {
|
||||
@ -421,8 +425,7 @@ export default {
|
||||
this.extendedLinesBus.updateHoverExtendEventLine(this.keyString, null);
|
||||
});
|
||||
}
|
||||
const limitEvaluation = this.limitEvaluator.evaluate(event, this.valueMetadata);
|
||||
const limitClass = limitEvaluation?.cssClass;
|
||||
const limitClass = this.getLimitClass(event);
|
||||
if (limitClass) {
|
||||
eventWrapper.classList.add(limitClass);
|
||||
event.limitClass = limitClass;
|
||||
@ -451,12 +454,22 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
showToolTip(textToShow, referenceElement) {
|
||||
showToolTip(textToShow, referenceElement, event) {
|
||||
const aClasses = ['c-events-tooltip'];
|
||||
const limitClass = this.getLimitClass(event);
|
||||
if (limitClass) {
|
||||
aClasses.push(limitClass);
|
||||
}
|
||||
const showToLeft = false; // Temp, stubbed in
|
||||
if (showToLeft) {
|
||||
aClasses.push('--left');
|
||||
}
|
||||
|
||||
this.tooltip = this.openmct.tooltips.tooltip({
|
||||
toolTipText: textToShow,
|
||||
toolTipLocation: this.openmct.tooltips.TOOLTIP_LOCATIONS.RIGHT,
|
||||
parentElement: referenceElement,
|
||||
cssClasses: ['c-timeline-event-tooltip']
|
||||
cssClasses: [aClasses.join(' ')]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,16 @@
|
||||
@mixin styleEventLine($colorConst) {
|
||||
background-color: $colorConst !important;
|
||||
&:hover,
|
||||
&[s-selected] {
|
||||
box-shadow: rgba($colorConst, 0.5) 0 0 0px 4px;
|
||||
transition: none;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
@mixin styleEventLineExtended($colorConst) {
|
||||
background-color: $colorConst !important;
|
||||
}
|
||||
|
||||
.c-events-tsv {
|
||||
$m: $interiorMargin;
|
||||
overflow: hidden;
|
||||
@ -11,21 +24,37 @@
|
||||
top: $m; right: 0; bottom: $m; left: 0;
|
||||
}
|
||||
|
||||
&__event-wrapper {
|
||||
&__event-line {
|
||||
// Wraps an individual event line
|
||||
// Also holds the hover flyout element
|
||||
$c: $colorEventLine;
|
||||
$lineW: $eventLineW;
|
||||
$hitAreaW: 7px;
|
||||
$m: $interiorMarginSm;
|
||||
background-color: rgba($c, 0.6);
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
top: $m; bottom: $m;
|
||||
transition: box-shadow 250ms ease-out;
|
||||
width: $lineW;
|
||||
z-index: 1;
|
||||
|
||||
@include styleEventLine($colorEventLine);
|
||||
&.is-event {
|
||||
&--purple {
|
||||
@include styleEventLine($colorEventPurpleLine);
|
||||
}
|
||||
&--red {
|
||||
@include styleEventLine($colorEventRedLine);
|
||||
}
|
||||
&--orange {
|
||||
@include styleEventLine($colorEventOrangeLine);
|
||||
}
|
||||
&--yellow {
|
||||
@include styleEventLine($colorEventYellowLine);
|
||||
}
|
||||
}
|
||||
|
||||
&:before {
|
||||
// Extend hit area
|
||||
content: '';
|
||||
@ -36,17 +65,6 @@
|
||||
width: $hitAreaW;
|
||||
transform: translateX(($hitAreaW - $lineW) * -0.5);
|
||||
}
|
||||
|
||||
&.is-selected, // TODO: temp, remove this once we set selection correctly
|
||||
&[s-selected],
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
background-color: $c;
|
||||
|
||||
&:before {
|
||||
background-color: rgba($c, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__no-items {
|
||||
@ -64,3 +82,38 @@
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
// Extended event lines
|
||||
.c-timeline__event-line--extended {
|
||||
@include abs();
|
||||
transition: opacity 250ms ease-out;
|
||||
width: $eventLineW;
|
||||
opacity: 0.4;
|
||||
|
||||
&.--hilite {
|
||||
opacity: 0.8;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
@include styleEventLineExtended($colorEventLine);
|
||||
&.is-event {
|
||||
&--purple {
|
||||
@include styleEventLineExtended($colorEventPurpleLine);
|
||||
}
|
||||
&--red {
|
||||
@include styleEventLineExtended($colorEventRedLine);
|
||||
}
|
||||
&--orange {
|
||||
@include styleEventLineExtended($colorEventOrangeLine);
|
||||
}
|
||||
&--yellow {
|
||||
@include styleEventLineExtended($colorEventYellowLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-events-tooltip {
|
||||
// Default to right of event line
|
||||
border-radius: 0 !important;
|
||||
//transform: translate(0, $interiorMargin);
|
||||
}
|
||||
|
@ -24,18 +24,17 @@
|
||||
<div
|
||||
v-for="(lines, key) in extendedLinesPerKey"
|
||||
:key="key"
|
||||
class="c-timeline__extended-line-container"
|
||||
class="c-timeline__event-line--extended-container"
|
||||
>
|
||||
<div
|
||||
v-for="(line, index) in lines"
|
||||
:id="line.id"
|
||||
:key="index"
|
||||
class="c-timeline__extended-line"
|
||||
class="c-timeline__event-line--extended"
|
||||
:class="[
|
||||
line.limitClass,
|
||||
{
|
||||
'c-timeline__extended-line-hovered':
|
||||
hoveredLineId && hoveredKeyString === key && line.id === hoveredLineId
|
||||
'--hilite': hoveredLineId && hoveredKeyString === key && line.id === hoveredLineId
|
||||
}
|
||||
]"
|
||||
:style="{ left: `${line.x + leftOffset}px`, height: `${height}px` }"
|
||||
|
@ -51,10 +51,4 @@
|
||||
pointer-events: none; // Allows clicks to pass through
|
||||
z-index: 10; // Ensure it sits atop swimlanes
|
||||
}
|
||||
|
||||
&__extended-line {
|
||||
position: absolute;
|
||||
width: $eventLineW;
|
||||
background-color: $colorEventLineExtended;
|
||||
}
|
||||
}
|
||||
|
@ -443,6 +443,10 @@ $colorEventPurpleBg: #31204a;
|
||||
$colorEventRedBg: #3c1616;
|
||||
$colorEventOrangeBg: #3e2a13;
|
||||
$colorEventYellowBg: #3e3316;
|
||||
$colorEventPurpleLine: #9e36ff;
|
||||
$colorEventRedLine: #ff2525;
|
||||
$colorEventOrangeLine: #ff8800;
|
||||
$colorEventYellowLine: #fdce22;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: #dddddd;
|
||||
|
@ -412,6 +412,10 @@ $colorEventPurpleBg: #31204a;
|
||||
$colorEventRedBg: #3c1616;
|
||||
$colorEventOrangeBg: #3e2a13;
|
||||
$colorEventYellowBg: #3e3316;
|
||||
$colorEventPurpleLine: #9e36ff;
|
||||
$colorEventRedLine: #ff2525;
|
||||
$colorEventOrangeLine: #ff8800;
|
||||
$colorEventYellowLine: #fdce22;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: #dddddd;
|
||||
|
@ -428,6 +428,10 @@ $colorEventPurpleBg: #31204a;
|
||||
$colorEventRedBg: #3c1616;
|
||||
$colorEventOrangeBg: #3e2a13;
|
||||
$colorEventYellowBg: #3e3316;
|
||||
$colorEventPurpleLine: #9e36ff;
|
||||
$colorEventRedLine: #ff2525;
|
||||
$colorEventOrangeLine: #ff8800;
|
||||
$colorEventYellowLine: #fdce22;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: #dddddd;
|
||||
|
@ -403,14 +403,18 @@ $colorLimitCyanFg: #d3faff;
|
||||
$colorLimitCyanIc: #1795c0;
|
||||
|
||||
// Events
|
||||
$colorEventPurpleFg: #6433ff;
|
||||
$colorEventPurpleFg: #6f07ed;
|
||||
$colorEventRedFg: #aa0000;
|
||||
$colorEventOrangeFg: #b84900;
|
||||
$colorEventYellowFg: #867109;
|
||||
$colorEventYellowFg: #a98c04;
|
||||
$colorEventPurpleBg: #ebe7fb;
|
||||
$colorEventRedBg: #fcefef;
|
||||
$colorEventOrangeBg: #ffece3;
|
||||
$colorEventYellowBg: #fdf8eb;
|
||||
$colorEventPurpleLine: $colorEventPurpleFg;
|
||||
$colorEventRedLine: $colorEventRedFg;
|
||||
$colorEventOrangeLine: $colorEventOrangeFg;
|
||||
$colorEventYellowLine: $colorEventYellowFg;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: $colorMenuBg;
|
||||
|
@ -252,8 +252,6 @@ tr {
|
||||
background-color: $colorEventYellowBg !important;
|
||||
color: $colorEventYellowFg !important;
|
||||
}
|
||||
&--no-style {
|
||||
background-color: $colorBodyBg !important;
|
||||
color: $colorBodyFg !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user