Skip to content

Commit 884eec8

Browse files
authored
Support creating guide sets via drag/drop for combined plots (#1153)
1 parent 12a235e commit 884eec8

5 files changed

Lines changed: 78 additions & 21 deletions

File tree

test/src/org/labkey/test/tests/targetedms/TargetedMSQCGuideSetTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public void runTestsInOrder() throws IOException, CommandException
113113
{
114114
testGuideSetStats();
115115
testGuideSetCreateValidation();
116+
testCombinedPlotsGuideSetCreation();
116117
testGuideSetPlotDisplay();
117118
testParetoPlot();
118119
testEmptyParetoPlot();
@@ -182,6 +183,31 @@ public void testGuideSetCreateValidation()
182183
createGuideSet(new GuideSet("", "", null, 47), overlapErrorMsg);
183184
}
184185

186+
187+
private void testCombinedPlotsGuideSetCreation()
188+
{
189+
preTest();
190+
PanoramaDashboard qcDashboard = new PanoramaDashboard(this);
191+
QCPlotsWebPart qcPlotsWebPart = qcDashboard.getQcPlotsWebPart();
192+
qcPlotsWebPart.resetInitialQCPlotFields();
193+
qcPlotsWebPart.setShowAllPeptidesInSinglePlot(true, 1);
194+
195+
GuideSet gsCombined = new GuideSet("2013/08/17 16:01:37", "2013/08/20 13:35:16", "guide set created from combined plots");
196+
createGuideSet(gsCombined);
197+
198+
clickTab("Guide Sets");
199+
DataRegionTable table = new DataRegionTable.DataRegionFinder(getDriver()).waitFor();
200+
assertEquals("Guide set was not created from combined plots", 6, table.getDataRowCount());
201+
202+
int rowIndex = table.getRowIndex("Comment", "guide set created from combined plots");
203+
table.checkCheckbox(rowIndex);
204+
doAndWaitForPageToLoad(() ->
205+
{
206+
table.clickHeaderButton("Delete");
207+
assertAlert("Are you sure you want to delete the selected row?");
208+
});
209+
}
210+
185211
public void testGuideSetPlotDisplay()
186212
{
187213
preTest();

test/src/org/labkey/test/tests/targetedms/TargetedMSQCTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,6 +1081,7 @@ private void verifyAddAnnotationsFromQCPlots()
10811081
String testComment = "Test annotation from QC plot";
10821082
setFormElement(Locator.name("description"), testComment);
10831083

1084+
log("Clicking Save button in add annotation dialog");
10841085
// Click the save button
10851086
addAnnotationDialog.clickButton("Save", true);
10861087
_ext4Helper.waitForMaskToDisappear();

webapp/TargetedMS/js/QCPlotHelperBase.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", {
694694
return precursor;
695695
},
696696

697-
addEachCombinedPrecursorPlot: function(plotIndex, id, combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, plotType, isCUSUMMean) {
697+
addEachCombinedPrecursorPlot: function(plotIndex, id, combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, plotType, isCUSUMMean, scope) {
698698
let plotLegendData = this.getCombinedPlotLegendData(metricProps, groupColors, yAxisCount, plotType, isCUSUMMean);
699699

700700
if (plotType !== LABKEY.vis.TrendingLinePlotType.CUSUM) {
@@ -735,6 +735,7 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", {
735735
color: 'fragment',
736736
defaultGuideSetLabel: 'fragment',
737737
pointSize: 2,
738+
pointIdAttr: function(row) { return row['fullDate'] + row['fragment']; },
738739
shapeRange: [LABKEY.vis.Scale.Shape()[0] /* circle */, LABKEY.vis.Scale.DataspaceShape()[0] /* open circle */, LABKEY.vis.Scale.Shape()[1], LABKEY.vis.Scale.Shape()[2]],
739740
shapeDomain: shapeDomain,
740741
showTrendLine: true,
@@ -794,6 +795,24 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperBase", {
794795
visibility: this.isMultiSeries() ? undefined : 'hidden'
795796
}
796797
},
798+
brushing: !this.allowGuideSetBrushing() ? undefined : {
799+
dimension: 'x',
800+
fillOpacity: 0.4,
801+
fillColor: 'rgba(20, 204, 201, 1)',
802+
strokeColor: 'rgba(20, 204, 201, 1)',
803+
brushstart: function(event, data, extent, plot, layerSelections) {
804+
scope.plotBrushStartEvent(plot);
805+
},
806+
brush: function(event, data, extent, plot, layerSelections) {
807+
scope.plotBrushEvent(extent, plot, layerSelections);
808+
},
809+
brushend: function(event, data, extent, plot, layerSelections) {
810+
scope.plotBrushEndEvent(data[data.length - 1], extent, plot);
811+
},
812+
brushclear: function(event, data, plot, layerSelections) {
813+
scope.plotBrushClearEvent(data[data.length - 1], plot);
814+
}
815+
},
797816
properties: trendLineProps
798817
});
799818

