Mct6157 creating annotations for plots on multiple yaxes (#6161)

* First pass

* Get bounding box min and max values based on the y axis that a series belongs to.
Handle removal of telemetry from an overlay plot
Handle addition of telemetry after annotations have been saved to an overlay plot

* Fix showing the rectangle for a given target's bounding box.

* remove invalid comment

Co-authored-by: Scott Bell <scott@traclabs.com>
This commit is contained in:
Shefali Joshi 2023-01-24 03:00:45 -08:00 committed by GitHub
parent 8847c862fa
commit 60e808689c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 44 deletions

View File

@ -820,21 +820,29 @@ export default {
marqueeAnnotations(annotationsToSelect) { marqueeAnnotations(annotationsToSelect) {
annotationsToSelect.forEach(annotationToSelect => { annotationsToSelect.forEach(annotationToSelect => {
const firstTargetKeyString = Object.keys(annotationToSelect.targets)[0]; Object.keys(annotationToSelect.targets).forEach(targetKeyString => {
const firstTarget = annotationToSelect.targets[firstTargetKeyString]; const target = annotationToSelect.targets[targetKeyString];
const rectangle = { const series = this.seriesModels.find(seriesModel => seriesModel.keyString === targetKeyString);
start: { if (!series) {
x: firstTarget.minX, return;
y: firstTarget.minY }
},
end: {
x: firstTarget.maxX,
y: firstTarget.maxY
},
color: [1, 1, 1, 0.10]
};
this.rectangles.push(rectangle);
const yAxisId = series.get('yAxisId');
const rectangle = {
start: {
x: target.minX,
y: [target.minY],
yAxisIds: [yAxisId]
},
end: {
x: target.maxX,
y: [target.maxY],
yAxisIds: [yAxisId]
},
color: [1, 1, 1, 0.10]
};
this.rectangles.push(rectangle);
});
}); });
}, },
gatherNearbyAnnotations() { gatherNearbyAnnotations() {
@ -1197,20 +1205,16 @@ export default {
]; ];
this.openmct.selection.select(selection, true); this.openmct.selection.select(selection, true);
}, },
selectNewPlotAnnotations(minX, minY, maxX, maxY, pointsInBox, event) { selectNewPlotAnnotations(boundingBoxPerYAxis, pointsInBox, event) {
const boundingBox = {
minX,
minY,
maxX,
maxY
};
let targetDomainObjects = {}; let targetDomainObjects = {};
let targetDetails = {}; let targetDetails = {};
let annotations = {}; let annotations = {};
pointsInBox.forEach(pointInBox => { pointsInBox.forEach(pointInBox => {
if (pointInBox.length) { if (pointInBox.length) {
const seriesID = pointInBox[0].series.keyString; const seriesID = pointInBox[0].series.keyString;
targetDetails[seriesID] = boundingBox; const boundingBoxWithId = boundingBoxPerYAxis.find(box => box.id === pointInBox[0].series.get('yAxisId'));
targetDetails[seriesID] = boundingBoxWithId?.boundingBox;
targetDomainObjects[seriesID] = pointInBox[0].series.domainObject; targetDomainObjects[seriesID] = pointInBox[0].series.domainObject;
} }
}); });
@ -1225,10 +1229,23 @@ export default {
rawAnnotations.forEach(rawAnnotation => { rawAnnotations.forEach(rawAnnotation => {
if (rawAnnotation.targets) { if (rawAnnotation.targets) {
const targetValues = Object.values(rawAnnotation.targets); const targetValues = Object.values(rawAnnotation.targets);
const targetKeys = Object.keys(rawAnnotation.targets);
if (targetValues && targetValues.length) { if (targetValues && targetValues.length) {
// just get the first one let boundingBoxPerYAxis = [];
const boundingBox = Object.values(targetValues)?.[0]; targetValues.forEach((boundingBox, index) => {
const pointsInBox = this.getPointsInBox(boundingBox, rawAnnotation); const seriesId = targetKeys[index];
const series = this.seriesModels.find(seriesModel => seriesModel.keyString === seriesId);
if (!series) {
return;
}
boundingBoxPerYAxis.push({
id: series.get('yAxisId'),
boundingBox
});
});
const pointsInBox = this.getPointsInBox(boundingBoxPerYAxis, rawAnnotation);
if (pointsInBox && pointsInBox.length) { if (pointsInBox && pointsInBox.length) {
annotationsByPoints.push(pointsInBox.flat()); annotationsByPoints.push(pointsInBox.flat());
} }
@ -1238,10 +1255,17 @@ export default {
return annotationsByPoints.flat(); return annotationsByPoints.flat();
}, },
getPointsInBox(boundingBox, rawAnnotation) { getPointsInBox(boundingBoxPerYAxis, rawAnnotation) {
// load series models in KD-Trees // load series models in KD-Trees
const seriesKDTrees = []; const seriesKDTrees = [];
this.seriesModels.forEach(seriesModel => { this.seriesModels.forEach(seriesModel => {
const boundingBoxWithId = boundingBoxPerYAxis.find(box => box.id === seriesModel.get('yAxisId'));
const boundingBox = boundingBoxWithId?.boundingBox;
//Series was probably added after the last annotations were saved
if (!boundingBox) {
return;
}
const seriesData = seriesModel.getSeriesData(); const seriesData = seriesModel.getSeriesData();
if (seriesData && seriesData.length) { if (seriesData && seriesData.length) {
const kdTree = new KDBush(seriesData, const kdTree = new KDBush(seriesData,
@ -1283,25 +1307,31 @@ export default {
return seriesKDTrees; return seriesKDTrees;
}, },
endAnnotationMarquee(event) { endAnnotationMarquee(event) {
const minX = Math.min(this.marquee.start.x, this.marquee.end.x); const boundingBoxPerYAxis = [];
const startMinY = this.marquee.start.y.reduce((previousY, currentY) => { this.yAxisListWithRange.forEach((yAxis, yIndex) => {
return Math.min(previousY, currentY); const minX = Math.min(this.marquee.start.x, this.marquee.end.x);
}, this.marquee.start.y[0]); const minY = Math.min(this.marquee.start.y[yIndex], this.marquee.end.y[yIndex]);
const endMinY = this.marquee.end.y.reduce((previousY, currentY) => { const maxX = Math.max(this.marquee.start.x, this.marquee.end.x);
return Math.min(previousY, currentY); const maxY = Math.max(this.marquee.start.y[yIndex], this.marquee.end.y[yIndex]);
}, this.marquee.end.y[0]); const boundingBox = {
const minY = Math.min(startMinY, endMinY); minX,
const maxX = Math.max(this.marquee.start.x, this.marquee.end.x); minY,
const maxY = Math.max(startMinY, endMinY); maxX,
const boundingBox = { maxY
minX, };
minY, boundingBoxPerYAxis.push({
maxX, id: yAxis.get('id'),
maxY boundingBox
}; });
const pointsInBox = this.getPointsInBox(boundingBox); });
const pointsInBox = this.getPointsInBox(boundingBoxPerYAxis);
if (!pointsInBox) {
return;
}
this.annotationSelections = pointsInBox.flat(); this.annotationSelections = pointsInBox.flat();
this.selectNewPlotAnnotations(minX, minY, maxX, maxY, pointsInBox, event); this.selectNewPlotAnnotations(boundingBoxPerYAxis, pointsInBox, event);
}, },
endZoomMarquee() { endZoomMarquee() {
const startPixels = this.marquee.startPixels; const startPixels = this.marquee.startPixels;

View File

@ -744,6 +744,10 @@ export default {
} }
}, },
annotatedPointWithinRange(annotatedPoint, xRange, yRange) { annotatedPointWithinRange(annotatedPoint, xRange, yRange) {
if (!yRange) {
return false;
}
const xValue = annotatedPoint.series.getXVal(annotatedPoint.point); const xValue = annotatedPoint.series.getXVal(annotatedPoint.point);
const yValue = annotatedPoint.series.getYVal(annotatedPoint.point); const yValue = annotatedPoint.series.getYVal(annotatedPoint.point);