diff --git a/webapp/TargetedMS/js/QCPlotHelperBase.js b/webapp/TargetedMS/js/QCPlotHelperBase.js index 11fb334b3..3a0ac0463 100644 --- a/webapp/TargetedMS/js/QCPlotHelperBase.js +++ b/webapp/TargetedMS/js/QCPlotHelperBase.js @@ -332,7 +332,7 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", { Ext4.Object.each(this.guideSetDataMap, function(guideSetId, guideSetData) { // for truncating out of range guideset data find first index of plotDate ending at guideset.trainingEnd - if (plotData.guideSetId === guideSetId && plotData.inGuideSetTrainingRange && guideSetData.TrainingEnd <= this.startDate) { + if (plotData.guideSetId == guideSetId && plotData.inGuideSetTrainingRange && guideSetData.TrainingEnd <= this.startDate) { this.filterPoints[frag][plotData.MetricId]['filterPointsFirstIndex'] = j + 1; // ReferenceRangeSeries is used to separate series plotData['ReferenceRangeSeries'] = "GuideSet"; @@ -365,11 +365,18 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", { if (this.showExpRunRange && this.filterPoints) { for (let i = 0; i < plotDataRows.length; i++) { - Ext4.Object.each(this.filterPoints[plotDataRows[i].SeriesLabel], function (metricId, filterPointsData) { + const seriesPoints = this.filterPoints && this.filterPoints[plotDataRows[i].SeriesLabel]; + if (!seriesPoints) { + continue; + } + Ext4.Object.each(seriesPoints, function (metricId, filterPointsData) { // no need to filter if less than 6 data points are present between reference end of guideset and startdate if (filterPointsData['filterPointsFirstIndex'] && filterPointsData['filterPointsLastIndex']) { if (filterPointsData['filterPointsLastIndex'] - filterPointsData['filterPointsFirstIndex'] < 6) { - this.filterQCPoints = false; + // Fewer than 6 out-of-range points for this series/metric, so there is nothing to truncate + // for it. Flag only this entry rather than clearing the global this.filterQCPoints, so that + // other series still truncate and the separator / guide-set line break still render. + filterPointsData['skipTruncation'] = true; // set the startDate field = acquired time of the 1st point of 5 points before the experiment run range this.getStartDateField().setValue(this.formatDate(plotDataRows[i].data[filterPointsData['filterPointsFirstIndex']].AcquiredTime)); @@ -434,7 +441,7 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", { Ext4.Object.each(this.fragmentPlotData, function(label, fragmentData) { // traverse plotData backwards from firstIndex to lastIndex and // remove them from the array - if (this.filterQCPoints && this.filterPoints) { + if (this.filterQCPoints && this.filterPoints && this.filterPoints[label]) { // when we're plotting two different metrics at the same time, then we // have repeated dates (from oldest to newest for metric 1, and then oldest to newest for metric 2, all in the same array). @@ -443,6 +450,9 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", { const lab = label; filterPointsReversed.forEach(metricId => { + if (this.filterPoints[lab][metricId]['skipTruncation']) { + return; // too few out-of-range points for this series/metric to truncate + } let firstIndex = this.filterPoints[lab][metricId]['filterPointsFirstIndex']; let lastIndex = this.filterPoints[lab][metricId]['filterPointsLastIndex']; diff --git a/webapp/TargetedMS/js/QCTrendPlotPanel.js b/webapp/TargetedMS/js/QCTrendPlotPanel.js index ec699977d..cc303f354 100644 --- a/webapp/TargetedMS/js/QCTrendPlotPanel.js +++ b/webapp/TargetedMS/js/QCTrendPlotPanel.js @@ -2325,8 +2325,10 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', { .attr('stroke', color).attr('stroke-opacity', 0.1) .attr('fill', color).attr('fill-opacity', 0.1) .append("title") - .text(function (d) { - return "Selected replicate: " + Ext4.String.htmlEncode(plot.data[d.EndIndex].ReplicateName); + .text(function () { + // 'data' is the already-matched point for this replicate, don't index plot.data by + // seqValue (EndIndex), which breaks once out-of-range points have been truncated. + return "Selected replicate: " + Ext4.String.htmlEncode(data.ReplicateName); }); this.sendSvgElementToBack(plot, outlierRect); @@ -2399,8 +2401,14 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', { var pointsData = precursorInfo.data; var expDataArr = []; - for (var i = startIndex; i <= endIndex; i++) { - expDataArr.push(pointsData[i].value); + // startIndex/endIndex are seqValues (x-axis positions), not array indices. Once out-of-range + // points are truncated, the array positions no longer line up with seqValue, so collect the + // experiment-range values by matching seqValue rather than indexing pointsData directly. + for (var i = 0; i < pointsData.length; i++) { + if (pointsData[i].seqValue >= startIndex && pointsData[i].seqValue <= endIndex + && pointsData[i].value !== undefined && pointsData[i].value !== null) { + expDataArr.push(pointsData[i].value); + } } var expMean = LABKEY.targetedms.PlotSettingsUtil.formatNumeric(LABKEY.vis.Stat.getMean(expDataArr));