webapp/TargetedMS/js/QCPlotHelperWrapper.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperWrapper", {
128128
},
129129

130130
addCombinedPeptideSinglePlot : function(metricProps) {
131+
const me = this; // for plot brushing
131132
let yAxisCount = this.isMultiSeries() ? 2 : 1, //Will only have a right if there is already a left y-axis
132133
groupColors = this.getColorRange(),
133134
combinePlotData = this.getCombinedPlotInitData(),
@@ -195,25 +196,25 @@ Ext4.define("LABKEY.targetedms.QCPlotHelperWrapper", {
195196
legendMargin = 300;
196197

197198
if (this.showMetricValuePlot()) {
198-
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex++], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.LeveyJennings);
199+
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex++], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.LeveyJennings, false, me);
199200
}
200201
if (this.showMovingRangePlot()) {
201-
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex++], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.MovingRange);
202+
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex++], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.MovingRange, false, me);
202203
}
203204
if (this.showMeanCUSUMPlot()) {
204-
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex++], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.CUSUM, true);
205+
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex++], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.CUSUM, true, me);
205206
}
206207
if (this.showVariableCUSUMPlot()) {
207-
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.CUSUM, false);
208+
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.CUSUM, false, me);
208209
}
209210
if (this.showTrailingMeanPlot()) {
210-
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.TrailingMean, false);
211+
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.TrailingMean, false, me);
211212
}
212213
if (this.showTrailingCVPlot()) {
213-
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.TrailingCV, false);
214+
this.addEachCombinedPrecursorPlot(plotIndex, ids[plotIndex], combinePlotData, groupColors, yAxisCount, metricProps, showLogInvalid, legendMargin, LABKEY.vis.TrendingLinePlotType.TrailingCV, false, me);
214215
}
215216

216-
217+
this.setPlotBrushingDisplayStyle();
217218
return true;
218219
},
219220

