mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 20:57:53 +00:00
Remove large series models from reactive data in plots (#6961)
* remove series object from highlights * remove series models from legend reactive data * drawing all annotations at once is way faster * fix multi annotations * lots of reactive things depending on config * make annotation lookup faster * lint * readd perf test * address PR comments * fix highlight typo --------- Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com> Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
This commit is contained in:
parent
0be106f29e
commit
8e917b2679
@ -32,7 +32,7 @@ const {
|
||||
waitForPlotsToRender
|
||||
} = require('../../appActions');
|
||||
|
||||
test.describe.fixme('Plot Tagging Performance', () => {
|
||||
test.describe('Plot Tagging Performance', () => {
|
||||
/**
|
||||
* Given a canvas and a set of points, tags the points on the canvas.
|
||||
* @param {import('@playwright/test').Page} page
|
||||
|
@ -78,8 +78,8 @@
|
||||
:rectangles="rectangles"
|
||||
:highlights="highlights"
|
||||
:show-limit-line-labels="limitLineLabels"
|
||||
:annotated-points="annotatedPoints"
|
||||
:annotation-selections="annotationSelections"
|
||||
:annotated-points-by-series="annotatedPointsBySeries"
|
||||
:annotation-selections-by-series="annotationSelectionsBySeries"
|
||||
:hidden-y-axis-ids="hiddenYAxisIds"
|
||||
:annotation-viewing-and-editing-allowed="annotationViewingAndEditingAllowed"
|
||||
@plotReinitializeCanvas="initCanvas"
|
||||
@ -245,9 +245,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
altPressed: false,
|
||||
annotatedPointsBySeries: {},
|
||||
highlights: [],
|
||||
annotatedPoints: [],
|
||||
annotationSelections: [],
|
||||
annotationSelectionsBySeries: {},
|
||||
annotationsEverLoaded: false,
|
||||
lockHighlightPoint: false,
|
||||
yKeyOptions: [],
|
||||
@ -256,8 +256,6 @@ export default {
|
||||
plotHistory: [],
|
||||
selectedXKeyOption: {},
|
||||
xKeyOptions: [],
|
||||
seriesModels: [],
|
||||
legend: {},
|
||||
pending: 0,
|
||||
isRealTime: this.openmct.time.isRealTime(),
|
||||
loaded: false,
|
||||
@ -346,6 +344,8 @@ export default {
|
||||
this.abortController = new AbortController();
|
||||
},
|
||||
mounted() {
|
||||
this.seriesModels = [];
|
||||
this.config = {};
|
||||
this.yAxisIdVisibility = {};
|
||||
this.offsetWidth = 0;
|
||||
|
||||
@ -357,7 +357,6 @@ export default {
|
||||
this.setTimeContext = this.setTimeContext.bind(this);
|
||||
|
||||
this.config = this.getConfig();
|
||||
this.legend = this.config.legend;
|
||||
this.yAxes = [
|
||||
{
|
||||
id: this.config.yAxis.id,
|
||||
@ -455,7 +454,7 @@ export default {
|
||||
const clickedOption = event.target.closest('.js-autocomplete-options') !== null;
|
||||
if (!clickedInsidePlot && !clickedInsideInspector && !clickedOption) {
|
||||
this.rectangles = [];
|
||||
this.annotationSelections = [];
|
||||
this.annotationSelectionsBySeries = {};
|
||||
this.selectPlot();
|
||||
document.body.removeEventListener('click', this.cancelSelection);
|
||||
}
|
||||
@ -639,7 +638,7 @@ export default {
|
||||
})
|
||||
);
|
||||
if (rawAnnotationsForPlot) {
|
||||
this.annotatedPoints = this.findAnnotationPoints(rawAnnotationsForPlot);
|
||||
this.annotatedPointsBySeries = this.findAnnotationPoints(rawAnnotationsForPlot);
|
||||
}
|
||||
this.annotationsEverLoaded = true;
|
||||
},
|
||||
@ -795,7 +794,7 @@ export default {
|
||||
};
|
||||
this.config.xAxis.set('range', newRange);
|
||||
if (!isTick) {
|
||||
this.annotatedPoints = [];
|
||||
this.annotatedPointsBySeries = {};
|
||||
this.clearPanZoomHistory();
|
||||
this.synchronizeIfBoundsMatch();
|
||||
this.loadMoreData(newRange, true);
|
||||
@ -1157,7 +1156,7 @@ export default {
|
||||
series.closest = series.nearestPoint(point);
|
||||
|
||||
return {
|
||||
series: series,
|
||||
seriesKeyString: series.keyString,
|
||||
point: series.closest
|
||||
};
|
||||
});
|
||||
@ -1245,7 +1244,7 @@ export default {
|
||||
|
||||
startMarquee(event, annotationEvent) {
|
||||
this.rectangles = [];
|
||||
this.annotationSelections = [];
|
||||
this.annotationSelectionsBySeries = {};
|
||||
this.canvas.classList.remove('plot-drag');
|
||||
this.canvas.classList.add('plot-marquee');
|
||||
|
||||
@ -1273,7 +1272,10 @@ export default {
|
||||
|
||||
const nearbyAnnotations = this.gatherNearbyAnnotations();
|
||||
|
||||
if (this.annotationViewingAndEditingAllowed && this.annotationSelections.length) {
|
||||
if (
|
||||
this.annotationViewingAndEditingAllowed &&
|
||||
Object.keys(this.annotationSelectionsBySeries).length
|
||||
) {
|
||||
//no annotations were found, but we are adding some now
|
||||
return;
|
||||
}
|
||||
@ -1353,20 +1355,18 @@ export default {
|
||||
|
||||
document.body.addEventListener('click', this.cancelSelection);
|
||||
},
|
||||
selectNewPlotAnnotations(boundingBoxPerYAxis, pointsInBox, event) {
|
||||
selectNewPlotAnnotations(boundingBoxPerYAxis, pointsInBoxBySeries, event) {
|
||||
let targetDomainObjects = {};
|
||||
let targetDetails = {};
|
||||
let annotations = [];
|
||||
pointsInBox.forEach((pointInBox) => {
|
||||
if (pointInBox.length) {
|
||||
const seriesID = pointInBox[0].series.keyString;
|
||||
const boundingBoxWithId = boundingBoxPerYAxis.find(
|
||||
(box) => box.id === pointInBox[0].series.get('yAxisId')
|
||||
);
|
||||
targetDetails[seriesID] = boundingBoxWithId?.boundingBox;
|
||||
Object.keys(pointsInBoxBySeries).forEach((seriesKey) => {
|
||||
const seriesModel = this.getSeries(seriesKey);
|
||||
const boundingBoxWithId = boundingBoxPerYAxis.find(
|
||||
(box) => box.id === seriesModel.get('yAxisId')
|
||||
);
|
||||
targetDetails[seriesKey] = boundingBoxWithId?.boundingBox;
|
||||
|
||||
targetDomainObjects[seriesID] = pointInBox[0].series.domainObject;
|
||||
}
|
||||
targetDomainObjects[seriesKey] = seriesModel.domainObject;
|
||||
});
|
||||
this.selectPlotAnnotations({
|
||||
targetDetails,
|
||||
@ -1375,7 +1375,7 @@ export default {
|
||||
});
|
||||
},
|
||||
findAnnotationPoints(rawAnnotations) {
|
||||
const annotationsByPoints = [];
|
||||
const annotationsBySeries = {};
|
||||
rawAnnotations.forEach((rawAnnotation) => {
|
||||
if (rawAnnotation.targets) {
|
||||
const targetValues = Object.values(rawAnnotation.targets);
|
||||
@ -1390,6 +1390,9 @@ export default {
|
||||
if (!series) {
|
||||
return;
|
||||
}
|
||||
if (!annotationsBySeries[seriesId]) {
|
||||
annotationsBySeries[seriesId] = [];
|
||||
}
|
||||
|
||||
boundingBoxPerYAxis.push({
|
||||
id: series.get('yAxisId'),
|
||||
@ -1397,15 +1400,23 @@ export default {
|
||||
});
|
||||
});
|
||||
|
||||
const pointsInBox = this.getPointsInBox(boundingBoxPerYAxis, rawAnnotation);
|
||||
if (pointsInBox && pointsInBox.length) {
|
||||
annotationsByPoints.push(pointsInBox.flat());
|
||||
const pointsInBoxBySeries = this.getPointsInBoxBySeries(
|
||||
boundingBoxPerYAxis,
|
||||
rawAnnotation
|
||||
);
|
||||
if (pointsInBoxBySeries && Object.values(pointsInBoxBySeries).length) {
|
||||
Object.keys(pointsInBoxBySeries).forEach((seriesKeyString) => {
|
||||
const pointsInBox = pointsInBoxBySeries[seriesKeyString];
|
||||
if (pointsInBox && pointsInBox.length) {
|
||||
annotationsBySeries[seriesKeyString].push(...pointsInBox);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return annotationsByPoints.flat();
|
||||
return annotationsBySeries;
|
||||
},
|
||||
searchWithFlatbush(seriesData, seriesModel, boundingBox) {
|
||||
const flatbush = new Flatbush(seriesData.length);
|
||||
@ -1425,9 +1436,15 @@ export default {
|
||||
|
||||
return rangeResults;
|
||||
},
|
||||
getPointsInBox(boundingBoxPerYAxis, rawAnnotation) {
|
||||
getSeries(keyStringToFind) {
|
||||
const foundSeries = this.seriesModels.find((series) => {
|
||||
return series.keyString === keyStringToFind;
|
||||
});
|
||||
return foundSeries;
|
||||
},
|
||||
getPointsInBoxBySeries(boundingBoxPerYAxis, rawAnnotation) {
|
||||
// load series models in KD-Trees
|
||||
const seriesKDTrees = [];
|
||||
const searchResultsBySeries = {};
|
||||
this.seriesModels.forEach((seriesModel) => {
|
||||
const boundingBoxWithId = boundingBoxPerYAxis.find(
|
||||
(box) => box.id === seriesModel.get('yAxisId')
|
||||
@ -1440,16 +1457,15 @@ export default {
|
||||
|
||||
const seriesData = seriesModel.getSeriesData();
|
||||
if (seriesData && seriesData.length) {
|
||||
const searchResults = [];
|
||||
searchResultsBySeries[seriesModel.keyString] = [];
|
||||
const rangeResults = this.searchWithFlatbush(seriesData, seriesModel, boundingBox);
|
||||
rangeResults.forEach((id) => {
|
||||
const seriesDatum = seriesData[id];
|
||||
if (seriesDatum) {
|
||||
const result = {
|
||||
series: seriesModel,
|
||||
point: seriesDatum
|
||||
};
|
||||
searchResults.push(result);
|
||||
searchResultsBySeries[seriesModel.keyString].push(result);
|
||||
}
|
||||
|
||||
if (rawAnnotation) {
|
||||
@ -1463,13 +1479,10 @@ export default {
|
||||
seriesDatum.annotationsById[annotationKeyString] = rawAnnotation;
|
||||
}
|
||||
});
|
||||
if (searchResults.length) {
|
||||
seriesKDTrees.push(searchResults);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return seriesKDTrees;
|
||||
return searchResultsBySeries;
|
||||
},
|
||||
endAnnotationMarquee(event) {
|
||||
const boundingBoxPerYAxis = [];
|
||||
@ -1490,13 +1503,13 @@ export default {
|
||||
});
|
||||
});
|
||||
|
||||
const pointsInBox = this.getPointsInBox(boundingBoxPerYAxis);
|
||||
if (!pointsInBox) {
|
||||
const pointsInBoxBySeries = this.getPointsInBoxBySeries(boundingBoxPerYAxis);
|
||||
if (!pointsInBoxBySeries || Object.values(pointsInBoxBySeries).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.annotationSelections = pointsInBox.flat();
|
||||
this.selectNewPlotAnnotations(boundingBoxPerYAxis, pointsInBox, event);
|
||||
this.annotationSelectionsBySeries = pointsInBoxBySeries;
|
||||
this.selectNewPlotAnnotations(boundingBoxPerYAxis, this.annotationSelectionsBySeries, event);
|
||||
},
|
||||
endZoomMarquee() {
|
||||
const startPixels = this.marquee.startPixels;
|
||||
|
@ -101,16 +101,16 @@ export default {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
annotatedPoints: {
|
||||
type: Array,
|
||||
annotatedPointsBySeries: {
|
||||
type: Object,
|
||||
default() {
|
||||
return [];
|
||||
return {};
|
||||
}
|
||||
},
|
||||
annotationSelections: {
|
||||
type: Array,
|
||||
annotationSelectionsBySeries: {
|
||||
type: Object,
|
||||
default() {
|
||||
return [];
|
||||
return {};
|
||||
}
|
||||
},
|
||||
showLimitLineLabels: {
|
||||
@ -143,17 +143,15 @@ export default {
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
annotatedPoints: {
|
||||
annotatedPointsBySeries: {
|
||||
handler() {
|
||||
this.scheduleDraw();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
annotationSelections: {
|
||||
annotationSelectionsBySeries: {
|
||||
handler() {
|
||||
this.scheduleDraw();
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
rectangles: {
|
||||
handler() {
|
||||
@ -177,6 +175,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
eventHelpers.extend(this);
|
||||
this.seriesModels = [];
|
||||
this.config = this.getConfig();
|
||||
this.isDestroyed = false;
|
||||
this.lines = [];
|
||||
@ -256,7 +255,8 @@ export default {
|
||||
this.changeAlarmMarkers(newXKey, oldXKey, series);
|
||||
this.changeLimitLines(newXKey, oldXKey, series);
|
||||
},
|
||||
onSeriesAdd(series) {
|
||||
onSeriesAdd(series, index) {
|
||||
this.seriesModels[index] = series;
|
||||
this.listenTo(series, `change:${HANDLED_ATTRIBUTES.xKey}`, this.reDraw, this);
|
||||
this.listenTo(
|
||||
series,
|
||||
@ -280,10 +280,15 @@ export default {
|
||||
this.makeChartElement(series);
|
||||
this.makeLimitLines(series);
|
||||
},
|
||||
onSeriesRemove(series) {
|
||||
this.stopListening(series);
|
||||
this.removeChartElement(series);
|
||||
onSeriesRemove(seriesToRemove) {
|
||||
this.stopListening(seriesToRemove);
|
||||
this.removeChartElement(seriesToRemove);
|
||||
this.scheduleDraw();
|
||||
|
||||
const seriesIndexToRemove = this.seriesModels.findIndex(
|
||||
(series) => series.keyString === seriesToRemove.keyString
|
||||
);
|
||||
this.seriesModels.splice(seriesIndexToRemove, 1);
|
||||
},
|
||||
onAddPoint(point, insertIndex, series) {
|
||||
const mainYAxisId = this.config.yAxis.get('id');
|
||||
@ -642,8 +647,8 @@ export default {
|
||||
this.drawHighlights(id);
|
||||
// only draw these in fixed time mode or plot is paused
|
||||
if (this.annotationViewingAndEditingAllowed) {
|
||||
this.drawAnnotatedPoints(id);
|
||||
this.drawAnnotationSelections(id);
|
||||
this.prepareToDrawAnnotatedPoints(id);
|
||||
this.prepareToDrawAnnotationSelections(id);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -698,6 +703,7 @@ export default {
|
||||
pointSets.forEach(this.drawPoints, this);
|
||||
const alarmSets = this.alarmSets.filter(this.matchByYAxisId.bind(this, id));
|
||||
alarmSets.forEach(this.drawAlarmPoints, this);
|
||||
//console.timeEnd('📈 drawSeries');
|
||||
},
|
||||
updateLimitLines() {
|
||||
Array.from(this.$refs.limitArea.children).forEach((el) => el.remove());
|
||||
@ -827,82 +833,110 @@ export default {
|
||||
);
|
||||
}
|
||||
},
|
||||
drawAnnotatedPoints(yAxisId) {
|
||||
// we should do this by series, and then plot all the points at once instead
|
||||
// of doing it one by one
|
||||
if (this.annotatedPoints && this.annotatedPoints.length) {
|
||||
const uniquePointsToDraw = [];
|
||||
prepareToDrawAnnotatedPoints(yAxisId) {
|
||||
if (this.annotatedPointsBySeries && Object.values(this.annotatedPointsBySeries).length) {
|
||||
const uniquePointsToDraw = new Set();
|
||||
|
||||
const annotatedPoints = this.annotatedPoints.filter(
|
||||
this.matchByYAxisId.bind(this, yAxisId)
|
||||
);
|
||||
annotatedPoints.forEach((annotatedPoint) => {
|
||||
Object.keys(this.annotatedPointsBySeries).forEach((seriesKeyString) => {
|
||||
const seriesModel = this.getSeries(seriesKeyString);
|
||||
const matchesYAxis = this.matchByYAxisId(yAxisId, { series: seriesModel });
|
||||
if (!matchesYAxis) {
|
||||
return;
|
||||
}
|
||||
// annotation points are all within range (checked in MctPlot with FlatBush), so we don't need to check
|
||||
const canvasXValue = this.offset[yAxisId].xVal(
|
||||
annotatedPoint.point,
|
||||
annotatedPoint.series
|
||||
const annotatedPointBuffer = new Float32Array(
|
||||
this.annotatedPointsBySeries[seriesKeyString].length * 2
|
||||
);
|
||||
const canvasYValue = this.offset[yAxisId].yVal(
|
||||
annotatedPoint.point,
|
||||
annotatedPoint.series
|
||||
Object.values(this.annotatedPointsBySeries[seriesKeyString]).forEach(
|
||||
(annotatedPoint, index) => {
|
||||
const canvasXValue = this.offset[yAxisId].xVal(annotatedPoint.point, seriesModel);
|
||||
const canvasYValue = this.offset[yAxisId].yVal(annotatedPoint.point, seriesModel);
|
||||
const drawnPointKey = `${canvasXValue}|${canvasYValue}`;
|
||||
if (!uniquePointsToDraw.has(drawnPointKey)) {
|
||||
annotatedPointBuffer[index * 2] = canvasXValue;
|
||||
annotatedPointBuffer[index * 2 + 1] = canvasYValue;
|
||||
uniquePointsToDraw.add(drawnPointKey);
|
||||
}
|
||||
}
|
||||
);
|
||||
const pointToDraw = new Float32Array([canvasXValue, canvasYValue]);
|
||||
const drawnPoint = uniquePointsToDraw.some((rawPoint) => {
|
||||
return rawPoint[0] === pointToDraw[0] && rawPoint[1] === pointToDraw[1];
|
||||
});
|
||||
if (!drawnPoint) {
|
||||
uniquePointsToDraw.push(pointToDraw);
|
||||
this.drawAnnotatedPoint(annotatedPoint, pointToDraw);
|
||||
this.drawAnnotatedPoints(seriesModel, annotatedPointBuffer);
|
||||
});
|
||||
}
|
||||
},
|
||||
drawAnnotatedPoints(seriesModel, annotatedPointBuffer) {
|
||||
if (annotatedPointBuffer && seriesModel) {
|
||||
const color = seriesModel.get('color').asRGBAArray();
|
||||
// set transparency
|
||||
color[3] = 0.15;
|
||||
const pointCount = annotatedPointBuffer.length / 2;
|
||||
const shape = seriesModel.get('markerShape');
|
||||
|
||||
this.drawAPI.drawPoints(annotatedPointBuffer, color, pointCount, ANNOTATION_SIZE, shape);
|
||||
}
|
||||
},
|
||||
prepareToDrawAnnotationSelections(yAxisId) {
|
||||
if (
|
||||
this.annotationSelectionsBySeries &&
|
||||
Object.keys(this.annotationSelectionsBySeries).length
|
||||
) {
|
||||
Object.keys(this.annotationSelectionsBySeries).forEach((seriesKeyString) => {
|
||||
const seriesModel = this.getSeries(seriesKeyString);
|
||||
const matchesYAxis = this.matchByYAxisId(yAxisId, { series: seriesModel });
|
||||
if (matchesYAxis) {
|
||||
const annotationSelectionBuffer = new Float32Array(
|
||||
this.annotationSelectionsBySeries[seriesKeyString].length * 2
|
||||
);
|
||||
Object.values(this.annotationSelectionsBySeries[seriesKeyString]).forEach(
|
||||
(annotatedSelectedPoint, index) => {
|
||||
const canvasXValue = this.offset[yAxisId].xVal(
|
||||
annotatedSelectedPoint.point,
|
||||
seriesModel
|
||||
);
|
||||
const canvasYValue = this.offset[yAxisId].yVal(
|
||||
annotatedSelectedPoint.point,
|
||||
seriesModel
|
||||
);
|
||||
annotationSelectionBuffer[index * 2] = canvasXValue;
|
||||
annotationSelectionBuffer[index * 2 + 1] = canvasYValue;
|
||||
}
|
||||
);
|
||||
this.drawAnnotationSelections(seriesModel, annotationSelectionBuffer);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
drawAnnotatedPoint(annotatedPoint, pointToDraw) {
|
||||
if (annotatedPoint.point && annotatedPoint.series) {
|
||||
const color = annotatedPoint.series.get('color').asRGBAArray();
|
||||
// set transparency
|
||||
color[3] = 0.15;
|
||||
const pointCount = 1;
|
||||
const shape = annotatedPoint.series.get('markerShape');
|
||||
|
||||
this.drawAPI.drawPoints(pointToDraw, color, pointCount, ANNOTATION_SIZE, shape);
|
||||
}
|
||||
},
|
||||
drawAnnotationSelections(yAxisId) {
|
||||
if (this.annotationSelections && this.annotationSelections.length) {
|
||||
const annotationSelections = this.annotationSelections.filter(
|
||||
this.matchByYAxisId.bind(this, yAxisId)
|
||||
);
|
||||
annotationSelections.forEach(this.drawAnnotationSelection.bind(this, yAxisId), this);
|
||||
}
|
||||
},
|
||||
drawAnnotationSelection(yAxisId, annotationSelection) {
|
||||
const points = new Float32Array([
|
||||
this.offset[yAxisId].xVal(annotationSelection.point, annotationSelection.series),
|
||||
this.offset[yAxisId].yVal(annotationSelection.point, annotationSelection.series)
|
||||
]);
|
||||
|
||||
drawAnnotationSelections(seriesModel, annotationSelectionBuffer) {
|
||||
const color = [255, 255, 255, 1]; // white
|
||||
const pointCount = 1;
|
||||
const shape = annotationSelection.series.get('markerShape');
|
||||
const pointCount = annotationSelectionBuffer.length / 2;
|
||||
const shape = seriesModel.get('markerShape');
|
||||
|
||||
this.drawAPI.drawPoints(points, color, pointCount, ANNOTATION_SIZE, shape);
|
||||
this.drawAPI.drawPoints(annotationSelectionBuffer, color, pointCount, ANNOTATION_SIZE, shape);
|
||||
},
|
||||
drawHighlights(yAxisId) {
|
||||
if (this.highlights && this.highlights.length) {
|
||||
const highlights = this.highlights.filter(this.matchByYAxisId.bind(this, yAxisId));
|
||||
const highlights = this.highlights.filter((highlight) => {
|
||||
const series = this.getSeries(highlight.seriesKeyString);
|
||||
return this.matchByYAxisId.bind(yAxisId, { series });
|
||||
});
|
||||
highlights.forEach(this.drawHighlight.bind(this, yAxisId), this);
|
||||
}
|
||||
},
|
||||
getSeries(keyStringToFind) {
|
||||
const foundSeries = this.seriesModels.find((series) => {
|
||||
return series.keyString === keyStringToFind;
|
||||
});
|
||||
return foundSeries;
|
||||
},
|
||||
drawHighlight(yAxisId, highlight) {
|
||||
const series = this.getSeries(highlight.seriesKeyString);
|
||||
const points = new Float32Array([
|
||||
this.offset[yAxisId].xVal(highlight.point, highlight.series),
|
||||
this.offset[yAxisId].yVal(highlight.point, highlight.series)
|
||||
this.offset[yAxisId].xVal(highlight.point, series),
|
||||
this.offset[yAxisId].yVal(highlight.point, series)
|
||||
]);
|
||||
|
||||
const color = highlight.series.get('color').asRGBAArray();
|
||||
const color = series.get('color').asRGBAArray();
|
||||
const pointCount = 1;
|
||||
const shape = highlight.series.get('markerShape');
|
||||
const shape = series.get('markerShape');
|
||||
|
||||
this.drawAPI.drawPoints(points, color, pointCount, HIGHLIGHT_SIZE, shape);
|
||||
},
|
||||
|
@ -45,7 +45,7 @@
|
||||
:key="`${seriesObject.keyString}-${seriesIndex}-collapsed`"
|
||||
:highlights="highlights"
|
||||
:value-to-show-when-collapsed="valueToShowWhenCollapsed"
|
||||
:series-object="seriesObject"
|
||||
:series-key-string="seriesObject.keyString"
|
||||
@legendHoverChanged="legendHoverChanged"
|
||||
/>
|
||||
</div>
|
||||
@ -72,7 +72,7 @@
|
||||
<plot-legend-item-expanded
|
||||
v-for="(seriesObject, seriesIndex) in seriesModels"
|
||||
:key="`${seriesObject.keyString}-${seriesIndex}-expanded`"
|
||||
:series-object="seriesObject"
|
||||
:series-key-string="seriesObject.keyString"
|
||||
:highlights="highlights"
|
||||
@legendHoverChanged="legendHoverChanged"
|
||||
/>
|
||||
|
@ -71,12 +71,9 @@ export default {
|
||||
mixins: [stalenessMixin, tooltipHelpers],
|
||||
inject: ['openmct', 'domainObject'],
|
||||
props: {
|
||||
seriesObject: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
seriesKeyString: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
highlights: {
|
||||
type: Array,
|
||||
@ -112,7 +109,7 @@ export default {
|
||||
highlights: {
|
||||
handler(newHighlights) {
|
||||
const highlightedObject = newHighlights.find(
|
||||
(highlight) => highlight.series.keyString === this.seriesObject.keyString
|
||||
(highlight) => highlight.seriesKeyString === this.seriesKeyString
|
||||
);
|
||||
if (newHighlights.length === 0 || highlightedObject) {
|
||||
this.initialize(highlightedObject);
|
||||
@ -122,28 +119,14 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.seriesModels = [];
|
||||
eventHelpers.extend(this);
|
||||
this.config = this.getConfig();
|
||||
this.listenTo(this.config.series, 'add', this.onSeriesAdd, this);
|
||||
this.listenTo(this.config.series, 'remove', this.onSeriesRemove, this);
|
||||
this.config.series.forEach(this.onSeriesAdd, this);
|
||||
this.legend = this.config.legend;
|
||||
this.loaded = true;
|
||||
this.listenTo(
|
||||
this.seriesObject,
|
||||
'change:color',
|
||||
(newColor) => {
|
||||
this.updateColor(newColor);
|
||||
},
|
||||
this
|
||||
);
|
||||
this.listenTo(
|
||||
this.seriesObject,
|
||||
'change:name',
|
||||
() => {
|
||||
this.updateName();
|
||||
},
|
||||
this
|
||||
);
|
||||
this.subscribeToStaleness(this.seriesObject.domainObject);
|
||||
this.initialize();
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.stopListening();
|
||||
@ -154,8 +137,44 @@ export default {
|
||||
|
||||
return configStore.get(configId);
|
||||
},
|
||||
onSeriesAdd(series, index) {
|
||||
this.seriesModels[index] = series;
|
||||
if (series.keyString === this.seriesKeyString) {
|
||||
this.listenTo(
|
||||
series,
|
||||
'change:color',
|
||||
(newColor) => {
|
||||
this.updateColor(newColor);
|
||||
},
|
||||
this
|
||||
);
|
||||
this.listenTo(
|
||||
series,
|
||||
'change:name',
|
||||
() => {
|
||||
this.updateName();
|
||||
},
|
||||
this
|
||||
);
|
||||
this.subscribeToStaleness(series.domainObject);
|
||||
this.initialize();
|
||||
}
|
||||
},
|
||||
onSeriesRemove(seriesToRemove) {
|
||||
const seriesIndexToRemove = this.seriesModels.findIndex(
|
||||
(series) => series.keyString === seriesToRemove.keyString
|
||||
);
|
||||
this.seriesModels.splice(seriesIndexToRemove, 1);
|
||||
},
|
||||
getSeries(keyStringToFind) {
|
||||
const foundSeries = this.seriesModels.find((series) => {
|
||||
return series.keyString === keyStringToFind;
|
||||
});
|
||||
return foundSeries;
|
||||
},
|
||||
initialize(highlightedObject) {
|
||||
const seriesObject = highlightedObject?.series || this.seriesObject;
|
||||
const seriesKeyStringToUse = highlightedObject?.seriesKeyString || this.seriesKeyString;
|
||||
const seriesObject = this.getSeries(seriesKeyStringToUse);
|
||||
|
||||
this.isMissing = seriesObject.domainObject.status === 'missing';
|
||||
this.colorAsHexString = seriesObject.get('color').asHexString();
|
||||
@ -187,7 +206,8 @@ export default {
|
||||
this.colorAsHexString = newColor.asHexString();
|
||||
},
|
||||
updateName() {
|
||||
this.nameWithUnit = this.seriesObject.nameWithUnit();
|
||||
const seriesObject = this.getSeries(this.seriesKeyString);
|
||||
this.nameWithUnit = seriesObject.nameWithUnit();
|
||||
},
|
||||
toggleHover(hover) {
|
||||
this.hover = hover;
|
||||
@ -195,15 +215,16 @@ export default {
|
||||
'legendHoverChanged',
|
||||
this.hover
|
||||
? {
|
||||
seriesKey: this.seriesObject.keyString
|
||||
seriesKey: this.seriesKeyString
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
},
|
||||
async showToolTip() {
|
||||
const seriesObject = this.getSeries(this.seriesKeyString);
|
||||
const { BELOW } = this.openmct.tooltips.TOOLTIP_LOCATIONS;
|
||||
this.buildToolTip(
|
||||
await this.getTelemetryPathString(this.seriesObject.domainObject.identifier),
|
||||
await this.getTelemetryPathString(seriesObject.domainObject.identifier),
|
||||
BELOW,
|
||||
'series'
|
||||
);
|
||||
|
@ -86,12 +86,9 @@ export default {
|
||||
mixins: [stalenessMixin, tooltipHelpers],
|
||||
inject: ['openmct', 'domainObject'],
|
||||
props: {
|
||||
seriesObject: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
seriesKeyString: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
highlights: {
|
||||
type: Array,
|
||||
@ -135,7 +132,7 @@ export default {
|
||||
highlights: {
|
||||
handler(newHighlights) {
|
||||
const highlightedObject = newHighlights.find(
|
||||
(highlight) => highlight.series.keyString === this.seriesObject.keyString
|
||||
(highlight) => highlight.seriesKeyString === this.seriesKeyString
|
||||
);
|
||||
if (newHighlights.length === 0 || highlightedObject) {
|
||||
this.initialize(highlightedObject);
|
||||
@ -145,40 +142,62 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.seriesModels = [];
|
||||
eventHelpers.extend(this);
|
||||
this.config = this.getConfig();
|
||||
this.listenTo(this.config.series, 'add', this.onSeriesAdd, this);
|
||||
this.listenTo(this.config.series, 'remove', this.onSeriesRemove, this);
|
||||
this.config.series.forEach(this.onSeriesAdd, this);
|
||||
this.legend = this.config.legend;
|
||||
this.loaded = true;
|
||||
this.listenTo(
|
||||
this.seriesObject,
|
||||
'change:color',
|
||||
(newColor) => {
|
||||
this.updateColor(newColor);
|
||||
},
|
||||
this
|
||||
);
|
||||
this.listenTo(
|
||||
this.seriesObject,
|
||||
'change:name',
|
||||
() => {
|
||||
this.updateName();
|
||||
},
|
||||
this
|
||||
);
|
||||
this.subscribeToStaleness(this.seriesObject.domainObject);
|
||||
this.initialize();
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.stopListening();
|
||||
},
|
||||
methods: {
|
||||
onSeriesAdd(series, index) {
|
||||
this.seriesModels[index] = series;
|
||||
if (series.keyString === this.seriesKeyString) {
|
||||
this.listenTo(
|
||||
series,
|
||||
'change:color',
|
||||
(newColor) => {
|
||||
this.updateColor(newColor);
|
||||
},
|
||||
this
|
||||
);
|
||||
this.listenTo(
|
||||
series,
|
||||
'change:name',
|
||||
() => {
|
||||
this.updateName();
|
||||
},
|
||||
this
|
||||
);
|
||||
this.subscribeToStaleness(series.domainObject);
|
||||
this.initialize();
|
||||
}
|
||||
},
|
||||
onSeriesRemove(seriesToRemove) {
|
||||
const seriesIndexToRemove = this.seriesModels.findIndex(
|
||||
(series) => series.keyString === seriesToRemove.keyString
|
||||
);
|
||||
this.seriesModels.splice(seriesIndexToRemove, 1);
|
||||
},
|
||||
getSeries(keyStringToFind) {
|
||||
const foundSeries = this.seriesModels.find((series) => {
|
||||
return series.keyString === keyStringToFind;
|
||||
});
|
||||
return foundSeries;
|
||||
},
|
||||
getConfig() {
|
||||
const configId = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
|
||||
return configStore.get(configId);
|
||||
},
|
||||
initialize(highlightedObject) {
|
||||
const seriesObject = highlightedObject?.series || this.seriesObject;
|
||||
const seriesKeyStringToUse = highlightedObject?.seriesKeyString || this.seriesKeyString;
|
||||
const seriesObject = this.getSeries(seriesKeyStringToUse);
|
||||
|
||||
this.isMissing = seriesObject.domainObject.status === 'missing';
|
||||
this.colorAsHexString = seriesObject.get('color').asHexString();
|
||||
@ -209,22 +228,20 @@ export default {
|
||||
updateColor(newColor) {
|
||||
this.colorAsHexString = newColor.asHexString();
|
||||
},
|
||||
updateName(newName) {
|
||||
this.nameWithUnit = this.seriesObject.nameWithUnit();
|
||||
updateName() {
|
||||
const seriesObject = this.getSeries(this.seriesKeyString);
|
||||
this.nameWithUnit = seriesObject.nameWithUnit();
|
||||
},
|
||||
toggleHover(hover) {
|
||||
this.hover = hover;
|
||||
this.$emit('legendHoverChanged', {
|
||||
seriesKey: this.hover ? this.seriesObject.keyString : ''
|
||||
seriesKey: this.hover ? this.seriesKeyString : ''
|
||||
});
|
||||
},
|
||||
async showToolTip() {
|
||||
const { BELOW } = this.openmct.tooltips.TOOLTIP_LOCATIONS;
|
||||
this.buildToolTip(
|
||||
await this.getTelemetryPathString(this.seriesObject.domainObject.identifier),
|
||||
BELOW,
|
||||
'seriesName'
|
||||
);
|
||||
const seriesIdentifier = this.openmct.objects.parseKeyString(this.seriesKeyString);
|
||||
this.buildToolTip(await this.getTelemetryPathString(seriesIdentifier), BELOW, 'seriesName');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user