Compare commits

...

10 Commits

Author SHA1 Message Date
c7d8d91e87 fix length of undefined check (#3292) 2020-08-11 13:46:41 -07:00
2d19975917 [Plots] Allow changing x-axis metadata for release candidate (#3280)
* refactor toggleYAxisLabel for reusability and add toggleXAxisLabel

* allow change of x-axis metadata in single plots

* Revert "refactor toggleYAxisLabel for reusability and add toggleXAxisLabel"

This reverts commit a94a461235.

* change ticks on x-axis metadata change

* update all visible x-axis ticks when changing x-axis metadata

* fix x-axis change to only update ticks when needed

* change x axis toggle to key from label

* remove comments and unnecessary code

* Minor tweaks

 - Refined position of X label select;
 - Fixed ``:hover` to use ``@include hover`;

* WIP do not re-request data on x-axis metadata change

* change x axis selected option on x key change

* options and timesystem change react correctly

* set display range on change of x axis metadata

* clean up regeneration of ticks on x-axis change

remove commented code

* only enable x key toggle when appropriate

* remove comment

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-08-06 13:51:20 -07:00
29e7942a4e port regex change to R4.5 (#3281) 2020-08-06 13:30:55 -07:00
4f853016d6 fix bug with calculateColumnWidths 2020-08-06 12:01:21 -07:00
abbb31f384 Table Row Sizing (#3272)
* working sizingRow  - need style changes

* clear interval on destroy

* Fixes for dynamic table row heights

- Added tr { min-height } to `data-font-size` CSS;
- Refined markup in sizing-row.vue;

* only poll on edit

* fixed small bugs

* fix lint warning

* move sizing row to sizing table

* add reject callbacks to failing tests

* revert changes to elasticsearchproviderspec

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-08-06 11:22:10 -07:00
ae8ed2d71f Compare the enum value to the input, not the index of the enumeration (#3278) 2020-08-06 11:20:38 -07:00
9ecb257e5d change notification indicator to use v-show 2020-08-06 11:19:07 -07:00
5e2d8106a5 [Time conductor] Better persistence handling for history for release branch (#3260)
* remove unnecessary persist call

* do not update bounds if no zoom range

pass correct bounds prop to history

* fix syncing issues with history and local storage

* Update TelemetryTable config to allow disable multiselect.

* rename for clarity

* [Snapshots] Are holding on to outdated domainObjects when clicking on preview #3078 (#3240)

* [Snapshots] Are holding on to outdated domainObjects when clicking on preview #3078

* #3250 :  [Preview] Preview window should not have any context menu actions

* cleanup: removed redundant code

* New eslint rules auto fix (#3058)

* no-implicit-coercion and no-unneeded-ternary

* End every line with a semicolon

* Spacing and formatting

* Enabled semi-spacing

* Applies npm run lint:fix to code after master merge

* Fix merge issues

* Switched operator-linebreak to 'before'

Co-authored-by: Joshi <simplyrender@gmail.com>

* [Telemetry Tables][Plots] Display units where applicable (#3198)

* added unit columns in telemetry tables

* added unit column hiding in telemetry tables, added units to lad tables and sets

* added units to plots and plot legends

* Revert "Merge branch 'master' into time-conductor-fixes"

This reverts commit 4adde12472, reversing
changes made to 79b20067c1.

Co-authored-by: Mandlik, Nikhil K. (ARC-TI)[KBR Wyle Services, LLC] <nikhil.k.mandlik@nasa.gov>
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
Co-authored-by: Joshi <simplyrender@gmail.com>
Co-authored-by: Jamie V <jamie.j.vigliotta@nasa.gov>
2020-08-03 13:58:09 -07:00
32aa412d1e Font Styling (#3252)
* working proto for font size

* wip

* Font styling

 - Base classes for font-size and font;
 - WIP!

* working data attribute for fontsize

* Font styling

 - Add `js-style-receiver` to markup, refine style targeting JS for
 better application of styles;
 - Refinements to font and size CSS;
 - WIP!

* Font styling

 - Redo CSS to use `data-*` attributes;
 - New `u-style-receiver` class for use as font-size and font-family CSS
 selector target;
 - New `js-style-receiver` class for use as JS target by ObjectView.vue;
 - New classes added to markup in all Open MCT views;
 - Changed font-size values from 'is-font-size--*' to just the number;
 - Some refinement to individual views to account for font-sizing
 capability;
 - Removed automatic font-size 13px being set by SubobjectView.vue;
 - WIP!

* working mixed styles

* Font styling

 - Added `u-style-receiver` to TelemetryView.vue;
 - Added `icon-font-size` to Font Size dropdown button;
 - TODO: better font-size icon;

* working font-family

* Font styling

 - Art for `icon-font-size` glyph updated;
 - Redefined glyph usage in some Layout toolbar buttons;
 - Updated font-size and font dropdown menus options text;

* Font styling

 - Refined font-size and font dropdown values;
 - Fixed toolbar-select-menu.vue to remove 'px' from non-specific option
  return;

* dont allow font styling on layouts that contain other layouts

* fix lint warning

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-07-31 10:37:33 -07:00
cb7f431fdf Snapshot outdated objects fix (#3251)
* [Snapshots] Are holding on to outdated domainObjects when clicking on preview #3078

* #3250 :  [Preview] Preview window should not have any context menu actions

* cleanup: removed redundant code

Co-authored-by: Mandlik, Nikhil K. (ARC-TI)[KBR Wyle Services, LLC] <nikhil.k.mandlik@nasa.gov>
2020-07-29 16:34:32 -07:00
47 changed files with 786 additions and 139 deletions

View File

@ -19,7 +19,7 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<div class="c-clock l-time-display" ng-controller="ClockController as clock"> <div class="c-clock l-time-display u-style-receiver js-style-receiver" ng-controller="ClockController as clock">
<div class="c-clock__timezone"> <div class="c-clock__timezone">
{{clock.zone()}} {{clock.zone()}}
</div> </div>

View File

@ -19,7 +19,7 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<div class="c-timer is-{{timer.timerState}}" ng-controller="TimerController as timer"> <div class="c-timer u-style-receiver js-style-receiver is-{{timer.timerState}}" ng-controller="TimerController as timer">
<div class="c-timer__controls"> <div class="c-timer__controls">
<button ng-click="timer.clickStopButton()" <button ng-click="timer.clickStopButton()"
ng-hide="timer.timerState == 'stopped'" ng-hide="timer.timerState == 'stopped'"

View File

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
<template> <template>
<div class="c-lad-table-wrapper"> <div class="c-lad-table-wrapper u-style-receiver js-style-receiver">
<table class="c-table c-lad-table"> <table class="c-table c-lad-table">
<thead> <thead>
<tr> <tr>

View File

@ -203,7 +203,7 @@ export default class TelemetryCriterion extends EventEmitter {
let inputValue; let inputValue;
if (metadataObject) { if (metadataObject) {
if(metadataObject.enumerations && input.length) { if(metadataObject.enumerations && input.length) {
const enumeration = metadataObject.enumerations[input[0]]; const enumeration = metadataObject.enumerations.find((item) => item.value.toString() === input[0].toString());
if (enumeration !== undefined && enumeration.string) { if (enumeration !== undefined && enumeration.string) {
inputValue = [enumeration.string]; inputValue = [enumeration.string];
} }

View File

@ -22,7 +22,7 @@
<template> <template>
<component :is="urlDefined ? 'a' : 'span'" <component :is="urlDefined ? 'a' : 'span'"
class="c-condition-widget" class="c-condition-widget u-style-receiver js-style-receiver"
:href="urlDefined ? internalDomainObject.url : null" :href="urlDefined ? internalDomainObject.url : null"
> >
<div class="c-condition-widget__label"> <div class="c-condition-widget__label">

View File

@ -124,7 +124,117 @@ define(['lodash'], function (_) {
'telemetry.plot.overlay-multi': [ 'telemetry.plot.overlay-multi': [
VIEW_TYPES['telemetry.plot.stacked'] VIEW_TYPES['telemetry.plot.stacked']
] ]
}; },
SMALL_FONT_SIZES = [
{
name: 'Default Size',
value: 'default'
},
{
name: '8px',
value: '8'
},
{
name: '9px',
value: '9'
},
{
name: '10px',
value: '10'
},
{
name: '11px',
value: '11'
},
{
name: '12px',
value: '12'
},
{
name: '13px',
value: '13'
},
{
name: '14px',
value: '14'
},
{
name: '16px',
value: '16'
},
{
name: '18px',
value: '18'
},
{
name: '20px',
value: '20'
},
{
name: '24px',
value: '24'
}
],
LARGE_FONT_SIZES = [
{
name: '28px',
value: '28'
},
{
name: '32px',
value: '32'
},
{
name: '36px',
value: '36'
},
{
name: '42px',
value: '42'
},
{
name: '48px',
value: '48'
},
{
name: '72px',
value: '72'
},
{
name: '96px',
value: '96'
},
{
name: '128px',
value: '128'
}
],
FONTS = [
{
name: 'Default',
value: 'default'
},
{
name: 'Bold',
value: 'default-bold'
},
{
name: 'Narrow',
value: 'narrow'
},
{
name: 'Narrow Bold',
value: 'narrow-bold'
},
{
name: 'Monospace',
value: 'monospace'
},
{
name: 'Monospace Bold',
value: 'monospace-bold'
}
]
function getUserInput(form) { function getUserInput(form) {
return openmct.$injector.get('dialogService').getUserInput(form, {}); return openmct.$injector.get('dialogService').getUserInput(form, {});
@ -378,25 +488,136 @@ define(['lodash'], function (_) {
} }
} }
function getTextSizeMenu(selectedParent, selection) { function getAvailableFontSizeOptions(selection) {
const TEXT_SIZE = [8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96, 128]; let sizeOptions = 'big';
return {
control: "select-menu", selection.forEach(selectable => {
domainObject: selectedParent, if (selectable[0].context.item) {
applicableSelectedItems: selection.filter(selectionPath => { if (selectable[0].context.item.type.includes('plot') ||
let type = selectionPath[0].context.layoutItem.type; selectable[0].context.item.type.includes('table')) {
return type === 'text-view' || type === 'telemetry-view'; sizeOptions = 'small';
}), }
property: function (selectionPath) { }
return getPath(selectionPath) + ".size"; });
},
title: "Set text size", if (sizeOptions === 'small') {
options: TEXT_SIZE.map(size => { return SMALL_FONT_SIZES;
return { } else {
value: size + "px" return SMALL_FONT_SIZES.concat(LARGE_FONT_SIZES);
}; }
}) }
};
function getFontSizeMenu(selectedParent, selection) {
if (selection.length === 1) {
let primary = selection[0][0];
let type = primary.context.layoutItem.type;
if (type === 'subobject-view') {
let objectType = primary.context.item.type;
if (objectType === 'layout' ||
objectType === 'flexible-layout' ||
objectType === 'tabs') {
return;
}
}
return {
control: 'select-menu',
domainObject: selectedParent,
icon: "icon-font-size",
applicableSelectedItems: selection,
property: (selectionPath) => {
return getPath(selectionPath) + '.fontSize';
},
title: "Set font size",
options: getAvailableFontSizeOptions(selection)
};
} else {
return {
control: 'select-menu',
domainObject: selectedParent,
icon: "icon-font-size",
applicableSelectedItems: selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
if (type === 'line-view' || type === 'box-view') {
return false;
} else if (type === 'subobject-view') {
let objectType = selectionPath[0].context.item.type;
if (objectType === 'layout' ||
objectType === 'flexible-layout' ||
objectType === 'tabs') {
return false;
}
}
return true;
}),
property: (selectionPath) => {
return getPath(selectionPath) + '.fontSize';
},
title: "Set font size",
options: getAvailableFontSizeOptions(selection)
}
}
}
function getFontMenu(selectedParent, selection) {
if (selection.length === 1) {
let primary = selection[0][0];
let type = primary.context.layoutItem.type;
if (type === 'subobject-view') {
let objectType = primary.context.item.type;
if (objectType === 'layout' ||
objectType === 'flexible-layout' ||
objectType === 'tabs') {
return;
}
}
return {
control: 'select-menu',
domainObject: selectedParent,
icon: "icon-font",
applicableSelectedItems: selection,
property: (selectionPath) => {
return getPath(selectionPath) + '.font';
},
title: "Set font style",
options: FONTS
}
} else {
return {
control: 'select-menu',
domainObject: selectedParent,
icon: "icon-font",
applicableSelectedItems: selection.filter(selectionPath => {
let type = selectionPath[0].context.layoutItem.type;
if (type === 'line-view' || type === 'box-view') {
return false;
} else if (type === 'subobject-view') {
let objectType = selectionPath[0].context.item.type;
if (objectType === 'layout' ||
objectType === 'flexible-layout' ||
objectType === 'tabs') {
return false;
}
}
return true;
}),
property: (selectionPath) => {
return getPath(selectionPath) + '.font';
},
title: "Set font style",
options: FONTS
}
}
} }
function getTextButton(selectedParent, selection) { function getTextButton(selectedParent, selection) {
@ -409,7 +630,7 @@ define(['lodash'], function (_) {
property: function (selectionPath) { property: function (selectionPath) {
return getPath(selectionPath); return getPath(selectionPath);
}, },
icon: "icon-font", icon: "icon-pencil",
title: "Edit text properties", title: "Edit text properties",
dialog: DIALOG_FORM.text dialog: DIALOG_FORM.text
}; };
@ -586,7 +807,8 @@ define(['lodash'], function (_) {
'display-mode': [], 'display-mode': [],
'telemetry-value': [], 'telemetry-value': [],
'style': [], 'style': [],
'text-style': [], 'font-size': [],
'font-family': [],
'position': [], 'position': [],
'duplicate': [], 'duplicate': [],
'remove': [] 'remove': []
@ -622,6 +844,16 @@ define(['lodash'], function (_) {
if (toolbar.viewSwitcher.length === 0) { if (toolbar.viewSwitcher.length === 0) {
toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)]; toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)];
} }
if (toolbar['font-size'].length === 0) {
toolbar['font-size'] = [
getFontSizeMenu(selectedParent, selectedObjects)
];
}
if (toolbar['font-family'].length === 0) {
toolbar['font-family'] = [
getFontMenu(selectedParent, selectedObjects)
];
}
} else if (layoutItem.type === 'telemetry-view') { } else if (layoutItem.type === 'telemetry-view') {
if (toolbar['display-mode'].length === 0) { if (toolbar['display-mode'].length === 0) {
toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selectedObjects)]; toolbar['display-mode'] = [getDisplayModeMenu(selectedParent, selectedObjects)];
@ -629,9 +861,14 @@ define(['lodash'], function (_) {
if (toolbar['telemetry-value'].length === 0) { if (toolbar['telemetry-value'].length === 0) {
toolbar['telemetry-value'] = [getTelemetryValueMenu(selectionPath, selectedObjects)]; toolbar['telemetry-value'] = [getTelemetryValueMenu(selectionPath, selectedObjects)];
} }
if (toolbar['text-style'].length === 0) { if (toolbar['font-size'].length === 0) {
toolbar['text-style'] = [ toolbar['font-size'] = [
getTextSizeMenu(selectedParent, selectedObjects) getFontSizeMenu(selectedParent, selectedObjects)
];
}
if (toolbar['font-family'].length === 0) {
toolbar['font-family'] = [
getFontMenu(selectedParent, selectedObjects)
]; ];
} }
if (toolbar.position.length === 0) { if (toolbar.position.length === 0) {
@ -650,9 +887,14 @@ define(['lodash'], function (_) {
toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)]; toolbar.viewSwitcher = [getViewSwitcherMenu(selectedParent, selectionPath, selectedObjects)];
} }
} else if (layoutItem.type === 'text-view') { } else if (layoutItem.type === 'text-view') {
if (toolbar['text-style'].length === 0) { if (toolbar['font-size'].length === 0) {
toolbar['text-style'] = [ toolbar['font-size'] = [
getTextSizeMenu(selectedParent, selectedObjects) getFontSizeMenu(selectedParent, selectedObjects)
];
}
if (toolbar['font-family'].length === 0) {
toolbar['font-family'] = [
getFontMenu(selectedParent, selectedObjects)
]; ];
} }
if (toolbar.position.length === 0) { if (toolbar.position.length === 0) {

View File

@ -29,7 +29,7 @@
@endMove="() => $emit('endMove')" @endMove="() => $emit('endMove')"
> >
<div <div
class="c-box-view" class="c-box-view u-style-receiver js-style-receiver"
:class="[styleClass]" :class="[styleClass]"
:style="style" :style="style"
></div> ></div>

View File

@ -22,7 +22,7 @@
<template> <template>
<div <div
class="l-layout" class="l-layout u-style-receiver js-style-receiver"
:class="{ :class="{
'is-multi-selected': selectedLayoutItems.length > 1, 'is-multi-selected': selectedLayoutItems.length > 1,
'allow-editing': isEditing 'allow-editing': isEditing

View File

@ -81,6 +81,7 @@ export default {
style() { style() {
let backgroundImage = 'url(' + this.item.url + ')'; let backgroundImage = 'url(' + this.item.url + ')';
let border = '1px solid ' + this.item.stroke; let border = '1px solid ' + this.item.stroke;
if (this.itemStyle) { if (this.itemStyle) {
if (this.itemStyle.imageUrl !== undefined) { if (this.itemStyle.imageUrl !== undefined) {
backgroundImage = 'url(' + this.itemStyle.imageUrl + ')'; backgroundImage = 'url(' + this.itemStyle.imageUrl + ')';

View File

@ -35,6 +35,8 @@
:object-path="currentObjectPath" :object-path="currentObjectPath"
:has-frame="item.hasFrame" :has-frame="item.hasFrame"
:show-edit-view="false" :show-edit-view="false"
:font-size="item.fontSize"
:font="item.font"
/> />
</layout-frame> </layout-frame>
</template> </template>
@ -73,6 +75,8 @@ export default {
y: position[1], y: position[1],
identifier: domainObject.identifier, identifier: domainObject.identifier,
hasFrame: hasFrameByDefault(domainObject.type), hasFrame: hasFrameByDefault(domainObject.type),
fontSize: 'default',
font: 'default',
viewKey viewKey
}; };
}, },
@ -120,7 +124,6 @@ export default {
if (!this.context) { if (!this.context) {
return; return;
} }
this.context.layoutItem = newItem; this.context.layoutItem = newItem;
} }
}, },

View File

@ -30,12 +30,14 @@
> >
<div <div
v-if="domainObject" v-if="domainObject"
class="c-telemetry-view" class="u-style-receiver c-telemetry-view"
:class="{ :class="{
styleClass, styleClass,
'is-missing': domainObject.status === 'missing' 'is-missing': domainObject.status === 'missing'
}" }"
:style="styleObject" :style="styleObject"
:data-font-size="item.fontSize"
:data-font="item.font"
@contextmenu.prevent="showContextMenu" @contextmenu.prevent="showContextMenu"
> >
<div class="is-missing__indicator" <div class="is-missing__indicator"
@ -89,7 +91,8 @@ export default {
stroke: "", stroke: "",
fill: "", fill: "",
color: "", color: "",
size: "13px" fontSize: 'default',
font: 'default'
}; };
}, },
inject: ['openmct', 'objectPath'], inject: ['openmct', 'objectPath'],
@ -136,10 +139,15 @@ export default {
return displayMode === 'all' || displayMode === 'value'; return displayMode === 'all' || displayMode === 'value';
}, },
styleObject() { styleObject() {
return Object.assign({}, { let size;
fontSize: this.item.size //for legacy size support
}, this.itemStyle); if (!this.item.fontSize) {
size = this.item.size
}
return Object.assign({}, {
size
}, this.itemStyle);
}, },
fieldName() { fieldName() {
return this.valueMetadata && this.valueMetadata.name; return this.valueMetadata && this.valueMetadata.name;

View File

@ -29,7 +29,9 @@
@endMove="() => $emit('endMove')" @endMove="() => $emit('endMove')"
> >
<div <div
class="c-text-view" class="c-text-view u-style-receiver js-style-receiver"
:data-font-size="item.fontSize"
:data-font="item.font"
:class="[styleClass]" :class="[styleClass]"
:style="style" :style="style"
> >
@ -47,13 +49,14 @@ export default {
return { return {
fill: '', fill: '',
stroke: '', stroke: '',
size: '13px',
color: '', color: '',
x: 1, x: 1,
y: 1, y: 1,
width: 10, width: 10,
height: 5, height: 5,
text: element.text text: element.text,
fontSize: 'default',
font: 'default'
}; };
}, },
inject: ['openmct'], inject: ['openmct'],
@ -84,8 +87,14 @@ export default {
}, },
computed: { computed: {
style() { style() {
let size;
//legacy size support
if (!this.item.fontSize) {
size = this.item.size;
}
return Object.assign({ return Object.assign({
fontSize: this.item.size size
}, this.itemStyle); }, this.itemStyle);
} }
}, },

View File

@ -29,7 +29,7 @@
> >
</div> </div>
<div class="c-imagery__control-bar"> <div class="c-imagery__control-bar">
<div class="c-imagery__timestamp">{{ getTime() }}</div> <div class="c-imagery__timestamp u-style-receiver js-style-receiver">{{ getTime() }}</div>
<div class="h-local-controls flex-elem"> <div class="h-local-controls flex-elem">
<button <button
class="c-button icon-pause pause-play" class="c-button icon-pause pause-play"

View File

@ -248,7 +248,8 @@ export default {
previewEmbed() { previewEmbed() {
const self = this; const self = this;
const previewAction = new PreviewAction(self.openmct); const previewAction = new PreviewAction(self.openmct);
previewAction.invoke(JSON.parse(self.embed.objectPath)); this.openmct.objects.get(self.embed.domainObject.identifier)
.then(domainObject => previewAction.invoke([domainObject]));
}, },
removeEmbed(success) { removeEmbed(success) {
if (!success) { if (!success) {

View File

@ -95,8 +95,7 @@ export const createNewEmbed = (snapshotMeta, snapshot = '') => {
id: 'embed-' + date, id: 'embed-' + date,
name, name,
snapshot, snapshot,
type, type
objectPath: JSON.stringify(objectPath)
}; };
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div <div
v-if="notifications.length > 0" v-show="notifications.length > 0"
class="c-indicator c-indicator--clickable icon-bell" class="c-indicator c-indicator--clickable icon-bell"
:class="[severityClass]" :class="[severityClass]"
> >

View File

@ -232,9 +232,9 @@
</div> </div>
</div> </div>
<div class="gl-plot-axis-area gl-plot-x"> <div class="gl-plot-axis-area gl-plot-x has-local-controls">
<mct-ticks axis="xAxis"> <mct-ticks axis="xAxis">
<div ng-repeat="tick in ticks track by tick.value" <div ng-repeat="tick in ticks track by tick.text"
class="gl-plot-tick gl-plot-x-tick-label" class="gl-plot-tick gl-plot-x-tick-label"
ng-style="{ ng-style="{
left: (100 * (tick.value - min) / interval) + '%' left: (100 * (tick.value - min) / interval) + '%'
@ -244,9 +244,21 @@
</div> </div>
</mct-ticks> </mct-ticks>
<div class="gl-plot-label gl-plot-x-label"> <div
class="gl-plot-label gl-plot-x-label"
ng-class="{'icon-gear': (xKeyOptions.length > 1 && series.length === 1)}"
>
{{ xAxis.get('label') }} {{ xAxis.get('label') }}
</div> </div>
<select
ng-if="plot.isEnabledXKeyToggle()"
ng-model="selectedXKeyOption.key"
ng-change="plot.toggleXKeyOption()"
class="gl-plot-x-label__select local-controls--hidden"
ng-options="option.key as option.name for option in xKeyOptions"
>
</select>
</div> </div>
</div> </div>

View File

@ -41,7 +41,7 @@
</button> </button>
</div> </div>
<div class="l-view-section"> <div class="l-view-section u-style-receiver js-style-receiver">
<div class="c-loading--overlay loading" <div class="c-loading--overlay loading"
ng-show="!!pending"></div> ng-show="!!pending"></div>
<mct-plot config="controller.config" <mct-plot config="controller.config"

View File

@ -40,7 +40,7 @@
title="Toggle cursor guides"> title="Toggle cursor guides">
</button> </button>
</div> </div>
<div class="l-view-section"> <div class="l-view-section u-style-receiver js-style-receiver">
<div class="c-loading--overlay loading" <div class="c-loading--overlay loading"
ng-show="!!currentRequest.pending"></div> ng-show="!!currentRequest.pending"></div>
<div class="gl-plot child-frame u-inspectable" <div class="gl-plot child-frame u-inspectable"

View File

@ -68,7 +68,6 @@ function (
this.listenTo(this.config.series, 'add', this.onSeriesAdd, this); this.listenTo(this.config.series, 'add', this.onSeriesAdd, this);
this.listenTo(this.config.series, 'remove', this.onSeriesRemove, this); this.listenTo(this.config.series, 'remove', this.onSeriesRemove, this);
this.listenTo(this.config.yAxis, 'change:key', this.clearOffset, this); this.listenTo(this.config.yAxis, 'change:key', this.clearOffset, this);
this.listenTo(this.config.xAxis, 'change:key', this.clearOffset, this);
this.listenTo(this.config.yAxis, 'change', this.scheduleDraw); this.listenTo(this.config.yAxis, 'change', this.scheduleDraw);
this.listenTo(this.config.xAxis, 'change', this.scheduleDraw); this.listenTo(this.config.xAxis, 'change', this.scheduleDraw);
this.$scope.$watch('highlights', this.scheduleDraw); this.$scope.$watch('highlights', this.scheduleDraw);
@ -81,7 +80,14 @@ function (
MCTChartController.$inject = ['$scope']; MCTChartController.$inject = ['$scope'];
MCTChartController.prototype.reDraw = function (mode, o, series) {
this.changeInterpolate(mode, o, series);
this.changeMarkers(mode, o, series);
this.changeAlarmMarkers(mode, o, series);
};
MCTChartController.prototype.onSeriesAdd = function (series) { MCTChartController.prototype.onSeriesAdd = function (series) {
this.listenTo(series, 'change:xKey', this.reDraw, this);
this.listenTo(series, 'change:interpolate', this.changeInterpolate, this); this.listenTo(series, 'change:interpolate', this.changeInterpolate, this);
this.listenTo(series, 'change:markers', this.changeMarkers, this); this.listenTo(series, 'change:markers', this.changeMarkers, this);
this.listenTo(series, 'change:alarmMarkers', this.changeAlarmMarkers, this); this.listenTo(series, 'change:alarmMarkers', this.changeAlarmMarkers, this);

View File

@ -415,6 +415,19 @@ define([
this.filters = deepCopiedFilters; this.filters = deepCopiedFilters;
} }
}, },
getDisplayRange: function (xKey) {
const unsortedData = this.data;
this.data = [];
unsortedData.forEach(point => this.add(point, false));
const minValue = this.getXVal(this.data[0]);
const maxValue = this.getXVal(this.data[this.data.length-1]);
return {
min: minValue,
max: maxValue
};
},
markerOptionsDisplayText: function () { markerOptionsDisplayText: function () {
const showMarkers = this.get('markers'); const showMarkers = this.get('markers');
if (!showMarkers) { if (!showMarkers) {

View File

@ -48,6 +48,7 @@ define([
this.set('range', this.get('range')); this.set('range', this.get('range'));
} }
this.listenTo(this, 'change:key', this.changeKey, this); this.listenTo(this, 'change:key', this.changeKey, this);
this.listenTo(this, 'resetSeries', this.resetSeries, this);
}, },
changeKey: function (newKey) { changeKey: function (newKey) {
var series = this.plot.series.first(); var series = this.plot.series.first();
@ -62,8 +63,13 @@ define([
}); });
this.set('label', newKey); this.set('label', newKey);
} }
this.plot.series.forEach(function (plotSeries) { this.plot.series.forEach(function (plotSeries) {
plotSeries.set('xKey', newKey); plotSeries.set('xKey', newKey);
});
},
resetSeries: function () {
this.plot.series.forEach(function (plotSeries) {
plotSeries.reset(); plotSeries.reset();
}); });
}, },

View File

@ -101,12 +101,32 @@ define([
this.listenTo(this.$scope, 'plot:tickWidth', this.onTickWidthChange, this); this.listenTo(this.$scope, 'plot:tickWidth', this.onTickWidthChange, this);
this.listenTo(this.$scope, 'plot:highlight:set', this.onPlotHighlightSet, this); this.listenTo(this.$scope, 'plot:highlight:set', this.onPlotHighlightSet, this);
this.listenTo(this.$scope, 'plot:reinitializeCanvas', this.initCanvas, this); this.listenTo(this.$scope, 'plot:reinitializeCanvas', this.initCanvas, this);
this.listenTo(this.config.xAxis, 'resetSeries', this.setUpXAxisOptions, this);
this.listenTo(this.config.xAxis, 'change:displayRange', this.onXAxisChange, this); this.listenTo(this.config.xAxis, 'change:displayRange', this.onXAxisChange, this);
this.listenTo(this.config.yAxis, 'change:displayRange', this.onYAxisChange, this); this.listenTo(this.config.yAxis, 'change:displayRange', this.onYAxisChange, this);
this.setUpXAxisOptions();
this.setUpYAxisOptions(); this.setUpYAxisOptions();
}; };
MCTPlotController.prototype.setUpXAxisOptions = function () {
const xAxisKey = this.config.xAxis.get('key');
if (this.$scope.series.length === 1) {
let metadata = this.$scope.series[0].metadata;
this.$scope.xKeyOptions = metadata
.valuesForHints(['domain'])
.map(function (o) {
return {
name: o.name,
key: o.key
};
});
this.$scope.selectedXKeyOption = this.getXKeyOption(xAxisKey);
}
};
MCTPlotController.prototype.setUpYAxisOptions = function () { MCTPlotController.prototype.setUpYAxisOptions = function () {
if (this.$scope.series.length === 1) { if (this.$scope.series.length === 1) {
let metadata = this.$scope.series[0].metadata; let metadata = this.$scope.series[0].metadata;
@ -520,6 +540,22 @@ define([
this.cursorGuide = !this.cursorGuide; this.cursorGuide = !this.cursorGuide;
}; };
MCTPlotController.prototype.getXKeyOption = function (key) {
return this.$scope.xKeyOptions.find(option => option.key === key);
};
MCTPlotController.prototype.isEnabledXKeyToggle = function () {
const isSinglePlot = this.$scope.xKeyOptions && this.$scope.xKeyOptions.length > 1 && this.$scope.series.length === 1;
const isFrozen = this.config.xAxis.get('frozen');
const inRealTimeMode = this.config.openmct.time.clock();
return isSinglePlot && !isFrozen && !inRealTimeMode;
};
MCTPlotController.prototype.toggleXKeyOption = function () {
this.config.xAxis.set('key', this.$scope.selectedXKeyOption.key);
};
MCTPlotController.prototype.toggleYAxisLabel = function (label, options, series) { MCTPlotController.prototype.toggleYAxisLabel = function (label, options, series) {
let yAxisObject = options.filter(o => o.name === label)[0]; let yAxisObject = options.filter(o => o.name === label)[0];

View File

@ -122,6 +122,7 @@ define([
this.tickUpdate = false; this.tickUpdate = false;
this.listenTo(this.axis, 'change:displayRange', this.updateTicks, this); this.listenTo(this.axis, 'change:displayRange', this.updateTicks, this);
this.listenTo(this.axis, 'change:format', this.updateTicks, this); this.listenTo(this.axis, 'change:format', this.updateTicks, this);
this.listenTo(this.axis, 'change:key', this.updateTicksForceRegeneration, this);
this.listenTo(this.$scope, '$destroy', this.stopListening, this); this.listenTo(this.$scope, '$destroy', this.stopListening, this);
this.updateTicks(); this.updateTicks();
} }
@ -133,12 +134,18 @@ define([
/** /**
* Determine whether ticks should be regenerated for a given range. * Determine whether ticks should be regenerated for a given range.
* Ticks are updated a) if they don't exist, b) if the existing ticks are * Ticks are updated
* outside of given range, or c) if the range exceeds the size of the tick * a) if they don't exist,
* range by more than one tick step. * b) if existing ticks are outside of given range,
* c) if range exceeds size of tick range by more than one tick step,
* d) if forced to regenerate (ex. changing x-axis metadata).
*
* @private * @private
*/ */
MCTTicksController.prototype.shouldRegenerateTicks = function (range) { MCTTicksController.prototype.shouldRegenerateTicks = function (range, forceRegeneration) {
if (forceRegeneration) {
return true;
}
if (!this.tickRange || !this.$scope.ticks || !this.$scope.ticks.length) { if (!this.tickRange || !this.$scope.ticks || !this.$scope.ticks.length) {
return true; return true;
} }
@ -166,7 +173,11 @@ define([
return ticks(range.min, range.max, number); return ticks(range.min, range.max, number);
}; };
MCTTicksController.prototype.updateTicks = function () { MCTTicksController.prototype.updateTicksForceRegeneration = function () {
this.updateTicks(true);
}
MCTTicksController.prototype.updateTicks = function (forceRegeneration = false) {
var range = this.axis.get('displayRange'); var range = this.axis.get('displayRange');
if (!range) { if (!range) {
delete this.$scope.min; delete this.$scope.min;
@ -184,7 +195,7 @@ define([
this.$scope.min = range.min; this.$scope.min = range.min;
this.$scope.max = range.max; this.$scope.max = range.max;
this.$scope.interval = Math.abs(range.min - range.max); this.$scope.interval = Math.abs(range.min - range.max);
if (this.shouldRegenerateTicks(range)) { if (this.shouldRegenerateTicks(range, forceRegeneration)) {
var newTicks = this.getTicks(); var newTicks = this.getTicks();
this.tickRange = { this.tickRange = {
min: Math.min.apply(Math, newTicks), min: Math.min.apply(Math, newTicks),
@ -242,6 +253,7 @@ define([
this.$scope.$emit('plot:tickWidth', tickWidth); this.$scope.$emit('plot:tickWidth', tickWidth);
this.shouldCheckWidth = false; this.shouldCheckWidth = false;
} }
this.$scope.$digest(); this.$scope.$digest();
this.tickUpdate = false; this.tickUpdate = false;
}; };

View File

@ -130,6 +130,9 @@ define([
}; };
PlotController.prototype.addSeries = function (series) { PlotController.prototype.addSeries = function (series) {
this.listenTo(series, 'change:xKey', function (xKey) {
this.setDisplayRange(series, xKey);
}, this);
this.listenTo(series, 'change:yKey', function () { this.listenTo(series, 'change:yKey', function () {
this.loadSeriesData(series); this.loadSeriesData(series);
}, this); }, this);
@ -141,6 +144,16 @@ define([
this.loadSeriesData(series); this.loadSeriesData(series);
}; };
PlotController.prototype.setDisplayRange = function (series, xKey) {
if (this.config.series.models.length !== 1) {
return;
}
const displayRange = series.getDisplayRange(xKey);
this.config.xAxis.set('range', displayRange);
};
PlotController.prototype.removeSeries = function (plotSeries) { PlotController.prototype.removeSeries = function (plotSeries) {
this.stopListening(plotSeries); this.stopListening(plotSeries);
}; };
@ -162,6 +175,7 @@ define([
PlotController.prototype.onTimeSystemChange = function (timeSystem) { PlotController.prototype.onTimeSystemChange = function (timeSystem) {
this.config.xAxis.set('key', timeSystem.key); this.config.xAxis.set('key', timeSystem.key);
this.config.xAxis.emit('resetSeries');
}; };
PlotController.prototype.destroy = function () { PlotController.prototype.destroy = function () {

View File

@ -46,11 +46,23 @@ define(
filter = filter.trim().toLowerCase(); filter = filter.trim().toLowerCase();
let rowsToFilter = this.getRowsToFilter(columnKey, filter); let rowsToFilter = this.getRowsToFilter(columnKey, filter);
if (filter.length === 0) { if (filter.length === 0) {
delete this.columnFilters[columnKey]; delete this.columnFilters[columnKey];
} else { } else {
this.columnFilters[columnKey] = filter; this.columnFilters[columnKey] = filter;
} }
this.rows = rowsToFilter.filter(this.matchesFilters, this);
this.emit('filter');
}
setColumnRegexFilter(columnKey, filter) {
filter = filter.trim();
let rowsToFilter = this.masterCollection.getRows();
this.columnFilters[columnKey] = new RegExp(filter);
this.rows = rowsToFilter.filter(this.matchesFilters, this); this.rows = rowsToFilter.filter(this.matchesFilters, this);
this.emit('filter'); this.emit('filter');
} }
@ -70,6 +82,10 @@ define(
* @private * @private
*/ */
isSubsetOfCurrentFilter(columnKey, filter) { isSubsetOfCurrentFilter(columnKey, filter) {
if (this.columnFilters[columnKey] instanceof RegExp) {
return false;
}
return this.columnFilters[columnKey] && return this.columnFilters[columnKey] &&
filter.startsWith(this.columnFilters[columnKey]) && filter.startsWith(this.columnFilters[columnKey]) &&
// startsWith check will otherwise fail when filter cleared // startsWith check will otherwise fail when filter cleared
@ -96,7 +112,11 @@ define(
return false; return false;
} }
doesMatchFilters = formattedValue.toLowerCase().indexOf(this.columnFilters[key]) !== -1; if (this.columnFilters[key] instanceof RegExp) {
doesMatchFilters = this.columnFilters[key].test(formattedValue);
} else {
doesMatchFilters = formattedValue.toLowerCase().indexOf(this.columnFilters[key]) !== -1;
}
}); });
return doesMatchFilters; return doesMatchFilters;
} }

View File

@ -0,0 +1,56 @@
<template>
<tr class="c-telemetry-table__sizing-tr"><td>SIZING ROW</td></tr>
</template>
<script>
export default {
props: {
isEditing: {
type: Boolean,
default: false
}
},
watch: {
isEditing: function (isEditing) {
if (isEditing) {
this.pollForRowHeight();
} else {
this.clearPoll();
}
}
},
mounted() {
this.$nextTick().then(() => {
this.height = this.$el.offsetHeight;
this.$emit('change-height', this.height);
});
if (this.isEditing) {
this.pollForRowHeight();
}
},
destroyed() {
this.clearPoll();
},
methods: {
pollForRowHeight() {
this.clearPoll();
this.pollID = window.setInterval(this.heightPoll, 300);
},
clearPoll() {
if (this.pollID) {
window.clearInterval(this.pollID);
this.pollID = undefined;
}
},
heightPoll() {
let height = this.$el.offsetHeight;
if (height !== this.height) {
this.$emit('change-height', height);
this.height = height;
}
}
}
}
</script>

View File

@ -9,6 +9,9 @@
.c-telemetry-table { .c-telemetry-table {
// Table that displays telemetry in a scrolling body area // Table that displays telemetry in a scrolling body area
@include fontAndSize();
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
justify-content: flex-start; justify-content: flex-start;
@ -112,7 +115,7 @@
display: flex; // flex-flow defaults to row nowrap (which is what we want) so no need to define display: flex; // flex-flow defaults to row nowrap (which is what we want) so no need to define
align-items: stretch; align-items: stretch;
position: absolute; position: absolute;
height: 18px; // Needed when a row has empty values in its cells min-height: 18px; // Needed when a row has empty values in its cells
&.is-selected { &.is-selected {
background-color: $colorSelectedBg !important; background-color: $colorSelectedBg !important;
@ -150,6 +153,12 @@
white-space: nowrap; white-space: nowrap;
} }
} }
&__sizing-tr {
// A row element used to determine sizing of rows based on font size
visibility: hidden;
pointer-events: none;
}
} }
/******************************* SPECIFIC CASE WRAPPERS */ /******************************* SPECIFIC CASE WRAPPERS */

View File

@ -125,7 +125,7 @@
<!-- alternate controlbar end --> <!-- alternate controlbar end -->
<div <div
class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar" class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar u-style-receiver js-style-receiver"
:class="{ :class="{
'loading': loading, 'loading': loading,
'is-paused' : paused 'is-paused' : paused
@ -190,7 +190,17 @@
class="c-table__search" class="c-table__search"
@input="filterChanged(key)" @input="filterChanged(key)"
@clear="clearFilter(key)" @clear="clearFilter(key)"
/> >
<button
class="c-search__use-regex"
:class="{ 'is-active': enableRegexSearch[key] }"
title="Click to enable regex: enter a string with slashes, like this: /regex_exp/"
@click="toggleRegex(key)"
>
/R/
</button>
</search>
</table-column-header> </table-column-header>
</tr> </tr>
</thead> </thead>
@ -234,6 +244,10 @@
class="c-telemetry-table__sizing js-telemetry-table__sizing" class="c-telemetry-table__sizing js-telemetry-table__sizing"
:style="sizingTableWidth" :style="sizingTableWidth"
> >
<sizing-row
:is-editing="isEditing"
@change-height="setRowHeight"
/>
<tr> <tr>
<template v-for="(title, key) in headers"> <template v-for="(title, key) in headers">
<th <th
@ -266,6 +280,7 @@ import TelemetryFilterIndicator from './TelemetryFilterIndicator.vue';
import CSVExporter from '../../../exporters/CSVExporter.js'; import CSVExporter from '../../../exporters/CSVExporter.js';
import _ from 'lodash'; import _ from 'lodash';
import ToggleSwitch from '../../../ui/components/ToggleSwitch.vue'; import ToggleSwitch from '../../../ui/components/ToggleSwitch.vue';
import SizingRow from './sizing-row.vue';
const VISIBLE_ROW_COUNT = 100; const VISIBLE_ROW_COUNT = 100;
const ROW_HEIGHT = 17; const ROW_HEIGHT = 17;
@ -278,7 +293,8 @@ export default {
TableColumnHeader, TableColumnHeader,
search, search,
TelemetryFilterIndicator, TelemetryFilterIndicator,
ToggleSwitch ToggleSwitch,
SizingRow
}, },
inject: ['table', 'openmct', 'objectPath'], inject: ['table', 'openmct', 'objectPath'],
props: { props: {
@ -341,7 +357,8 @@ export default {
paused: false, paused: false,
markedRows: [], markedRows: [],
isShowingMarkedRowsOnly: false, isShowingMarkedRowsOnly: false,
hideHeaders: configuration.hideHeaders hideHeaders: configuration.hideHeaders,
enableRegexSearch: {}
} }
}, },
computed: { computed: {
@ -493,7 +510,7 @@ export default {
let columnWidths = {}, let columnWidths = {},
totalWidth = 0, totalWidth = 0,
headerKeys = Object.keys(this.headers), headerKeys = Object.keys(this.headers),
sizingTableRow = this.sizingTable.children[0], sizingTableRow = this.sizingTable.children[1],
sizingCells = sizingTableRow.children; sizingCells = sizingTableRow.children;
headerKeys.forEach((headerKey, headerIndex, array)=>{ headerKeys.forEach((headerKey, headerIndex, array)=>{
@ -550,6 +567,17 @@ export default {
}, },
filterChanged(columnKey) { filterChanged(columnKey) {
this.table.filteredRows.setColumnFilter(columnKey, this.filters[columnKey]); this.table.filteredRows.setColumnFilter(columnKey, this.filters[columnKey]);
if (this.enableRegexSearch[columnKey]) {
if (this.isCompleteRegex(this.filters[columnKey])) {
this.table.filteredRows.setColumnRegexFilter(columnKey, this.filters[columnKey].slice(1,-1));
} else {
return;
}
} else {
this.table.filteredRows.setColumnFilter(columnKey, this.filters[columnKey]);
}
this.setHeight(); this.setHeight();
}, },
clearFilter(columnKey) { clearFilter(columnKey) {
@ -876,6 +904,23 @@ export default {
this.isAutosizeEnabled = true; this.isAutosizeEnabled = true;
this.$nextTick().then(this.calculateColumnWidths); this.$nextTick().then(this.calculateColumnWidths);
},
setRowHeight(height) {
this.rowHeight = height;
this.setHeight();
this.calculateTableSize();
this.clearRowsAndRerender();
},
toggleRegex(key) {
this.$set(this.filters, key, '');
if (this.enableRegexSearch[key] === undefined) {
this.$set(this.enableRegexSearch, key, true)
} else {
this.$set(this.enableRegexSearch, key, !this.enableRegexSearch[key]);
}
},
isCompleteRegex(string) {
return (string.length > 2 && string[0] === '/' && string[string.length - 1] === '/')
} }
} }
} }

View File

@ -143,7 +143,7 @@
<ConductorHistory <ConductorHistory
v-if="isFixed" v-if="isFixed"
class="c-conductor__history-select" class="c-conductor__history-select"
:bounds="openmct.time.bounds()" :bounds="bounds"
:time-system="timeSystem" :time-system="timeSystem"
/> />
</div> </div>
@ -190,6 +190,10 @@ export default {
start: offsets && durationFormatter.format(Math.abs(offsets.start)), start: offsets && durationFormatter.format(Math.abs(offsets.start)),
end: offsets && durationFormatter.format(Math.abs(offsets.end)) end: offsets && durationFormatter.format(Math.abs(offsets.end))
}, },
bounds: {
start: bounds.start,
end: bounds.end
},
formattedBounds: { formattedBounds: {
start: timeFormatter.format(bounds.start), start: timeFormatter.format(bounds.start),
end: timeFormatter.format(bounds.end) end: timeFormatter.format(bounds.end)
@ -210,7 +214,7 @@ export default {
document.addEventListener('keydown', this.handleKeyDown); document.addEventListener('keydown', this.handleKeyDown);
document.addEventListener('keyup', this.handleKeyUp); document.addEventListener('keyup', this.handleKeyUp);
this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.timeSystem()))); this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.timeSystem())));
this.openmct.time.on('bounds', this.setViewFromBounds); this.openmct.time.on('bounds', this.handleNewBounds);
this.openmct.time.on('timeSystem', this.setTimeSystem); this.openmct.time.on('timeSystem', this.setTimeSystem);
this.openmct.time.on('clock', this.setViewFromClock); this.openmct.time.on('clock', this.setViewFromClock);
this.openmct.time.on('clockOffsets', this.setViewFromOffsets) this.openmct.time.on('clockOffsets', this.setViewFromOffsets)
@ -220,6 +224,13 @@ export default {
document.removeEventListener('keyup', this.handleKeyUp); document.removeEventListener('keyup', this.handleKeyUp);
}, },
methods: { methods: {
handleNewBounds(bounds) {
this.setBounds(bounds);
this.setViewFromBounds(bounds);
},
setBounds(bounds) {
this.bounds = bounds;
},
handleKeyDown(event) { handleKeyDown(event) {
if (event.key === 'Alt') { if (event.key === 'Alt') {
this.altPressed = true; this.altPressed = true;
@ -246,10 +257,13 @@ export default {
this.formattedBounds.end = this.timeFormatter.format(bounds.end); this.formattedBounds.end = this.timeFormatter.format(bounds.end);
}, },
endZoom(bounds) { endZoom(bounds) {
const _bounds = bounds ? bounds : this.openmct.time.bounds();
this.isZooming = false; this.isZooming = false;
this.openmct.time.bounds(_bounds); if (bounds) {
this.handleNewBounds(bounds);
} else {
this.setViewFromBounds(this.bounds);
}
}, },
setTimeSystem(timeSystem) { setTimeSystem(timeSystem) {
this.timeSystem = timeSystem this.timeSystem = timeSystem

View File

@ -207,7 +207,7 @@ export default {
this.$emit('panAxis', panBounds); this.$emit('panAxis', panBounds);
}, },
endPan() { endPan() {
const panBounds = this.dragStartX && this.dragX && this.dragStartX !== this.dragX const panBounds = this.isChangingViewBounds()
? this.getPanBounds() ? this.getPanBounds()
: undefined; : undefined;
this.$emit('endPan', panBounds); this.$emit('endPan', panBounds);
@ -251,16 +251,14 @@ export default {
}); });
}, },
endZoom() { endZoom() {
const zoomRange = this.dragStartX && this.dragX && this.dragStartX !== this.dragX let zoomBounds;
? this.getZoomRange() if (this.isChangingViewBounds()) {
: undefined; const zoomRange = this.getZoomRange();
zoomBounds = {
const zoomBounds = zoomRange
? {
start: this.scaleToBounds(zoomRange.start), start: this.scaleToBounds(zoomRange.start),
end: this.scaleToBounds(zoomRange.end) end: this.scaleToBounds(zoomRange.end)
} };
: this.openmct.time.bounds(); }
this.zoomStyle = {}; this.zoomStyle = {};
this.$emit('endZoom', zoomBounds); this.$emit('endZoom', zoomBounds);
@ -289,6 +287,9 @@ export default {
const offset = valueDelta / this.width * timeDelta; const offset = valueDelta / this.width * timeDelta;
return bounds.start + offset; return bounds.start + offset;
}, },
isChangingViewBounds() {
return this.dragStartX && this.dragX && this.dragStartX !== this.dragX;
},
resize() { resize() {
if (this.$refs.axisHolder.clientWidth !== this.width) { if (this.$refs.axisHolder.clientWidth !== this.width) {
this.setAxisDimensions(); this.setAxisDimensions();

View File

@ -84,7 +84,12 @@ export default {
}, },
data() { data() {
return { return {
history: {}, // contains arrays of timespans {start, end}, array key is time system key /**
* previous bounds entries available for easy re-use
* @history array of timespans
* @timespans {start, end} number representing timestamp
*/
history: this.getHistoryFromLocalStorage(),
presets: [] presets: []
} }
}, },
@ -111,22 +116,20 @@ export default {
this.addTimespan(); this.addTimespan();
}, },
deep: true deep: true
},
history: {
handler() {
this.persistHistoryToLocalStorage();
},
deep: true
} }
}, },
mounted() { mounted() {
this.getHistoryFromLocalStorage(); this.initializeHistoryIfNoHistory();
}, },
methods: { methods: {
getHistoryFromLocalStorage() { getHistoryFromLocalStorage() {
if (localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY)) { const localStorageHistory = localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY);
this.history = JSON.parse(localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY)) const history = localStorageHistory ? JSON.parse(localStorageHistory) : undefined;
} else {
return history;
},
initializeHistoryIfNoHistory() {
if (!this.history) {
this.history = {}; this.history = {};
this.persistHistoryToLocalStorage(); this.persistHistoryToLocalStorage();
} }
@ -156,6 +159,8 @@ export default {
currentHistory.unshift(timespan); currentHistory.unshift(timespan);
this.history[key] = currentHistory; this.history[key] = currentHistory;
this.persistHistoryToLocalStorage();
}, },
selectTimespan(timespan) { selectTimespan(timespan) {
this.openmct.time.bounds(timespan); this.openmct.time.bounds(timespan);

View File

@ -102,6 +102,8 @@ $colorProgressBarHolder: rgba(black, 0.1);
$colorProgressBar: #0085ad; $colorProgressBar: #0085ad;
$progressAnimW: 500px; $progressAnimW: 500px;
$progressBarMinH: 6px; $progressBarMinH: 6px;
/************************** FONT STYLING */
$listFontSizes: 8,9,10,11,12,13,14,16,18,20,24,28,32,36,42,48,72,96,128;
/************************** GLYPH CHAR UNICODES */ /************************** GLYPH CHAR UNICODES */
$glyph-icon-alert-rect: '\e900'; $glyph-icon-alert-rect: '\e900';

View File

@ -96,6 +96,37 @@ body.desktop {
} }
} }
/******************************************************** FONTS */
@mixin fontAndSize() {
@each $size in $listFontSizes {
&[data-font-size="#{$size}"] {
font-size: #{$size}px;
// Set row heights in telemetry tables
tr {
min-height: #{$size + ($tabularTdPadTB * 2)};
}
}
}
&[data-font*="bold"] {
font-weight: bold;
}
&[data-font*="narrow"] {
font-family: 'Arial Narrow', sans-serif;
}
&[data-font*="monospace"] {
font-family: 'Andale Mono', sans-serif;
}
}
.u-style-receiver {
@include fontAndSize();
}
/******************************************************** HTML ENTITIES */ /******************************************************** HTML ENTITIES */
a { a {
color: $colorA; color: $colorA;
@ -226,7 +257,7 @@ body.desktop .has-local-controls {
} }
/******************************************************** STATES */ /******************************************************** STATES */
@mixin spinner($b: 5px, $c: $colorKey) { @mixin spinner($b: 5, $c: $colorKey) {
animation-name: rotation-centered; animation-name: rotation-centered;
animation-duration: 0.5s; animation-duration: 0.5s;
animation-iteration-count: infinite; animation-iteration-count: infinite;
@ -276,13 +307,13 @@ body.desktop .has-local-controls {
} }
&.c-tree__item { &.c-tree__item {
$d: $waitSpinnerTreeD; $d: $waitSpinnerTreeD;
$spinnerL: 19px + $d/2; $spinnerL: 19 + $d/2;
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: $spinnerL + $d/2 + $interiorMargin; padding-left: $spinnerL + $d/2 + $interiorMargin;
background: $colorLoadingBg; background: $colorLoadingBg;
min-height: 5px + $d; min-height: 5 + $d;
.c-tree__item__label { .c-tree__item__label {
font-style: italic; font-style: italic;
@ -291,7 +322,7 @@ body.desktop .has-local-controls {
&:before { &:before {
height: $d; height: $d;
width: $d; width: $d;
border-width: 4px; border-width: 4;
left: $spinnerL; left: $spinnerL;
} }
&:after { &:after {

View File

@ -27,7 +27,7 @@ mct-plot {
/*********************** STACKED PLOT LAYOUT */ /*********************** STACKED PLOT LAYOUT */
.is-editing { .is-editing {
.gl-plot.child-frame { .gl-plot.child-frame {
&:hover { @include hover {
background: rgba($editUIColorBg, 0.1); background: rgba($editUIColorBg, 0.1);
box-shadow: inset rgba($editUIColorBg, 0.3) 0 0 0 1px; box-shadow: inset rgba($editUIColorBg, 0.3) 0 0 0 1px;
} }
@ -52,6 +52,7 @@ mct-plot {
.c-control-bar { .c-control-bar {
display: none; display: none;
} }
.gl-plot-x-label__select,
.gl-plot-y-label__select { .gl-plot-y-label__select {
display: none; display: none;
} }
@ -172,6 +173,14 @@ mct-plot {
} }
} }
} }
&.gl-plot-x {
@include hover {
.gl-plot-x-label__select {
display: block;
}
}
}
} }
.gl-plot-coords { .gl-plot-coords {
@ -217,11 +226,19 @@ mct-plot {
} }
} }
.gl-plot-x-label__select {
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
z-index: 10;
}
.gl-plot-y-label__select { .gl-plot-y-label__select {
position: absolute; position: absolute;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
left: 20px; left: 0;
z-index: 10; z-index: 10;
} }

View File

@ -52,6 +52,7 @@
$ctrlW: 22px; $ctrlW: 22px;
&__controls { &__controls {
font-size: 1rem !important;
margin-right: 0; margin-right: 0;
min-width: 0; min-width: 0;
overflow: hidden; overflow: hidden;
@ -62,7 +63,7 @@
} }
&__direction { &__direction {
font-size: 0.9em; font-size: 0.9rem !important;
margin-right: $interiorMargin; margin-right: $interiorMargin;
} }

View File

@ -2,7 +2,7 @@
"metadata": { "metadata": {
"name": "Open MCT Symbols 16px", "name": "Open MCT Symbols 16px",
"lastOpened": 0, "lastOpened": 0,
"created": 1593102875898 "created": 1596146160781
}, },
"iconSets": [ "iconSets": [
{ {
@ -752,7 +752,7 @@
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 114, "order": 189,
"id": 4, "id": 4,
"name": "icon-font-size", "name": "icon-font-size",
"prevSize": 24, "prevSize": 24,
@ -2686,17 +2686,26 @@
{ {
"id": 4, "id": 4,
"paths": [ "paths": [
"M842.841 380.048h-120.956l-52.382 139.676 52.918 141.12 59.942-159.84 62.361 166.314h-119.884l34.019 90.717h119.884l39.695 105.836h105.836l-181.434-483.823z", "M1148 416h-152l-65.82 175.54 66.5 177.32 75.32-200.86 78.38 209h-150.66l42.76 114h150.64l49.88 133h133l-228-608z",
"M263.903 160.129l-263.903 703.742h153.944l57.729-153.944h280.397l57.729 153.944h153.944l-263.903-703.742zM261.154 577.976l90.717-241.911 90.717 241.911z" "M384 0l-384 1024h224l84-224h408l84 224h224l-384-1024zM380 608l132-352 132 352z"
],
"attrs": [
{},
{}
], ],
"attrs": [],
"grid": 16, "grid": 16,
"tags": [ "tags": [
"icon-font-size-alt1" "icon-font-size-alt1"
], ],
"isMulticolor": false,
"isMulticolor2": false,
"colorPermutations": { "colorPermutations": {
"12552552551": [] "12552552551": [
} {},
{}
]
},
"width": 1376
}, },
{ {
"id": 141, "id": 141,

View File

@ -100,7 +100,7 @@
<glyph unicode="&#xea2c;" glyph-name="icon-frame-hide" d="M128 642h420l104 128h-652v-802.4l128 157.4zM896 2h-420l-104-128h652v802.4l-128-157.4zM832 834l-832-1024h192l832 1024zM392 450l104 128h-304v-128z" /> <glyph unicode="&#xea2c;" glyph-name="icon-frame-hide" d="M128 642h420l104 128h-652v-802.4l128 157.4zM896 2h-420l-104-128h652v802.4l-128-157.4zM832 834l-832-1024h192l832 1024zM392 450l104 128h-304v-128z" />
<glyph unicode="&#xea2d;" glyph-name="icon-import" d="M832 639.6v-639.4c0-0.2-0.2-0.2-0.4-0.4h-319.6v-192h320c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192h-320v-192h319.6c0.2 0 0.4-0.2 0.4-0.4zM192 128v-192l384 384-384 384v-192h-192v-384z" /> <glyph unicode="&#xea2d;" glyph-name="icon-import" d="M832 639.6v-639.4c0-0.2-0.2-0.2-0.4-0.4h-319.6v-192h320c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192h-320v-192h319.6c0.2 0 0.4-0.2 0.4-0.4zM192 128v-192l384 384-384 384v-192h-192v-384z" />
<glyph unicode="&#xea2e;" glyph-name="icon-export" d="M192 0.34v639.32l0.34 0.34h319.66v192h-320c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h320v192h-319.66zM1024 320l-384 384v-192h-192v-384h192v-192l384 384z" /> <glyph unicode="&#xea2e;" glyph-name="icon-export" d="M192 0.34v639.32l0.34 0.34h319.66v192h-320c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h320v192h-319.66zM1024 320l-384 384v-192h-192v-384h192v-192l384 384z" />
<glyph unicode="&#xea2f;" glyph-name="icon-font-size" d="M842.841 451.952h-120.956l-52.382-139.676 52.918-141.12 59.942 159.84 62.361-166.314h-119.884l34.019-90.717h119.884l39.695-105.836h105.836l-181.434 483.823zM263.903 671.871l-263.903-703.742h153.944l57.729 153.944h280.397l57.729-153.944h153.944l-263.903 703.742zM261.154 254.024l90.717 241.911 90.717-241.911z" /> <glyph unicode="&#xea2f;" glyph-name="icon-font-size" horiz-adv-x="1376" d="M1148 416h-152l-65.82-175.54 66.5-177.32 75.32 200.86 78.38-209h-150.66l42.76-114h150.64l49.88-133h133l-228 608zM384 832l-384-1024h224l84 224h408l84-224h224l-384 1024zM380 224l132 352 132-352z" />
<glyph unicode="&#xea30;" glyph-name="icon-clear-data" d="M632 520l-120-120-120 120-80-80 120-120-120-120 80-80 120 120 120-120 80 80-120 120 120 120-80 80zM512 832c-282.76 0-512-86-512-192v-640c0-106 229.24-192 512-192s512 86 512 192v640c0 106-229.24 192-512 192zM512 0c-176.731 0-320 143.269-320 320s143.269 320 320 320c176.731 0 320-143.269 320-320v0c0-176.731-143.269-320-320-320v0z" /> <glyph unicode="&#xea30;" glyph-name="icon-clear-data" d="M632 520l-120-120-120 120-80-80 120-120-120-120 80-80 120 120 120-120 80 80-120 120 120 120-80 80zM512 832c-282.76 0-512-86-512-192v-640c0-106 229.24-192 512-192s512 86 512 192v640c0 106-229.24 192-512 192zM512 0c-176.731 0-320 143.269-320 320s143.269 320 320 320c176.731 0 320-143.269 320-320v0c0-176.731-143.269-320-320-320v0z" />
<glyph unicode="&#xea31;" glyph-name="icon-history" d="M576 768c-247.4 0-448-200.6-448-448h-128l192-192 192 192h-128c0 85.4 33.2 165.8 93.8 226.2 60.4 60.6 140.8 93.8 226.2 93.8s165.8-33.2 226.2-93.8c60.6-60.4 93.8-140.8 93.8-226.2s-33.2-165.8-93.8-226.2c-60.4-60.6-140.8-93.8-226.2-93.8s-165.8 33.2-226.2 93.8l-90.6-90.6c81-81 193-131.2 316.8-131.2 247.4 0 448 200.6 448 448s-200.6 448-448 448zM576 560c-26.6 0-48-21.4-48-48v-211.8l142-142c9.4-9.4 21.6-14 34-14s24.6 4.6 34 14c18.8 18.8 18.8 49.2 0 67.8l-114 114v172c0 26.6-21.4 48-48 48z" /> <glyph unicode="&#xea31;" glyph-name="icon-history" d="M576 768c-247.4 0-448-200.6-448-448h-128l192-192 192 192h-128c0 85.4 33.2 165.8 93.8 226.2 60.4 60.6 140.8 93.8 226.2 93.8s165.8-33.2 226.2-93.8c60.6-60.4 93.8-140.8 93.8-226.2s-33.2-165.8-93.8-226.2c-60.4-60.6-140.8-93.8-226.2-93.8s-165.8 33.2-226.2 93.8l-90.6-90.6c81-81 193-131.2 316.8-131.2 247.4 0 448 200.6 448 448s-200.6 448-448 448zM576 560c-26.6 0-48-21.4-48-48v-211.8l142-142c9.4-9.4 21.6-14 34-14s24.6 4.6 34 14c18.8 18.8 18.8 49.2 0 67.8l-114 114v172c0 26.6-21.4 48-48 48z" />
<glyph unicode="&#xea32;" glyph-name="icon-arrow-up-to-parent" horiz-adv-x="1056" d="M643.427 6.739c-81.955 0.697-148.179 67.065-148.642 149.010v395.872l296.871-247.393v197.914l-395.828 329.857-395.828-328.62v-197.502l296.871 246.156v-396.241c0-190.905 155.239-346.556 346.144-346.968l412.321-0.825 0.412 197.914z" /> <glyph unicode="&#xea32;" glyph-name="icon-arrow-up-to-parent" horiz-adv-x="1056" d="M643.427 6.739c-81.955 0.697-148.179 67.065-148.642 149.010v395.872l296.871-247.393v197.914l-395.828 329.857-395.828-328.62v-197.502l296.871 246.156v-396.241c0-190.905 155.239-346.556 346.144-346.968l412.321-0.825 0.412 197.914z" />

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -66,6 +66,8 @@
:object="domainObject" :object="domainObject"
:show-edit-view="showEditView" :show-edit-view="showEditView"
:object-path="objectPath" :object-path="objectPath"
:font-size="fontSize"
:font="font"
/> />
</div> </div>
</template> </template>
@ -103,6 +105,14 @@ export default {
showEditView: { showEditView: {
type: Boolean, type: Boolean,
default: true default: true
},
fontSize: {
type: String,
default: ''
},
font: {
type: String,
default: ''
} }
}, },
data() { data() {

View File

@ -20,12 +20,30 @@ export default {
default: () => { default: () => {
return []; return [];
} }
},
fontSize: {
type: String,
default: ''
},
font: {
type: String,
default: ''
} }
}, },
watch: { watch: {
object(newObject, oldObject) { object(newObject, oldObject) {
this.currentObject = newObject; this.currentObject = newObject;
this.debounceUpdateView(); this.debounceUpdateView();
},
fontSize(newSize, oldSize) {
if (newSize !== oldSize) {
this.setFontSize(newSize);
}
},
font(newFont, oldFont) {
if (newFont !== oldFont) {
this.setFont(newFont);
}
} }
}, },
destroyed() { destroyed() {
@ -63,8 +81,9 @@ export default {
if (this.currentObject) { if (this.currentObject) {
//This is to apply styles to subobjects in a layout //This is to apply styles to subobjects in a layout
this.initObjectStyles(); this.initObjectStyles();
this.setFontSize(this.fontSize);
this.setFont(this.font);
} }
}, },
methods: { methods: {
clear() { clear() {
@ -91,6 +110,15 @@ export default {
this.openmct.objectViews.off('clearData', this.clearData); this.openmct.objectViews.off('clearData', this.clearData);
}, },
getStyleReceiver() {
let styleReceiver = this.$el.querySelector('.js-style-receiver');
if (!styleReceiver) {
styleReceiver = this.$el.querySelector(':first-child');
}
return styleReceiver;
},
invokeEditModeHandler(editMode) { invokeEditModeHandler(editMode) {
let edit; let edit;
@ -111,20 +139,20 @@ export default {
return; return;
} }
let keys = Object.keys(styleObj); let keys = Object.keys(styleObj);
let elemToStyle = this.getStyleReceiver();
keys.forEach(key => { keys.forEach(key => {
let firstChild = this.$el.querySelector(':first-child'); if (elemToStyle) {
if (firstChild) {
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('__no_value') > -1)) { if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('__no_value') > -1)) {
if (firstChild.style[key]) { if (elemToStyle.style[key]) {
firstChild.style[key] = ''; elemToStyle.style[key] = '';
} }
} else { } else {
if (!styleObj.isStyleInvisible && firstChild.classList.contains(STYLE_CONSTANTS.isStyleInvisible)) { if (!styleObj.isStyleInvisible && elemToStyle.classList.contains(STYLE_CONSTANTS.isStyleInvisible)) {
firstChild.classList.remove(STYLE_CONSTANTS.isStyleInvisible); elemToStyle.classList.remove(STYLE_CONSTANTS.isStyleInvisible);
} else if (styleObj.isStyleInvisible && !firstChild.classList.contains(styleObj.isStyleInvisible)) { } else if (styleObj.isStyleInvisible && !elemToStyle.classList.contains(styleObj.isStyleInvisible)) {
firstChild.classList.add(styleObj.isStyleInvisible); elemToStyle.classList.add(styleObj.isStyleInvisible);
} }
firstChild.style[key] = styleObj[key]; elemToStyle.style[key] = styleObj[key];
} }
} }
}); });
@ -305,6 +333,14 @@ export default {
parentObject = objectPath[1]; parentObject = objectPath[1];
return [browseObject, parentObject, this.currentObject].every(object => object && !object.locked); return [browseObject, parentObject, this.currentObject].every(object => object && !object.locked);
},
setFontSize(newSize) {
let elemToStyle = this.getStyleReceiver();
elemToStyle.dataset.fontSize = newSize;
},
setFont(newFont) {
let elemToStyle = this.getStyleReceiver();
elemToStyle.dataset.font = newFont;
} }
} }
} }

View File

@ -1,3 +1,9 @@
@mixin visibleRegexButton {
opacity: 1;
padding: 1px 3px;
width: 24px;
}
.c-search { .c-search {
@include wrappedInput(); @include wrappedInput();
@ -9,8 +15,39 @@
content: $glyph-icon-magnify; content: $glyph-icon-magnify;
} }
&__use-regex {
// Button
$c: $colorBodyFg;
background: rgba($c, 0.2);
border: 1px solid rgba($c, 0.3);
color: $c;
border-radius: $controlCr;
font-weight: bold;
letter-spacing: 1px;
font-size: 0.8em;
margin-left: $interiorMarginSm;
min-width: 0;
opacity: 0;
order: 2;
overflow: hidden;
padding: 1px 0;
transform-origin: left;
transition: $transOut;
width: 0;
&.is-active {
$c: $colorBtnActiveBg;
@include visibleRegexButton();
background: rgba($c, 0.3);
border-color: $c;
color: $c;
}
}
&__clear-input { &__clear-input {
display: none; display: none;
order: 99;
padding: 1px 0;
} }
&.is-active { &.is-active {
@ -21,6 +58,15 @@
input[type='text'], input[type='text'],
input[type='search'] { input[type='search'] {
margin-left: $interiorMargin;
order: 3;
text-align: left; text-align: left;
} }
&:hover {
.c-search__use-regex {
@include visibleRegexButton();
transition: $transIn;
}
}
} }

View File

@ -15,6 +15,7 @@
class="c-search__clear-input icon-x-in-circle" class="c-search__clear-input icon-x-in-circle"
@click="clearInput" @click="clearInput"
></a> ></a>
<slot></slot>
</div> </div>
</template> </template>

View File

@ -2,7 +2,7 @@
<div class="c-inspector__header"> <div class="c-inspector__header">
<div v-if="!multiSelect" <div v-if="!multiSelect"
class="c-inspector__selected c-object-label" class="c-inspector__selected c-object-label"
:class="{'is-missing': domainObject.status === 'missing' }" :class="{'is-missing': domainObject && domainObject.status === 'missing' }"
> >
<div class="c-object-label__type-icon" <div class="c-object-label__type-icon"
:class="typeCssClass" :class="typeCssClass"

View File

@ -10,7 +10,6 @@
<span class="l-browse-bar__object-name c-object-label__name"> <span class="l-browse-bar__object-name c-object-label__name">
{{ domainObject.name }} {{ domainObject.name }}
</span> </span>
<context-menu-drop-down :object-path="objectPath" />
</div> </div>
</div> </div>
<div class="l-browse-bar__end"> <div class="l-browse-bar__end">
@ -21,12 +20,6 @@
:current-view="currentView" :current-view="currentView"
@setView="setView" @setView="setView"
/> />
<NotebookMenuSwitcher v-if="showNotebookMenuSwitcher"
:domain-object="domainObject"
:ignore-link="true"
:object-path="objectPath"
class="c-notebook-snapshot-menubutton"
/>
</div> </div>
</div> </div>
</div> </div>
@ -34,18 +27,13 @@
<script> <script>
import ContextMenuDropDown from '../../ui/components/contextMenuDropDown.vue';
import NotebookMenuSwitcher from '@/plugins/notebook/components/notebook-menu-switcher.vue';
import ViewSwitcher from '../../ui/layout/ViewSwitcher.vue'; import ViewSwitcher from '../../ui/layout/ViewSwitcher.vue';
export default { export default {
inject: [ inject: [
'openmct', 'openmct'
'objectPath'
], ],
components: { components: {
ContextMenuDropDown,
NotebookMenuSwitcher,
ViewSwitcher ViewSwitcher
}, },
props: { props: {
@ -67,12 +55,6 @@ export default {
return false; return false;
} }
}, },
showNotebookMenuSwitcher: {
type: Boolean,
default: () => {
return false;
}
},
views: { views: {
type: Array, type: Array,
default: () => { default: () => {

View File

@ -50,7 +50,7 @@ export default {
return selectedOption.name || selectedOption.value return selectedOption.name || selectedOption.value
} }
// If no selected option, then options are non-specific // If no selected option, then options are non-specific
return '??px'; return '??';
}, },
nonSpecific() { nonSpecific() {
return this.options.nonSpecific === true; return this.options.nonSpecific === true;