mirror of
https://github.com/nasa/openmct.git
synced 2025-06-16 06:08:11 +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:
@ -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;
|
||||
|
Reference in New Issue
Block a user