mirror of
https://github.com/nasa/openmct.git
synced 2025-02-21 17:57:04 +00:00
Type annotations (#4789)
* add some types to XAxisModel * some more type defs and small code tweaks while getting familiar with plots * more type annotations and a few small tweaks * more type annotations and small tweaks to make types show * add mocha types * Add karma and jasmine, too * further simplify plot canvas creation * further simplify plot canvas creation * update types, avoid runtime behavior in type definition that breaks SeriesCollection * undo the changes to MctChart, improve it later * lint fix Co-authored-by: unlikelyzero <jchill2@gmail.com> Co-authored-by: John Hill <john.c.hill@nasa.gov> Co-authored-by: Jamie V <jamie.j.vigliotta@nasa.gov>
This commit is contained in:
parent
d30ec4c757
commit
651e61954c
@ -8,6 +8,11 @@
|
|||||||
"@percy/cli": "1.0.0-beta.76",
|
"@percy/cli": "1.0.0-beta.76",
|
||||||
"@percy/playwright": "1.0.1",
|
"@percy/playwright": "1.0.1",
|
||||||
"@playwright/test": "1.19.2",
|
"@playwright/test": "1.19.2",
|
||||||
|
"@types/eventemitter3": "^1.0.0",
|
||||||
|
"@types/jasmine": "^3.10.3",
|
||||||
|
"@types/karma": "^6.3.2",
|
||||||
|
"@types/lodash": "^4.14.178",
|
||||||
|
"@types/mocha": "^9.1.0",
|
||||||
"allure-playwright": "2.0.0-beta.15",
|
"allure-playwright": "2.0.0-beta.15",
|
||||||
"babel-loader": "8.2.3",
|
"babel-loader": "8.2.3",
|
||||||
"babel-plugin-istanbul": "6.1.1",
|
"babel-plugin-istanbul": "6.1.1",
|
||||||
|
@ -365,3 +365,7 @@ class TimeContext extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default TimeContext;
|
export default TimeContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{start: number, end: number}} Bounds
|
||||||
|
*/
|
||||||
|
@ -661,7 +661,7 @@ export default {
|
|||||||
this.positionOverElement = {
|
this.positionOverElement = {
|
||||||
x: event.clientX - this.chartElementBounds.left,
|
x: event.clientX - this.chartElementBounds.left,
|
||||||
y: this.chartElementBounds.height
|
y: this.chartElementBounds.height
|
||||||
- (event.clientY - this.chartElementBounds.top)
|
- (event.clientY - this.chartElementBounds.top)
|
||||||
};
|
};
|
||||||
|
|
||||||
this.positionOverPlot = {
|
this.positionOverPlot = {
|
||||||
|
@ -112,6 +112,10 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
eventHelpers.extend(this);
|
eventHelpers.extend(this);
|
||||||
|
|
||||||
|
if (!this.axisType) {
|
||||||
|
throw new Error("axis-type prop expected");
|
||||||
|
}
|
||||||
|
|
||||||
this.axis = this.getAxisFromConfig();
|
this.axis = this.getAxisFromConfig();
|
||||||
|
|
||||||
this.tickCount = 4;
|
this.tickCount = 4;
|
||||||
@ -126,15 +130,16 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getAxisFromConfig() {
|
getAxisFromConfig() {
|
||||||
if (!this.axisType) {
|
const configId = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||||
return;
|
|
||||||
|
/** @type {import('./configuration/PlotConfigurationModel').default} */
|
||||||
|
let config = configStore.get(configId);
|
||||||
|
|
||||||
|
if (!config) {
|
||||||
|
throw new Error('config is missing');
|
||||||
}
|
}
|
||||||
|
|
||||||
const configId = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
return config[this.axisType];
|
||||||
let config = configStore.get(configId);
|
|
||||||
if (config) {
|
|
||||||
return config[this.axisType];
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Determine whether ticks should be regenerated for a given range.
|
* Determine whether ticks should be regenerated for a given range.
|
||||||
@ -210,8 +215,8 @@ export default {
|
|||||||
if (this.shouldRegenerateTicks(range, forceRegeneration)) {
|
if (this.shouldRegenerateTicks(range, forceRegeneration)) {
|
||||||
let newTicks = this.getTicks();
|
let newTicks = this.getTicks();
|
||||||
this.tickRange = {
|
this.tickRange = {
|
||||||
min: Math.min.apply(Math, newTicks),
|
min: Math.min(...newTicks),
|
||||||
max: Math.max.apply(Math, newTicks),
|
max: Math.max(...newTicks),
|
||||||
step: newTicks[1] - newTicks[0]
|
step: newTicks[1] - newTicks[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
import eventHelpers from '../lib/eventHelpers';
|
import eventHelpers from '../lib/eventHelpers';
|
||||||
|
|
||||||
export default class MCTChartAlarmLineSet {
|
export default class MCTChartAlarmLineSet {
|
||||||
|
/**
|
||||||
|
* @param {Bounds} bounds
|
||||||
|
*/
|
||||||
constructor(series, chart, offset, bounds) {
|
constructor(series, chart, offset, bounds) {
|
||||||
this.series = series;
|
this.series = series;
|
||||||
this.chart = chart;
|
this.chart = chart;
|
||||||
@ -40,6 +43,9 @@ export default class MCTChartAlarmLineSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Bounds} bounds
|
||||||
|
*/
|
||||||
updateBounds(bounds) {
|
updateBounds(bounds) {
|
||||||
this.bounds = bounds;
|
this.bounds = bounds;
|
||||||
this.getLimitPoints(this.series);
|
this.getLimitPoints(this.series);
|
||||||
@ -106,3 +112,7 @@ export default class MCTChartAlarmLineSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {import('@/api/time/TimeContext').Bounds} Bounds
|
||||||
|
*/
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
import MCTChartSeriesElement from './MCTChartSeriesElement';
|
import MCTChartSeriesElement from './MCTChartSeriesElement';
|
||||||
|
|
||||||
export default class MCTChartLineLinear extends MCTChartSeriesElement {
|
export default class MCTChartLineLinear extends MCTChartSeriesElement {
|
||||||
addPoint(point, start, count) {
|
addPoint(point, start) {
|
||||||
this.buffer[start] = point.x;
|
this.buffer[start] = point.x;
|
||||||
this.buffer[start + 1] = point.y;
|
this.buffer[start + 1] = point.y;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export default class MCTChartLineStepAfter extends MCTChartSeriesElement {
|
|||||||
return 2 + ((index - 1) * 4);
|
return 2 + ((index - 1) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
addPoint(point, start, count) {
|
addPoint(point, start) {
|
||||||
if (start === 0 && this.count === 0) {
|
if (start === 0 && this.count === 0) {
|
||||||
// First point is easy.
|
// First point is easy.
|
||||||
this.buffer[start] = point.x;
|
this.buffer[start] = point.x;
|
||||||
|
@ -24,7 +24,7 @@ import MCTChartSeriesElement from './MCTChartSeriesElement';
|
|||||||
|
|
||||||
// TODO: Is this needed? This is identical to MCTChartLineLinear. Why is it a different class?
|
// TODO: Is this needed? This is identical to MCTChartLineLinear. Why is it a different class?
|
||||||
export default class MCTChartPointSet extends MCTChartSeriesElement {
|
export default class MCTChartPointSet extends MCTChartSeriesElement {
|
||||||
addPoint(point, start, count) {
|
addPoint(point, start) {
|
||||||
this.buffer[start] = point.x;
|
this.buffer[start] = point.x;
|
||||||
this.buffer[start + 1] = point.y;
|
this.buffer[start + 1] = point.y;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
import eventHelpers from '../lib/eventHelpers';
|
import eventHelpers from '../lib/eventHelpers';
|
||||||
|
|
||||||
|
/** @abstract */
|
||||||
export default class MCTChartSeriesElement {
|
export default class MCTChartSeriesElement {
|
||||||
constructor(series, chart, offset) {
|
constructor(series, chart, offset) {
|
||||||
this.series = series;
|
this.series = series;
|
||||||
@ -72,9 +73,11 @@ export default class MCTChartSeriesElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removePoint(point, index, count) {
|
/** @abstract */
|
||||||
// by default, do nothing.
|
removePoint(index) {}
|
||||||
}
|
|
||||||
|
/** @abstract */
|
||||||
|
addPoint(point, index) {}
|
||||||
|
|
||||||
remove(point, index, series) {
|
remove(point, index, series) {
|
||||||
const vertexCount = this.vertexCountForPointAtIndex(index);
|
const vertexCount = this.vertexCountForPointAtIndex(index);
|
||||||
@ -155,3 +158,18 @@ export default class MCTChartSeriesElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/** @typedef {import('../configuration/PlotSeries').default} PlotSeries */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
x: (x: number) => number
|
||||||
|
y: (y: number) => number
|
||||||
|
xVal: (point: Point, pSeries: PlotSeries) => number
|
||||||
|
yVal: (point: Point, pSeries: PlotSeries) => number
|
||||||
|
xKey: TODO
|
||||||
|
yKey: TODO
|
||||||
|
}} Offset
|
||||||
|
*/
|
||||||
|
@ -21,11 +21,17 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import Model from './Model';
|
import Model from './Model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {object} T
|
||||||
|
* @template {object} O
|
||||||
|
* @extends {Model<T, O>}
|
||||||
|
*/
|
||||||
export default class Collection extends Model {
|
export default class Collection extends Model {
|
||||||
|
/** @type {Constructor} */
|
||||||
|
modelClass = Model;
|
||||||
|
|
||||||
initialize(options) {
|
initialize(options) {
|
||||||
super.initialize(options);
|
super.initialize(options);
|
||||||
this.modelClass = Model;
|
|
||||||
if (options.models) {
|
if (options.models) {
|
||||||
this.models = options.models.map(this.modelFn, this);
|
this.models = options.models.map(this.modelFn, this);
|
||||||
} else {
|
} else {
|
||||||
@ -107,3 +113,7 @@ export default class Collection extends Model {
|
|||||||
this.stopListening();
|
this.stopListening();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/** @typedef {new (...args: any[]) => object} Constructor */
|
||||||
|
@ -19,32 +19,47 @@
|
|||||||
* 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.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
function ConfigStore() {
|
class ConfigStore {
|
||||||
this.store = {};
|
/** @type {Record<string, Destroyable>} */
|
||||||
}
|
store = {};
|
||||||
|
|
||||||
ConfigStore.prototype.deleteStore = function (id) {
|
/**
|
||||||
if (this.store[id]) {
|
@param {string} id
|
||||||
if (this.store[id].destroy) {
|
*/
|
||||||
this.store[id].destroy();
|
deleteStore(id) {
|
||||||
|
const obj = this.store[id];
|
||||||
|
|
||||||
|
if (obj) {
|
||||||
|
if (obj.destroy) {
|
||||||
|
obj.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.store[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
delete this.store[id];
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
ConfigStore.prototype.deleteAll = function () {
|
deleteAll() {
|
||||||
Object.keys(this.store).forEach(id => this.deleteStore(id));
|
Object.keys(this.store).forEach(id => this.deleteStore(id));
|
||||||
};
|
}
|
||||||
|
|
||||||
ConfigStore.prototype.add = function (id, config) {
|
/**
|
||||||
this.store[id] = config;
|
@param {string} id
|
||||||
};
|
@param {any} config
|
||||||
|
*/
|
||||||
|
add(id, config) {
|
||||||
|
this.store[id] = config;
|
||||||
|
}
|
||||||
|
|
||||||
ConfigStore.prototype.get = function (id) {
|
/**
|
||||||
return this.store[id];
|
@param {string} id
|
||||||
};
|
*/
|
||||||
|
get(id) {
|
||||||
|
return this.store[id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const STORE = new ConfigStore();
|
const STORE = new ConfigStore();
|
||||||
|
|
||||||
export default STORE;
|
export default STORE;
|
||||||
|
|
||||||
|
/** @typedef {{destroy?(): void}} Destroyable */
|
||||||
|
@ -42,7 +42,10 @@ export default class LegendModel extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults(options) {
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
defaultModel(options) {
|
||||||
return {
|
return {
|
||||||
position: 'top',
|
position: 'top',
|
||||||
expandByDefault: false,
|
expandByDefault: false,
|
||||||
|
@ -20,11 +20,18 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import EventEmitter from 'EventEmitter';
|
import EventEmitter from 'eventemitter3';
|
||||||
import eventHelpers from "../lib/eventHelpers";
|
import eventHelpers from "../lib/eventHelpers";
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {object} T
|
||||||
|
* @template {object} O
|
||||||
|
*/
|
||||||
export default class Model extends EventEmitter {
|
export default class Model extends EventEmitter {
|
||||||
|
/**
|
||||||
|
* @param {ModelOptions<T, O>} options
|
||||||
|
*/
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -35,10 +42,14 @@ export default class Model extends EventEmitter {
|
|||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this.id is defined as a method further below, but here it is
|
||||||
|
// assigned a possibly-undefined value. Is this code unused?
|
||||||
this.id = options.id;
|
this.id = options.id;
|
||||||
|
|
||||||
|
/** @type {ModelType<T>} */
|
||||||
this.model = options.model;
|
this.model = options.model;
|
||||||
this.collection = options.collection;
|
this.collection = options.collection;
|
||||||
const defaults = this.defaults(options);
|
const defaults = this.defaultModel(options);
|
||||||
if (!this.model) {
|
if (!this.model) {
|
||||||
this.model = options.model = defaults;
|
this.model = options.model = defaults;
|
||||||
} else {
|
} else {
|
||||||
@ -46,14 +57,23 @@ export default class Model extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.initialize(options);
|
this.initialize(options);
|
||||||
|
|
||||||
|
/** @type {keyof ModelType<T> } */
|
||||||
this.idAttr = 'id';
|
this.idAttr = 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults(options) {
|
/**
|
||||||
|
* @param {ModelOptions<T, O>} options
|
||||||
|
* @returns {ModelType<T>}
|
||||||
|
*/
|
||||||
|
defaultModel(options) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize(model) {
|
/**
|
||||||
|
* @param {ModelOptions<T, O>} options
|
||||||
|
*/
|
||||||
|
initialize(options) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,14 +89,29 @@ export default class Model extends EventEmitter {
|
|||||||
return this.get(this.idAttr);
|
return this.get(this.idAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {keyof ModelType<T>} K
|
||||||
|
* @param {K} attribute
|
||||||
|
* @returns {ModelType<T>[K]}
|
||||||
|
*/
|
||||||
get(attribute) {
|
get(attribute) {
|
||||||
return this.model[attribute];
|
return this.model[attribute];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {keyof ModelType<T>} K
|
||||||
|
* @param {K} attribute
|
||||||
|
* @returns boolean
|
||||||
|
*/
|
||||||
has(attribute) {
|
has(attribute) {
|
||||||
return _.has(this.model, attribute);
|
return _.has(this.model, attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {keyof ModelType<T>} K
|
||||||
|
* @param {K} attribute
|
||||||
|
* @param {ModelType<T>[K]} value
|
||||||
|
*/
|
||||||
set(attribute, value) {
|
set(attribute, value) {
|
||||||
const oldValue = this.model[attribute];
|
const oldValue = this.model[attribute];
|
||||||
this.model[attribute] = value;
|
this.model[attribute] = value;
|
||||||
@ -84,6 +119,10 @@ export default class Model extends EventEmitter {
|
|||||||
this.emit('change:' + attribute, value, oldValue, this);
|
this.emit('change:' + attribute, value, oldValue, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {keyof ModelType<T>} K
|
||||||
|
* @param {K} attribute
|
||||||
|
*/
|
||||||
unset(attribute) {
|
unset(attribute) {
|
||||||
const oldValue = this.model[attribute];
|
const oldValue = this.model[attribute];
|
||||||
delete this.model[attribute];
|
delete this.model[attribute];
|
||||||
@ -91,3 +130,26 @@ export default class Model extends EventEmitter {
|
|||||||
this.emit('change:' + attribute, undefined, oldValue, this);
|
this.emit('change:' + attribute, undefined, oldValue, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/** @typedef {TODO} OpenMCT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@template {object} T
|
||||||
|
@typedef {{
|
||||||
|
id?: string
|
||||||
|
} & T} ModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@template {object} T
|
||||||
|
@template {object} O
|
||||||
|
@typedef {{
|
||||||
|
model?: ModelType<T>
|
||||||
|
models?: T[]
|
||||||
|
openmct: OpenMCT
|
||||||
|
id?: string
|
||||||
|
[k: string]: unknown
|
||||||
|
} & O} ModelOptions
|
||||||
|
*/
|
||||||
|
@ -26,20 +26,30 @@ import SeriesCollection from "./SeriesCollection";
|
|||||||
import XAxisModel from "./XAxisModel";
|
import XAxisModel from "./XAxisModel";
|
||||||
import YAxisModel from "./YAxisModel";
|
import YAxisModel from "./YAxisModel";
|
||||||
import LegendModel from "./LegendModel";
|
import LegendModel from "./LegendModel";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PlotConfiguration model stores the configuration of a plot and some
|
* PlotConfiguration model stores the configuration of a plot and some
|
||||||
* limited state. The indiidual parts of the plot configuration model
|
* limited state. The indiidual parts of the plot configuration model
|
||||||
* handle setting defaults and updating in response to various changes.
|
* handle setting defaults and updating in response to various changes.
|
||||||
*
|
*
|
||||||
|
* @extends {Model<PlotConfigModelType, PlotConfigModelOptions>}
|
||||||
*/
|
*/
|
||||||
export default class PlotConfigurationModel extends Model {
|
export default class PlotConfigurationModel extends Model {
|
||||||
/**
|
/**
|
||||||
* Initializes all sub models and then passes references to submodels
|
* Initializes all sub models and then passes references to submodels
|
||||||
* to those that need it.
|
* to those that need it.
|
||||||
|
*
|
||||||
|
* @override
|
||||||
|
* @param {import('./Model').ModelOptions<PlotConfigModelType, PlotConfigModelOptions>} options
|
||||||
*/
|
*/
|
||||||
initialize(options) {
|
initialize(options) {
|
||||||
this.openmct = options.openmct;
|
this.openmct = options.openmct;
|
||||||
|
|
||||||
|
// This is a type assertion for TypeScript, this error is never thrown in practice.
|
||||||
|
if (!options.model) {
|
||||||
|
throw new Error('Not a collection model.');
|
||||||
|
}
|
||||||
|
|
||||||
this.xAxis = new XAxisModel({
|
this.xAxis = new XAxisModel({
|
||||||
model: options.model.xAxis,
|
model: options.model.xAxis,
|
||||||
plot: this,
|
plot: this,
|
||||||
@ -76,6 +86,8 @@ export default class PlotConfigurationModel extends Model {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieve the persisted series config for a given identifier.
|
* Retrieve the persisted series config for a given identifier.
|
||||||
|
* @param {import('./PlotSeries').Identifier} identifier
|
||||||
|
* @returns {import('./PlotSeries').PlotSeriesModelType=}
|
||||||
*/
|
*/
|
||||||
getPersistedSeriesConfig(identifier) {
|
getPersistedSeriesConfig(identifier) {
|
||||||
const domainObject = this.get('domainObject');
|
const domainObject = this.get('domainObject');
|
||||||
@ -123,15 +135,48 @@ export default class PlotConfigurationModel extends Model {
|
|||||||
/**
|
/**
|
||||||
* Return defaults, which are extracted from the passed in domain
|
* Return defaults, which are extracted from the passed in domain
|
||||||
* object.
|
* object.
|
||||||
|
* @override
|
||||||
|
* @param {import('./Model').ModelOptions<PlotConfigModelType, PlotConfigModelOptions>} options
|
||||||
*/
|
*/
|
||||||
defaults(options) {
|
defaultModel(options) {
|
||||||
return {
|
return {
|
||||||
series: [],
|
series: [],
|
||||||
domainObject: options.domainObject,
|
domainObject: options.domainObject,
|
||||||
xAxis: {
|
xAxis: {},
|
||||||
},
|
yAxis: _.cloneDeep(options.domainObject.configuration?.yAxis ?? {}),
|
||||||
yAxis: _.cloneDeep(_.get(options.domainObject, 'configuration.yAxis', {})),
|
legend: _.cloneDeep(options.domainObject.configuration?.legend ?? {})
|
||||||
legend: _.cloneDeep(_.get(options.domainObject, 'configuration.legend', {}))
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/** @typedef {import('./PlotSeries').default} PlotSeries */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
configuration: {
|
||||||
|
series: import('./PlotSeries').PlotSeriesModelType[]
|
||||||
|
}
|
||||||
|
}} SomeDomainObject_NeedsName
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
xAxis: import('./XAxisModel').XAxisModelType
|
||||||
|
yAxis: import('./YAxisModel').YAxisModelType
|
||||||
|
legend: TODO
|
||||||
|
series: PlotSeries[]
|
||||||
|
domainObject: SomeDomainObject_NeedsName
|
||||||
|
}} PlotConfigModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @typedef {TODO} SomeOtherDomainObject */
|
||||||
|
|
||||||
|
/**
|
||||||
|
TODO: Is SomeOtherDomainObject the same domain object as with SomeDomainObject_NeedsName?
|
||||||
|
@typedef {{
|
||||||
|
plot: import('./PlotConfigurationModel').default
|
||||||
|
domainObject: SomeOtherDomainObject
|
||||||
|
}} PlotConfigModelOptions
|
||||||
|
*/
|
||||||
|
@ -59,9 +59,15 @@ import configStore from "../configuration/ConfigStore";
|
|||||||
* `metadata`: the Open MCT Telemetry Metadata Manager for the associated
|
* `metadata`: the Open MCT Telemetry Metadata Manager for the associated
|
||||||
* telemetry point.
|
* telemetry point.
|
||||||
* `formats`: the Open MCT format map for this telemetry point.
|
* `formats`: the Open MCT format map for this telemetry point.
|
||||||
|
*
|
||||||
|
* @extends {Model<PlotSeriesModelType, PlotSeriesModelOptions>}
|
||||||
*/
|
*/
|
||||||
export default class PlotSeries extends Model {
|
export default class PlotSeries extends Model {
|
||||||
|
/**
|
||||||
|
@param {import('./Model').ModelOptions<PlotSeriesModelType, PlotSeriesModelOptions>} options
|
||||||
|
*/
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
this.listenTo(this, 'change:xKey', this.onXKeyChange, this);
|
this.listenTo(this, 'change:xKey', this.onXKeyChange, this);
|
||||||
@ -76,8 +82,10 @@ export default class PlotSeries extends Model {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set defaults for telemetry series.
|
* Set defaults for telemetry series.
|
||||||
|
* @param {import('./Model').ModelOptions<PlotSeriesModelType, PlotSeriesModelOptions>} options
|
||||||
|
* @override
|
||||||
*/
|
*/
|
||||||
defaults(options) {
|
defaultModel(options) {
|
||||||
this.metadata = options
|
this.metadata = options
|
||||||
.openmct
|
.openmct
|
||||||
.telemetry
|
.telemetry
|
||||||
@ -109,13 +117,21 @@ export default class PlotSeries extends Model {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove real-time subscription when destroyed.
|
* Remove real-time subscription when destroyed.
|
||||||
|
* @override
|
||||||
*/
|
*/
|
||||||
onDestroy(model) {
|
destroy() {
|
||||||
|
super.destroy();
|
||||||
|
|
||||||
if (this.unsubscribe) {
|
if (this.unsubscribe) {
|
||||||
this.unsubscribe();
|
this.unsubscribe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set defaults for telemetry series.
|
||||||
|
* @override
|
||||||
|
* @param {import('./Model').ModelOptions<PlotSeriesModelType, PlotSeriesModelOptions>} options
|
||||||
|
*/
|
||||||
initialize(options) {
|
initialize(options) {
|
||||||
this.openmct = options.openmct;
|
this.openmct = options.openmct;
|
||||||
this.domainObject = options.domainObject;
|
this.domainObject = options.domainObject;
|
||||||
@ -136,9 +152,11 @@ export default class PlotSeries extends Model {
|
|||||||
|
|
||||||
});
|
});
|
||||||
this.openmct.time.on('bounds', this.updateLimits);
|
this.openmct.time.on('bounds', this.updateLimits);
|
||||||
this.on('destroy', this.onDestroy, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Bounds} bounds
|
||||||
|
*/
|
||||||
updateLimits(bounds) {
|
updateLimits(bounds) {
|
||||||
this.emit('limitBounds', bounds);
|
this.emit('limitBounds', bounds);
|
||||||
}
|
}
|
||||||
@ -188,7 +206,7 @@ export default class PlotSeries extends Model {
|
|||||||
return this.openmct
|
return this.openmct
|
||||||
.telemetry
|
.telemetry
|
||||||
.request(this.domainObject, options)
|
.request(this.domainObject, options)
|
||||||
.then(function (points) {
|
.then((points) => {
|
||||||
const data = this.getSeriesData();
|
const data = this.getSeriesData();
|
||||||
const newPoints = _(data)
|
const newPoints = _(data)
|
||||||
.concat(points)
|
.concat(points)
|
||||||
@ -196,7 +214,7 @@ export default class PlotSeries extends Model {
|
|||||||
.uniq(true, point => [this.getXVal(point), this.getYVal(point)].join())
|
.uniq(true, point => [this.getXVal(point), this.getYVal(point)].join())
|
||||||
.value();
|
.value();
|
||||||
this.reset(newPoints);
|
this.reset(newPoints);
|
||||||
}.bind(this))
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.warn('Error fetching data', error);
|
console.warn('Error fetching data', error);
|
||||||
});
|
});
|
||||||
@ -501,8 +519,55 @@ export default class PlotSeries extends Model {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the series data with the given value.
|
* Update the series data with the given value.
|
||||||
|
* @returns {Array<{
|
||||||
|
cos: number
|
||||||
|
sin: number
|
||||||
|
mctLimitState: {
|
||||||
|
cssClass: string
|
||||||
|
high: number
|
||||||
|
low: {sin: number, cos: number}
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
utc: number
|
||||||
|
wavelength: number
|
||||||
|
yesterday: number
|
||||||
|
}>}
|
||||||
*/
|
*/
|
||||||
getSeriesData() {
|
getSeriesData() {
|
||||||
return configStore.get(this.dataStoreId) || [];
|
return configStore.get(this.dataStoreId) || [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/** @typedef {{key: string, namespace: string}} Identifier */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
identifier: Identifier
|
||||||
|
name: string
|
||||||
|
unit: string
|
||||||
|
xKey: string
|
||||||
|
yKey: string
|
||||||
|
markers: boolean
|
||||||
|
markerShape: keyof typeof MARKER_SHAPES
|
||||||
|
markerSize: number
|
||||||
|
alarmMarkers: boolean
|
||||||
|
limitLines: boolean
|
||||||
|
interpolate: boolean
|
||||||
|
stats: TODO
|
||||||
|
}} PlotSeriesModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
model: PlotSeriesModelType
|
||||||
|
collection: import('./SeriesCollection').default
|
||||||
|
persistedConfig: PlotSeriesModelType
|
||||||
|
filters: TODO
|
||||||
|
}} PlotSeriesModelOptions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {import('@/api/time/TimeContext').Bounds} Bounds
|
||||||
|
*/
|
||||||
|
@ -26,8 +26,14 @@ import Collection from "./Collection";
|
|||||||
import Color from "@/ui/color/Color";
|
import Color from "@/ui/color/Color";
|
||||||
import ColorPalette from "@/ui/color/ColorPalette";
|
import ColorPalette from "@/ui/color/ColorPalette";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {Collection<SeriesCollectionModelType, SeriesCollectionOptions>}
|
||||||
|
*/
|
||||||
export default class SeriesCollection extends Collection {
|
export default class SeriesCollection extends Collection {
|
||||||
|
/**
|
||||||
|
@override
|
||||||
|
@param {import('./Model').ModelOptions<SeriesCollectionModelType, SeriesCollectionOptions>} options
|
||||||
|
*/
|
||||||
initialize(options) {
|
initialize(options) {
|
||||||
super.initialize(options);
|
super.initialize(options);
|
||||||
this.modelClass = PlotSeries;
|
this.modelClass = PlotSeries;
|
||||||
@ -83,11 +89,15 @@ export default class SeriesCollection extends Collection {
|
|||||||
// Clone to prevent accidental mutation by ref.
|
// Clone to prevent accidental mutation by ref.
|
||||||
seriesConfig = JSON.parse(JSON.stringify(seriesConfig));
|
seriesConfig = JSON.parse(JSON.stringify(seriesConfig));
|
||||||
|
|
||||||
|
if (!seriesConfig) {
|
||||||
|
throw "not possible";
|
||||||
|
}
|
||||||
|
|
||||||
this.add(new PlotSeries({
|
this.add(new PlotSeries({
|
||||||
model: seriesConfig,
|
model: seriesConfig,
|
||||||
domainObject: domainObject,
|
domainObject: domainObject,
|
||||||
collection: this,
|
|
||||||
openmct: this.openmct,
|
openmct: this.openmct,
|
||||||
|
collection: this,
|
||||||
persistedConfig: this.plot
|
persistedConfig: this.plot
|
||||||
.getPersistedSeriesConfig(domainObject.identifier),
|
.getPersistedSeriesConfig(domainObject.identifier),
|
||||||
filters: filters
|
filters: filters
|
||||||
@ -163,3 +173,13 @@ export default class SeriesCollection extends Collection {
|
|||||||
})[0];
|
})[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {PlotSeries} SeriesCollectionModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
plot: import('./PlotConfigurationModel').default
|
||||||
|
}} SeriesCollectionOptions
|
||||||
|
*/
|
||||||
|
@ -20,22 +20,38 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import Model from "./Model";
|
import Model from "./Model";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: doc strings.
|
* @extends {Model<XAxisModelType, XAxisModelOptions>}
|
||||||
*/
|
*/
|
||||||
export default class XAxisModel extends Model {
|
export default class XAxisModel extends Model {
|
||||||
|
// Despite providing template types to the Model class, we still need to
|
||||||
|
// re-define the type of the following initialize() method's options arg. Tracking
|
||||||
|
// issue for this: https://github.com/microsoft/TypeScript/issues/32082
|
||||||
|
// When they fix it, we can remove the `@param` we have here.
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
* @param {import('./Model').ModelOptions<XAxisModelType, XAxisModelOptions>} options
|
||||||
|
*/
|
||||||
initialize(options) {
|
initialize(options) {
|
||||||
this.plot = options.plot;
|
this.plot = options.plot;
|
||||||
|
|
||||||
|
// This is a type assertion for TypeScript, this error is not thrown in practice.
|
||||||
|
if (!options.model) {
|
||||||
|
throw new Error('Not a collection model.');
|
||||||
|
}
|
||||||
|
|
||||||
this.set('label', options.model.name || '');
|
this.set('label', options.model.name || '');
|
||||||
this.on('change:range', function (newValue, oldValue, model) {
|
|
||||||
if (!model.get('frozen')) {
|
this.on('change:range', (newValue) => {
|
||||||
model.set('displayRange', newValue);
|
if (!this.get('frozen')) {
|
||||||
|
this.set('displayRange', newValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('change:frozen', ((frozen, oldValue, model) => {
|
this.on('change:frozen', ((frozen) => {
|
||||||
if (!frozen) {
|
if (!frozen) {
|
||||||
model.set('range', this.get('range'));
|
this.set('range', this.get('range'));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -45,6 +61,10 @@ export default class XAxisModel extends Model {
|
|||||||
|
|
||||||
this.listenTo(this, 'change:key', this.changeKey, this);
|
this.listenTo(this, 'change:key', this.changeKey, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} newKey
|
||||||
|
*/
|
||||||
changeKey(newKey) {
|
changeKey(newKey) {
|
||||||
const series = this.plot.series.first();
|
const series = this.plot.series.first();
|
||||||
if (series) {
|
if (series) {
|
||||||
@ -68,12 +88,17 @@ export default class XAxisModel extends Model {
|
|||||||
plotSeries.reset();
|
plotSeries.reset();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
defaults(options) {
|
/**
|
||||||
|
* @param {import('./Model').ModelOptions<XAxisModelType, XAxisModelOptions>} options
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
defaultModel(options) {
|
||||||
const bounds = options.openmct.time.bounds();
|
const bounds = options.openmct.time.bounds();
|
||||||
const timeSystem = options.openmct.time.timeSystem();
|
const timeSystem = options.openmct.time.timeSystem();
|
||||||
const format = options.openmct.telemetry.getFormatter(timeSystem.timeFormat);
|
const format = options.openmct.telemetry.getFormatter(timeSystem.timeFormat);
|
||||||
|
|
||||||
return {
|
/** @type {XAxisModelType} */
|
||||||
|
const defaultModel = {
|
||||||
name: timeSystem.name,
|
name: timeSystem.name,
|
||||||
key: timeSystem.key,
|
key: timeSystem.key,
|
||||||
format: format.format.bind(format),
|
format: format.format.bind(format),
|
||||||
@ -83,5 +108,42 @@ export default class XAxisModel extends Model {
|
|||||||
},
|
},
|
||||||
frozen: false
|
frozen: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return defaultModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/** @typedef {TODO} OpenMCT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
min: number
|
||||||
|
max: number
|
||||||
|
}} NumberRange
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {import("./Model").ModelType<{
|
||||||
|
range: NumberRange
|
||||||
|
displayRange: NumberRange
|
||||||
|
frozen: boolean
|
||||||
|
label: string
|
||||||
|
format: (n: number) => string
|
||||||
|
values: Array<TODO>
|
||||||
|
}>} AxisModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {AxisModelType & {
|
||||||
|
name: string
|
||||||
|
key: string
|
||||||
|
}} XAxisModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
plot: import('./PlotConfigurationModel').default
|
||||||
|
}} XAxisModelOptions
|
||||||
|
*/
|
||||||
|
@ -23,27 +23,32 @@ import _ from 'lodash';
|
|||||||
import Model from './Model';
|
import Model from './Model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* YAxis model
|
* YAxis model
|
||||||
*
|
*
|
||||||
* TODO: docstrings.
|
* TODO: docstrings.
|
||||||
*
|
*
|
||||||
* has the following Model properties:
|
* has the following Model properties:
|
||||||
*
|
*
|
||||||
* `autoscale`: boolean, whether or not to autoscale.
|
* `autoscale`: boolean, whether or not to autoscale.
|
||||||
* `autoscalePadding`: float, percent of padding to display in plots.
|
* `autoscalePadding`: float, percent of padding to display in plots.
|
||||||
* `displayRange`: the current display range for the x Axis.
|
* `displayRange`: the current display range for the x Axis.
|
||||||
* `format`: the formatter for the axis.
|
* `format`: the formatter for the axis.
|
||||||
* `frozen`: boolean, if true, displayRange will not be updated automatically.
|
* `frozen`: boolean, if true, displayRange will not be updated automatically.
|
||||||
* Used to temporarily disable automatic updates during user interaction.
|
* Used to temporarily disable automatic updates during user interaction.
|
||||||
* `label`: label to display on axis.
|
* `label`: label to display on axis.
|
||||||
* `stats`: Min and Max Values of data, automatically updated by observing
|
* `stats`: Min and Max Values of data, automatically updated by observing
|
||||||
* plot series.
|
* plot series.
|
||||||
* `values`: for enumerated types, an array of possible display values.
|
* `values`: for enumerated types, an array of possible display values.
|
||||||
* `range`: the user-configured range to use for display, when autoscale is
|
* `range`: the user-configured range to use for display, when autoscale is
|
||||||
* disabled.
|
* disabled.
|
||||||
*
|
*
|
||||||
*/
|
* @extends {Model<YAxisModelType, YAxisModelOptions>}
|
||||||
|
*/
|
||||||
export default class YAxisModel extends Model {
|
export default class YAxisModel extends Model {
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
* @param {import('./Model').ModelOptions<YAxisModelType, YAxisModelOptions>} options
|
||||||
|
*/
|
||||||
initialize(options) {
|
initialize(options) {
|
||||||
this.plot = options.plot;
|
this.plot = options.plot;
|
||||||
this.listenTo(this, 'change:stats', this.calculateAutoscaleExtents, this);
|
this.listenTo(this, 'change:stats', this.calculateAutoscaleExtents, this);
|
||||||
@ -53,6 +58,9 @@ export default class YAxisModel extends Model {
|
|||||||
this.listenTo(this, 'change:range', this.updateDisplayRange, this);
|
this.listenTo(this, 'change:range', this.updateDisplayRange, this);
|
||||||
this.updateDisplayRange(this.get('range'));
|
this.updateDisplayRange(this.get('range'));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @param {import('./SeriesCollection').default} seriesCollection
|
||||||
|
*/
|
||||||
listenToSeriesCollection(seriesCollection) {
|
listenToSeriesCollection(seriesCollection) {
|
||||||
this.seriesCollection = seriesCollection;
|
this.seriesCollection = seriesCollection;
|
||||||
this.listenTo(this.seriesCollection, 'add', (series => {
|
this.listenTo(this.seriesCollection, 'add', (series => {
|
||||||
@ -138,6 +146,9 @@ export default class YAxisModel extends Model {
|
|||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @param {import('./PlotSeries').default} series
|
||||||
|
*/
|
||||||
trackSeries(series) {
|
trackSeries(series) {
|
||||||
this.listenTo(series, 'change:stats', seriesStats => {
|
this.listenTo(series, 'change:stats', seriesStats => {
|
||||||
if (!seriesStats) {
|
if (!seriesStats) {
|
||||||
@ -163,12 +174,13 @@ export default class YAxisModel extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Update yAxis format, values, and label from known series.
|
* Update yAxis format, values, and label from known series.
|
||||||
*/
|
* @param {import('./SeriesCollection').default} seriesCollection
|
||||||
updateFromSeries(series) {
|
*/
|
||||||
|
updateFromSeries(seriesCollection) {
|
||||||
const plotModel = this.plot.get('domainObject');
|
const plotModel = this.plot.get('domainObject');
|
||||||
const label = _.get(plotModel, 'configuration.yAxis.label');
|
const label = _.get(plotModel, 'configuration.yAxis.label');
|
||||||
const sampleSeries = series.first();
|
const sampleSeries = seriesCollection.first();
|
||||||
if (!sampleSeries) {
|
if (!sampleSeries) {
|
||||||
if (!label) {
|
if (!label) {
|
||||||
this.unset('label');
|
this.unset('label');
|
||||||
@ -183,7 +195,7 @@ export default class YAxisModel extends Model {
|
|||||||
this.set('format', yFormat.format.bind(yFormat));
|
this.set('format', yFormat.format.bind(yFormat));
|
||||||
this.set('values', yMetadata.values);
|
this.set('values', yMetadata.values);
|
||||||
if (!label) {
|
if (!label) {
|
||||||
const labelName = series.map(function (s) {
|
const labelName = seriesCollection.map(function (s) {
|
||||||
return s.metadata ? s.metadata.value(s.get('yKey')).name : '';
|
return s.metadata ? s.metadata.value(s.get('yKey')).name : '';
|
||||||
}).reduce(function (a, b) {
|
}).reduce(function (a, b) {
|
||||||
if (a === undefined) {
|
if (a === undefined) {
|
||||||
@ -203,7 +215,7 @@ export default class YAxisModel extends Model {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelUnits = series.map(function (s) {
|
const labelUnits = seriesCollection.map(function (s) {
|
||||||
return s.metadata ? s.metadata.value(s.get('yKey')).units : '';
|
return s.metadata ? s.metadata.value(s.get('yKey')).units : '';
|
||||||
}).reduce(function (a, b) {
|
}).reduce(function (a, b) {
|
||||||
if (a === undefined) {
|
if (a === undefined) {
|
||||||
@ -224,7 +236,13 @@ export default class YAxisModel extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaults(options) {
|
/**
|
||||||
|
* @override
|
||||||
|
* @param {import('./Model').ModelOptions<YAxisModelType, YAxisModelOptions>} options
|
||||||
|
* @returns {YAxisModelType}
|
||||||
|
*/
|
||||||
|
defaultModel(options) {
|
||||||
|
// @ts-ignore incomplete YAxisModelType object used for default value.
|
||||||
return {
|
return {
|
||||||
frozen: false,
|
frozen: false,
|
||||||
autoscale: true,
|
autoscale: true,
|
||||||
@ -232,3 +250,20 @@ export default class YAxisModel extends Model {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {any} TODO */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {import('./XAxisModel').AxisModelType & {
|
||||||
|
autoscale: boolean
|
||||||
|
autoscalePadding: number
|
||||||
|
stats: import('./XAxisModel').NumberRange
|
||||||
|
values: Array<TODO>
|
||||||
|
}} YAxisModelType
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
plot: import('./PlotConfigurationModel').default
|
||||||
|
}} YAxisModelOptions
|
||||||
|
*/
|
||||||
|
@ -110,6 +110,7 @@ DrawWebGL.prototype.onContextLost = function (event) {
|
|||||||
this.emit('error');
|
this.emit('error');
|
||||||
this.isContextLost = true;
|
this.isContextLost = true;
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
// TODO re-initialize and re-draw on context restored
|
||||||
};
|
};
|
||||||
|
|
||||||
DrawWebGL.prototype.initContext = function () {
|
DrawWebGL.prototype.initContext = function () {
|
||||||
|
@ -90,3 +90,10 @@ const helperFunctions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default helperFunctions;
|
export default helperFunctions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@typedef {{
|
||||||
|
listenTo: (object: any, event: any, callback: any, context: any) => void
|
||||||
|
stopListening: (object: any, event: any, callback: any, context: any) => void
|
||||||
|
}} EventHelpers
|
||||||
|
*/
|
||||||
|
@ -7,7 +7,14 @@
|
|||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"checkJs": false,
|
"checkJs": false,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node"
|
"moduleResolution": "node",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
// matches the alias in webpack config, so that types for those imports are visible.
|
||||||
|
"@/*": ["src/*"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user