webapp/TargetedMS/js/QCTrendPlotPanel.js

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', {
11691169
if (!this.createGuideSetToggleButton) {
11701170
this.createGuideSetToggleButton = Ext4.create('Ext.button.Button', {
11711171
text: 'Create Guide Set',
1172-
tooltip: 'Enable/disable guide set creation mode. Supported for separate plots, not grouped by date, when ' + LABKEY.targetedms.QCPlotHelperBase.maxPointsPerSeries + ' or fewer samples are shown',
1172+
tooltip: 'Enable/disable guide set creation mode. Supported for plots when ' + LABKEY.targetedms.QCPlotHelperBase.maxPointsPerSeries + ' or fewer samples are shown',
11731173
disabled: !this.canCreateGuideSetFromPlot(),
11741174
enableToggle: true,
11751175
handler: function(btn) {
@@ -1183,11 +1183,11 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', {
11831183
},
11841184

11851185
canCreateGuideSetFromPlot : function() {
1186-
return !(this.groupedX || this.singlePlot || this.isMultiSeries() || this.showExpRunRange || !this.showDataPoints);
1186+
return !(this.showExpRunRange || !this.showDataPoints);
11871187
},
11881188

11891189
setBrushingEnabled : function(enabled) {
1190-
// we don't currently allow creation of guide sets in single plot mode, grouped x-axis mode, multi series mode or when showingExpRunRange
1190+
// we don't currently allow creation when showingExpRunRange
11911191
this.getGuideSetCreateButton().setDisabled(!this.canCreateGuideSetFromPlot());
11921192

11931193
this.enableBrushing = enabled;
@@ -1552,7 +1552,7 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', {
15521552
this.bringSvgElementToFront(plot, "g.guideset-svg-button");
15531553
},
15541554

1555-
plotBrushClearEvent : function(data, plot) {
1555+
plotBrushClearEvent : function() {
15561556
this.plotBrushSelection = undefined;
15571557
},
15581558

@@ -1561,7 +1561,7 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', {
15611561
},
15621562

15631563
allowGuideSetBrushing : function() {
1564-
return this.canUserEdit() && !this.groupedX;
1564+
return this.canUserEdit();
15651565
},
15661566

15671567
createGuideSetSvgButton : function(plot, text, xLeftPos, width) {
@@ -1586,8 +1586,9 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', {
15861586
setPlotBrushingDisplayStyle : function() {
15871587
// hide the brushing related components for all plots if not in "create guide set" mode
15881588
var displayStyle = this.enableBrushing ? 'inline' : 'none';
1589-
d3.selectAll('.brush').style({'display': displayStyle});
1590-
d3.selectAll('.x-axis-handle').style({'display': displayStyle});
1589+
// Scope the selection to only plots within the current plotDivId to avoid affecting other plot types
1590+
d3.select('#' + this.plotDivId).selectAll('.brush').style({'display': displayStyle});
1591+
d3.select('#' + this.plotDivId).selectAll('.x-axis-handle').style({'display': displayStyle});
15911592
},
15921593

15931594
clearPlotBrush : function(plot) {
@@ -2328,17 +2329,26 @@ Ext4.define('LABKEY.targetedms.QCTrendPlotPanel', {
23282329
},
23292330

23302331
createGuideSetBtnClick: function() {
2331-
var minGuideSetPointCount = 5; // to warn user if less than this many points are selected for the new guide set
2332+
let minGuideSetReplicateCount = 5; // to warn user if less than this many replicates are selected for the new guide set
23322333

23332334
if (this.plotBrushSelection && this.plotBrushSelection.points.length > 0) {
2334-
var startDate = this.plotBrushSelection.points[0]['fullDate'];
2335-
var endDate = this.plotBrushSelection.points[this.plotBrushSelection.points.length - 1]['fullDate'];
2335+
let startDate = this.plotBrushSelection.points[0]['fullDate'];
2336+
let endDate = this.plotBrushSelection.points[this.plotBrushSelection.points.length - 1]['fullDate'];
2337+
2338+
let distinctSampleFileIds = {};
2339+
for (let i = 0; i < this.plotBrushSelection.points.length; i++) {
2340+
let sampleFileId = this.plotBrushSelection.points[i].SampleFileId;
2341+
if (sampleFileId !== undefined && sampleFileId !== null) {
2342+
distinctSampleFileIds[sampleFileId] = true;
2343+
}
2344+
}
2345+
let distinctCount = Object.keys(distinctSampleFileIds).length;
23362346

2337-
if (this.plotBrushSelection.points.length < minGuideSetPointCount) {
2347+
if (distinctCount < minGuideSetReplicateCount) {
23382348
Ext4.Msg.show({
2339-
title:'Create Guide Set Warning',
2349+
title: 'Create Guide Set Warning',
23402350
icon: Ext4.MessageBox.WARNING,
2341-
msg: 'Fewer than ' + minGuideSetPointCount + ' data points were selected for the new guide set, which may not be statistically significant. Would you like to proceed anyway?',
2351+
msg: 'Fewer than ' + minGuideSetReplicateCount + ' replicates were selected for the new guide set, which may not be statistically significant. Would you like to proceed anyway?',
23422352
buttons: Ext4.Msg.YESNO,
23432353
scope: this,
23442354
fn: function(btnId, text, opt){

0 commit comments

Comments
 (0)