diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerCallbackI.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerCallbackI.java index 1aa8c398..6d8c8146 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerCallbackI.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerCallbackI.java @@ -2,4 +2,6 @@ public interface AnalysisManagerCallbackI { public void callbackRefreshBlocksStatus(); + + public void reviewAndSculptDataAction(); } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerController.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerController.java index e68ecae9..7aab549c 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerController.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/AnalysisManagerController.java @@ -61,6 +61,7 @@ public class AnalysisManagerController implements Initializable, AnalysisManager public static AnalysisInterface analysis; public static MCMCPlotsWindow MCMCPlotsWindow; public static OGTripoliPlotsWindow ogTripoliPlotsWindow; + public static OGTripoliPlotsWindow ogTripoliPreviewPlotsWindow; private final Map mapOfGridPanesToCellUse = new TreeMap<>(); public Tab detectorDetailTab; public TabPane analysiMethodTabPane; @@ -112,6 +113,18 @@ public class AnalysisManagerController implements Initializable, AnalysisManager @FXML private Button addRatioButton; + public static void closePlotWindows() { + if (ogTripoliPreviewPlotsWindow != null) { + ogTripoliPreviewPlotsWindow.close(); + } + if (ogTripoliPlotsWindow != null) { + ogTripoliPlotsWindow.close(); + } + if (MCMCPlotsWindow != null) { + MCMCPlotsWindow.close(); + } + } + public static StackPane makeMassStackPane(String massName, String color) { Text massText = new Text(massName); massText.setFont(new Font("Monospaced Bold", 14)); @@ -375,6 +388,8 @@ private void populateAnalysisMethodRatioSelectorPane() { private void populateAnalysisMethodRatioBuilderPane() { addRatioButton.setStyle(addRatioButton.getStyle() + ";-fx-font-size:15"); + numeratorMassesListTextFlow.getChildren().clear(); + denominatorMassesListTextFlow.getChildren().clear(); if (null != analysis.getAnalysisMethod()) { activeRatiosList = new TreeSet<>(); List species = analysis.getAnalysisMethod().getSpeciesListSortedByMass(); @@ -590,7 +605,7 @@ private void selectDataFileButtonAction() { @FXML private void selectMethodFileButtonAction() { try { - File selectedFile = selectMethodFile(TripoliGUI.primaryStage); + File selectedFile = selectMethodFile(null); if ((null != selectedFile) && (selectedFile.exists())) { AnalysisMethod analysisMethod = analysis.extractAnalysisMethodfromPath(Path.of(selectedFile.toURI())); String compareInfo = compareAnalysisMethodToDataFileSpecs(analysisMethod, analysis.getMassSpecExtractedData()); @@ -615,6 +630,7 @@ private void selectMethodFileButtonAction() { // initialize block processing state for (Integer blockID : analysis.getMassSpecExtractedData().getBlocksData().keySet()) { analysis.getMapOfBlockIdToProcessStatus().put(blockID, RUN); + analysis.getMapOfBlockIdToModelsBurnCount().put(blockID, 0); } populateAnalysisManagerGridPane(); } @@ -635,18 +651,29 @@ final void initializeMonteCarloTechniqueAction() { } - public void reviewAndSculptDataAction() throws TripoliException { + public void previewAndSculptDataAction() throws TripoliException { // ogTripoli view - if (null != ogTripoliPlotsWindow) { - ogTripoliPlotsWindow.close(); + if (null != ogTripoliPreviewPlotsWindow) { + ogTripoliPreviewPlotsWindow.close(); } - ogTripoliPlotsWindow = new OGTripoliPlotsWindow(TripoliGUI.primaryStage); + ogTripoliPreviewPlotsWindow = new OGTripoliPlotsWindow(TripoliGUI.primaryStage, this); OGTripoliViewController.analysis = analysis; OGTripoliViewController.plottingData = AllBlockInitForOGTripoli.initBlockModels(analysis); - ogTripoliPlotsWindow.loadPlotsWindow(); + ogTripoliPreviewPlotsWindow.loadPlotsWindow(); } + public void reviewAndSculptDataAction() { + // fire up OGTripoli style session plots + if (null != ogTripoliPlotsWindow) { + ogTripoliPlotsWindow.close(); + } + ogTripoliPlotsWindow = new OGTripoliPlotsWindow(TripoliGUI.primaryStage, this); + AllBlockInitForOGTripoli.PlottingData plottingData = analysis.assemblePostProcessPlottingData(); + OGTripoliViewController.plottingData = plottingData; + ogTripoliPlotsWindow.loadPlotsWindow(); + } + public void selectRunAllAction() { for (Node button : blockStatusHBox.getChildren()) { if (button instanceof Button) { @@ -672,6 +699,9 @@ public void selectShowsAction() { } } + /** + * Restores block status buttons to their saved state + */ public void restoreAllAction() { for (Node button : blockStatusHBox.getChildren()) { if ((button instanceof Button) && (null != analysis.getMapOfBlockIdToProcessStatus().get(Integer.parseInt(button.getId())))) { diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliPlotsWindow.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliPlotsWindow.java index b813139f..2d2b1ee5 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliPlotsWindow.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliPlotsWindow.java @@ -33,23 +33,16 @@ public class OGTripoliPlotsWindow { public static final double PLOT_WINDOW_WIDTH = 1000.0; public static final double PLOT_WINDOW_HEIGHT = 700.0; - public static final double SCROLLBAR_THICKNESS = 15.0; - private final double xOffset = 0; - private final double yOffset = 0; public Stage plottingStage; public Window plottingWindow; private Stage primaryStage; - private OGTripoliPlotsWindow() { - } - - public OGTripoliPlotsWindow(Stage primaryStage) {//}, AnalysisManagerCallbackI analysisManagerCallbackI) { + public OGTripoliPlotsWindow(Stage primaryStage, AnalysisManagerCallbackI analysisManagerCallbackI) { this.primaryStage = primaryStage; plottingStage = new Stage(); plottingStage.setMinWidth(PLOT_WINDOW_WIDTH); plottingStage.setMinHeight(PLOT_WINDOW_HEIGHT); -// plottingStage.setTitle("Tripoli Preview and Sculpt Data"); plottingStage.setOnCloseRequest((WindowEvent e) -> { plottingStage.hide(); @@ -57,7 +50,7 @@ public OGTripoliPlotsWindow(Stage primaryStage) {//}, AnalysisManagerCallbackI a e.consume(); }); - // MCMCPlotsController.analysisManagerCallbackI = analysisManagerCallbackI; + OGTripoliViewController.analysisManagerCallbackI = analysisManagerCallbackI; } public void close() { @@ -66,17 +59,18 @@ public void close() { public void loadPlotsWindow() { if (!plottingStage.isShowing()) { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/cirdles/tripoli/gui/OGTripoliView.fxml")); try { - FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/cirdles/tripoli/gui/OGTripoliView.fxml")); Scene scene = new Scene(loader.load()); plottingStage.setScene(scene); - } catch (IOException iOException) { iOException.printStackTrace(); } plottingWindow = plottingStage.getScene().getWindow(); plottingStage.setTitle("Tripoli " + (plottingData.preview() ? "PREVIEW" : "REVIEW") + " and Sculpt Data"); +// ((OGTripoliViewController) loader.getController()).populatePlots(); plottingStage.show(); + } // center on app window diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliViewController.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliViewController.java index 84a792e5..ca71c583 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliViewController.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/OGTripoliViewController.java @@ -1,9 +1,13 @@ package org.cirdles.tripoli.gui; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; +import javafx.scene.control.TabPane; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; +import javafx.scene.layout.VBox; import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; @@ -35,29 +39,61 @@ public class OGTripoliViewController { public static AnalysisInterface analysis; public static AllBlockInitForOGTripoli.PlottingData plottingData; + public static AnalysisManagerCallbackI analysisManagerCallbackI; + @FXML + public VBox plotWindowVBox; + @FXML + public TabPane plotTabPane; @FXML public AnchorPane ogtSpeciesIntensitiesPlotAnchorPane; @FXML private AnchorPane ogtCycleRatioPlotsAnchorPane; @FXML - void initialize() { + public void initialize() { + plotWindowVBox.widthProperty().addListener((observable, oldValue, newValue) -> { + plotTabPane.setMinWidth((Double) newValue); + ogtCycleRatioPlotsAnchorPane.setMinWidth((Double) newValue); + ogtSpeciesIntensitiesPlotAnchorPane.setMinWidth((Double) newValue); + }); + + plotWindowVBox.heightProperty().addListener((observable, oldValue, newValue) -> { + plotTabPane.setMinHeight(((Double) newValue) - 30.0); + ogtCycleRatioPlotsAnchorPane.setMinHeight(((Double) newValue) - 65.0); + ogtSpeciesIntensitiesPlotAnchorPane.setMinHeight(((Double) newValue) - 100.0); + }); + populatePlots(); } - private void populatePlots() { + public void populatePlots() { plotRatios(); plotOnPeakIntensities(); } - private void plotRatios() { + public void plotRatios() { ogtCycleRatioPlotsAnchorPane.getChildren().clear(); - PlotWallPane plotsWallPane = PlotWallPane.createPlotWallPane("OGTripoliSession"); + PlotWallPane plotsWallPane = PlotWallPane.createPlotWallPane("OGTripoliSession", analysis, null, analysisManagerCallbackI); PlotWallPane.menuOffset = 0.0; plotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - plotsWallPane.setPrefSize(ogtCycleRatioPlotsAnchorPane.getPrefWidth(), ogtCycleRatioPlotsAnchorPane.getPrefHeight()); + + plotsWallPane.prefWidthProperty().bind(ogtCycleRatioPlotsAnchorPane.widthProperty()); + plotsWallPane.prefHeightProperty().bind(ogtCycleRatioPlotsAnchorPane.heightProperty()); + ogtCycleRatioPlotsAnchorPane.getChildren().add(plotsWallPane); + plotWindowVBox.widthProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + plotsWallPane.stackPlots(); + } + }); + plotWindowVBox.heightProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + plotsWallPane.stackPlots(); + } + }); SingleBlockModelRecord[] singleBlockModelRecords = plottingData.singleBlockModelRecords(); int countOfOnPeakCycles = singleBlockModelRecords[0].cycleCount(); @@ -82,6 +118,7 @@ private void plotRatios() { for (IsotopicRatio isotopicRatio : ratiosToPlot) { TripoliPlotPane tripoliPlotPane = TripoliPlotPane.makePlotPane(plotsWallPane); + List blockRatioCyclesRecords = new ArrayList<>(); for (int blockIndex = 0; blockIndex < singleBlockModelRecords.length; blockIndex++) { int blockStatus = analysis.getMapOfBlockIdToProcessStatus().get(blockIndex + 1); @@ -102,8 +139,11 @@ private void plotRatios() { blockRatioCyclesRecords, new String[]{isotopicRatio.prettyPrint()}, "Blocks & Cycles by Time", "Ratio"); AbstractPlot plot = BlockRatioCyclesSessionPlot.generatePlot( - new Rectangle(minPlotWidth, minPlotHeight), blockRatioCyclesSessionBuilder.getBlockRatioCyclesSessionRecord()); + new Rectangle(minPlotWidth, minPlotHeight), blockRatioCyclesSessionBuilder.getBlockRatioCyclesSessionRecord(), plotsWallPane); + tripoliPlotPane.addPlot(plot); + plot.refreshPanel(false, false); + } plotsWallPane.buildScaleControlsToolbar(); plotsWallPane.stackPlots(); @@ -115,8 +155,25 @@ private void plotOnPeakIntensities() { PlotWallPane.menuOffset = 0.0; plotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); plotsWallPane.setPrefSize(ogtSpeciesIntensitiesPlotAnchorPane.getPrefWidth(), ogtSpeciesIntensitiesPlotAnchorPane.getPrefHeight() + PlotWallPaneOGTripoli.toolBarHeight * 2.0); + + plotsWallPane.prefWidthProperty().bind(ogtSpeciesIntensitiesPlotAnchorPane.widthProperty()); + plotsWallPane.prefHeightProperty().bind(ogtSpeciesIntensitiesPlotAnchorPane.heightProperty()); + ogtSpeciesIntensitiesPlotAnchorPane.getChildren().add(plotsWallPane); + plotWindowVBox.widthProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + plotsWallPane.stackPlots(); + } + }); + plotWindowVBox.heightProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + plotsWallPane.stackPlots(); + } + }); + SingleBlockRawDataSetRecord[] singleBlockRawDataSetRecords = plottingData.singleBlockRawDataSetRecords(); SingleBlockModelRecord[] singleBlockModelRecords = plottingData.singleBlockModelRecords(); // only plotting onPeaks @@ -195,11 +252,13 @@ private void plotOnPeakIntensities() { } PlotBuilder plotBuilder = SpeciesIntensitySessionBuilder.initializeSpeciesIntensitySessionPlot( - xAxis, onPeakDataCounts, onPeakDataAmpResistance, onPeakBaseline, onPeakGain, new String[]{"Species Intensity by Session"}, "Time", "Intensity (counts)"); + xAxis, onPeakDataCounts, onPeakDataAmpResistance, onPeakBaseline, onPeakGain, new String[]{"Species Intensity by Session"}, "Time (secs)", "Intensity (counts)"); TripoliPlotPane tripoliPlotPane = TripoliPlotPane.makePlotPane(plotsWallPane); AbstractPlot plot = SpeciesIntensitySessionPlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), (SpeciesIntensitySessionBuilder) plotBuilder); tripoliPlotPane.addPlot(plot); + plot.refreshPanel(false, false); + plotsWallPane.buildOGTripoliToolBar(analysis.getAnalysisMethod().getSpeciesList()); plotsWallPane.buildScaleControlsToolbar(); plotsWallPane.stackPlots(); diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/TripoliGUIController.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/TripoliGUIController.java index e579898d..5840551b 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/TripoliGUIController.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/TripoliGUIController.java @@ -111,7 +111,7 @@ public static void quit() { } catch (TripoliException squidException) { TripoliMessageDialog.showWarningDialog(squidException.getMessage(), primaryStageWindow); } - // todo: confirmSaveOnProjectClose(); + // todo: confirmSaveOnSessionClose(); System.out.println("Tripoli quitting normally."); Platform.exit(); System.exit(0); @@ -156,6 +156,8 @@ private void removeAllManagers() throws TripoliException { manager.setVisible(false); } + AnalysisManagerController.closePlotWindows(); + // prevent stacking of panes splashAnchor.getChildren().remove(sessionManagerUI); splashAnchor.getChildren().remove(analysesManagerUI); diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/constants/ConstantsTripoliApp.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/constants/ConstantsTripoliApp.java index 376f7483..3c14dc9a 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/constants/ConstantsTripoliApp.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/constants/ConstantsTripoliApp.java @@ -41,6 +41,8 @@ public enum ConstantsTripoliApp { //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/paint/Color.html public static final String[] TRIPOLI_PALLETTE_FOUR = {"RED", "BLUE", "GREEN", "BLACK", "ORANGE", "INDIGO", "#35978f", "#01665e"}; + public static final Color TRIPOLI_MOVING_SHADE = new Color(255.0 / 256.0, 182.0 / 256.0, 193.0 / 256.0, 0.5); + public static @NonNls String convertColorToHex(Color color) { String red = Integer.toHexString((int) (color.getRed() * 255)); String green = Integer.toHexString((int) (color.getGreen() * 255)); @@ -49,5 +51,11 @@ public enum ConstantsTripoliApp { return "#" + red + green + blue; } + public static enum PlotLayoutStyle { + TILE(), + STACK(), + CASCADE(); + } + } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/AbstractPlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/AbstractPlot.java index 5109ee4d..80ed23eb 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/AbstractPlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/AbstractPlot.java @@ -35,10 +35,16 @@ import javafx.scene.text.Font; import javafx.scene.text.Text; import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots.HistogramSinglePlot; +import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots.LinePlot; +import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots.MultiLineIntensityPlot; +import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots.sessionPlots.BlockRatioCyclesSessionPlot; import org.cirdles.tripoli.gui.utilities.TripoliColor; +import org.cirdles.tripoli.plots.PlotBuilder; +import org.cirdles.tripoli.plots.linePlots.LinePlotBuilder; +import org.cirdles.tripoli.plots.linePlots.MultiLinePlotBuilder; import java.math.BigDecimal; -import java.util.Formatter; +import java.text.DecimalFormat; /** * @author James F. Bowring @@ -77,10 +83,12 @@ public abstract class AbstractPlot extends Canvas { protected boolean showYaxis; protected boolean showXaxis; + protected PlotBuilder plotBuilder; + ; + private AbstractPlot() { } - /** * @param bounds */ @@ -114,48 +122,75 @@ protected AbstractPlot(Rectangle bounds, int leftMargin, int topMargin, String[] @Override public void handle(ScrollEvent event) { if (mouseInHouse(event.getX(), event.getY())) { + // converting scroll as Y event zoomChunkX = Math.abs(zoomChunkX) * Math.signum(event.getDeltaY()); zoomChunkY = Math.abs(zoomChunkY) * Math.signum(event.getDeltaY()); if (getDisplayRangeX() >= zoomChunkX) { - minX += zoomChunkX; - maxX -= zoomChunkX; - minY += zoomChunkY; - maxY -= zoomChunkY; - - calculateTics(); - repaint(); + if (event.getSource() instanceof BlockRatioCyclesSessionPlot) { + BlockRatioCyclesSessionPlot sourceBlockRatioCyclesSessionPlot = (BlockRatioCyclesSessionPlot) event.getSource(); + sourceBlockRatioCyclesSessionPlot.getParentWallPane().synchronizeRatioPlotsScroll(zoomChunkX, zoomChunkY); + } else { + adjustZoom(); + } } } } }; addEventFilter(ScrollEvent.SCROLL, scrollEventEventHandler); + EventHandler mouseDraggedEventHandler = e -> { if (mouseInHouse(e.getX(), e.getY())) { - displayOffsetX = displayOffsetX + (convertMouseXToValue(mouseStartX) - convertMouseXToValue(e.getX())); - mouseStartX = e.getX(); - - if (this instanceof HistogramSinglePlot) { - displayOffsetY = Math.max(0.0, displayOffsetY + (convertMouseYToValue(mouseStartY) - convertMouseYToValue(e.getY()))); + if (e.getSource() instanceof BlockRatioCyclesSessionPlot) { + BlockRatioCyclesSessionPlot sourceBlockRatioCyclesSessionPlot = (BlockRatioCyclesSessionPlot) e.getSource(); + sourceBlockRatioCyclesSessionPlot.getParentWallPane().synchronizeRatioPlotsDrag(e.getX(), e.getY()); + } else if (e.getSource() instanceof LinePlot) { + LinePlot sourceLinePlot = (LinePlot) e.getSource(); + if (mouseInShadeHandle(plotBuilder.getShadeWidthForModelConvergence(), e.getX(), e.getY())) { + plotBuilder.setShadeWidthForModelConvergence(convertMouseXToValue(e.getX())); + sourceLinePlot.getParentWallPane().synchronizeConvergencePlotsShade(((LinePlotBuilder) plotBuilder).getBlockID(), convertMouseXToValue(e.getX())); + } + } else if (e.getSource() instanceof MultiLineIntensityPlot) { + MultiLineIntensityPlot sourceLinePlot = (MultiLineIntensityPlot) e.getSource(); + if (mouseInShadeHandle(plotBuilder.getShadeWidthForModelConvergence(), e.getX(), e.getY())) { + plotBuilder.setShadeWidthForModelConvergence(convertMouseXToValue(e.getX())); + sourceLinePlot.getParentWallPane().synchronizeConvergencePlotsShade(((MultiLinePlotBuilder) plotBuilder).getBlockID(), convertMouseXToValue(e.getX())); + } } else { - displayOffsetY = displayOffsetY + (convertMouseYToValue(mouseStartY) - convertMouseYToValue(e.getY())); - } - mouseStartY = e.getY(); + displayOffsetX = displayOffsetX + (convertMouseXToValue(mouseStartX) - convertMouseXToValue(e.getX())); + mouseStartX = e.getX(); + + if (this instanceof HistogramSinglePlot) { + displayOffsetY = Math.max(0.0, displayOffsetY + (convertMouseYToValue(mouseStartY) - convertMouseYToValue(e.getY()))); + } else { + displayOffsetY = displayOffsetY + (convertMouseYToValue(mouseStartY) - convertMouseYToValue(e.getY())); + } + mouseStartY = e.getY(); - calculateTics(); - repaint(); + calculateTics(); + repaint(); + } } }; addEventFilter(MouseEvent.MOUSE_DRAGGED, mouseDraggedEventHandler); + EventHandler mousePressedEventHandler = e -> { if (mouseInHouse(e.getX(), e.getY()) && e.isPrimaryButtonDown()) { - mouseStartX = e.getX(); - mouseStartY = e.getY(); + if (e.getSource() instanceof BlockRatioCyclesSessionPlot) { + BlockRatioCyclesSessionPlot sourceBlockRatioCyclesSessionPlot = (BlockRatioCyclesSessionPlot) e.getSource(); + sourceBlockRatioCyclesSessionPlot.getParentWallPane().synchronizeMouseStartsOnPress(e.getX(), e.getY()); + } else { + adjustMouseStartsForPress(e.getX(), e.getY()); + } } }; addEventFilter(MouseEvent.MOUSE_PRESSED, mousePressedEventHandler); setOnMouseClicked(new MouseClickEventHandler()); } + public PlotBuilder getPlotBuilder() { + return plotBuilder; + } + public TripoliColor getDataColor() { return dataColor; } @@ -215,6 +250,13 @@ public void paint(GraphicsContext g2d) { plotStats(g2d); } + if (this instanceof LinePlot) { + ((LinePlot) this).plotLeftShade(g2d); + } + if (this instanceof MultiLineIntensityPlot) { + ((MultiLineIntensityPlot) this).plotLeftShade(g2d); + } + drawAxes(g2d); labelAxisX(g2d); labelAxisY(g2d); @@ -233,14 +275,14 @@ public void prepareExtents(boolean reScaleX, boolean reScaleY) { } public void calculateTics() { - ticsX = TicGeneratorForAxes.generateTics(getDisplayMinX(), getDisplayMaxX(), (int) (plotWidth / 50.0)); + ticsX = TicGeneratorForAxes.generateTics(getDisplayMinX(), getDisplayMaxX(), Math.max(4, (int) (plotWidth / 50.0))); if (0 == ticsX.length) { ticsX = new BigDecimal[2]; ticsX[0] = new BigDecimal(Double.toString(minX)); ticsX[ticsX.length - 1] = new BigDecimal(Double.toString(maxX)); } - ticsY = TicGeneratorForAxes.generateTics(getDisplayMinY(), getDisplayMaxY(), (int) (plotHeight / 15.0)); + ticsY = TicGeneratorForAxes.generateTics(getDisplayMinY(), getDisplayMaxY(), Math.max(4, (int) (plotHeight / 15.0))); if ((0 == ticsY.length) && !Double.isInfinite(minY)) { ticsY = new BigDecimal[2]; ticsY[0] = new BigDecimal(Double.toString(minY)); @@ -270,9 +312,10 @@ private void drawAxes(GraphicsContext g2d) { g2d.strokeLine( leftMargin, mapY(bigDecimalTicY.doubleValue()), leftMargin + plotWidth, mapY(bigDecimalTicY.doubleValue())); // left side - Formatter fmt = new Formatter(); - fmt.format("%8.5g", bigDecimalTicY.doubleValue()); - String yText = fmt.toString().trim(); + double ticValue = bigDecimalTicY.doubleValue(); + DecimalFormat df = new DecimalFormat((99999 < Math.abs(ticValue) || 1.0e-5 > Math.abs(ticValue)) ? "0.0####E0" : "#####0.#####"); + String yText = (ticValue == 0.0) ? "0" : df.format(ticValue); + text.setText(yText); textWidth = (int) text.getLayoutBounds().getWidth(); g2d.fillText(text.getText(),// @@ -292,10 +335,10 @@ private void drawAxes(GraphicsContext g2d) { mapX(ticsX[i].doubleValue()), topMargin + plotHeight + 3); // bottom - // http://www.java2s.com/Tutorials/Java/String/How_to_use_Java_Formatter_to_format_value_in_scientific_notation.htm#:~:text=%25e%20is%20for%20scientific%20notation,scientific%20notation%2C%20use%20%25e. - Formatter fmt = new Formatter(); - fmt.format("%8.5g", ticsX[i].doubleValue()); - String xText = fmt.toString().trim(); + double ticValue = ticsX[i].doubleValue(); + DecimalFormat df = new DecimalFormat((99999 < Math.abs(ticValue) || 1.0e-5 > Math.abs(ticValue)) ? "0.0####E0" : "#####0.#####"); + String xText = (ticValue == 0.0) ? "0" : df.format(ticValue); + g2d.fillText(xText, (float) mapX(ticsX[i].doubleValue()) - 7.0f, (float) topMargin + plotHeight + 10); @@ -326,9 +369,9 @@ public void showTitle(GraphicsContext g2d) { private void labelAxisX(GraphicsContext g2d) { Paint savedPaint = g2d.getFill(); g2d.setFill(Paint.valueOf("BLACK")); - g2d.setFont(Font.font("SansSerif", 11)); + g2d.setFont(Font.font("SansSerif", 14)); Text text = new Text(); - text.setFont(Font.font("SansSerif", 11)); + text.setFont(Font.font("SansSerif", 14)); text.setText(plotAxisLabelX); int textWidth = (int) text.getLayoutBounds().getWidth(); g2d.fillText(text.getText(), leftMargin + (plotWidth - textWidth) / 2.0, plotHeight + 2.0 * topMargin - 2.0); @@ -338,9 +381,9 @@ private void labelAxisX(GraphicsContext g2d) { private void labelAxisY(GraphicsContext g2d) { Paint savedPaint = g2d.getFill(); g2d.setFill(Paint.valueOf("BLACK")); - g2d.setFont(Font.font("SansSerif", 11)); + g2d.setFont(Font.font("SansSerif", 14)); Text text = new Text(); - text.setFont(Font.font("SansSerif", 11)); + text.setFont(Font.font("SansSerif", 14)); text.setText(plotAxisLabelY); int textWidth = (int) text.getLayoutBounds().getWidth(); g2d.rotate(-90.0); @@ -542,8 +585,43 @@ public void setHeightF(double height) { this.height = height; } - public void performPrimaryClick(double mouseX, double mouseY) { + public void setZoomChunkX(double zoomChunkX) { + this.zoomChunkX = zoomChunkX; + } + + public void setZoomChunkY(double zoomChunkY) { + this.zoomChunkY = zoomChunkY; + } + + public void adjustZoom() { + minX += zoomChunkX; + maxX -= zoomChunkX; + minY += zoomChunkY; + maxY -= zoomChunkY; + calculateTics(); + repaint(); + } + + public void adjustOffsetsForDrag(double x, double y) { + displayOffsetX = displayOffsetX + (convertMouseXToValue(mouseStartX) - convertMouseXToValue(x)); + mouseStartX = x; + displayOffsetY = displayOffsetY + (convertMouseYToValue(mouseStartY) - convertMouseYToValue(y)); + mouseStartY = y; + calculateTics(); + repaint(); + } + + public void adjustMouseStartsForPress(double x, double y) { + mouseStartX = x; + mouseStartY = y; + } + + public boolean mouseInShadeHandle(double shadeWidthForModelConvergence, double x, double y) { + boolean inWidth = (x >= mapX(shadeWidthForModelConvergence) - 20) && (x <= mapX(shadeWidthForModelConvergence) + 20); + boolean inHeight = (y >= (mapY(minY) - mapY(maxY)) / 2 + mapY(maxY) - 20) && (y <= (mapY(minY) - mapY(maxY)) / 2 + mapY(maxY) + 20); + + return inWidth && inHeight; } class MouseClickEventHandler implements EventHandler { @@ -551,15 +629,20 @@ class MouseClickEventHandler implements EventHandler { public void handle(MouseEvent mouseEvent) { plotContextMenu.hide(); boolean isPrimary = (0 == mouseEvent.getButton().compareTo(MouseButton.PRIMARY)); + boolean isBlockRatioCyclesSessionPlot = (mouseEvent.getSource() instanceof BlockRatioCyclesSessionPlot); if (mouseInHouse(mouseEvent.getX(), mouseEvent.getY())) { - if (isPrimary) { - performPrimaryClick(mouseEvent.getX(), mouseEvent.getY()); - } else { + if (isPrimary && isBlockRatioCyclesSessionPlot) { + BlockRatioCyclesSessionPlot blockRatioCyclesSessionPlot = (BlockRatioCyclesSessionPlot) mouseEvent.getSource(); + // determine blockID + double xValue = convertMouseXToValue(mouseEvent.getX()); + int blockID = (int) ((xValue - 0.7) / blockRatioCyclesSessionPlot.getBlockRatioCyclesSessionRecord().cyclesPerBlock()) + 1; + BlockRatioCyclesSessionPlot sourceBlockRatioCyclesSessionPlot = (BlockRatioCyclesSessionPlot) mouseEvent.getSource(); + sourceBlockRatioCyclesSessionPlot.getParentWallPane().synchronizeBlockToggle(blockID); + } else if (!isPrimary) { plotContextMenu.show((Node) mouseEvent.getSource(), Side.LEFT, mouseEvent.getX() - getLayoutX(), mouseEvent.getY() - getLayoutY()); } } } } - } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPane.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPane.java index 06a6b885..c7e691b2 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPane.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPane.java @@ -17,15 +17,27 @@ package org.cirdles.tripoli.gui.dataViews.plots; import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.*; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.Pane; +import org.cirdles.tripoli.gui.AnalysisManagerCallbackI; +import org.cirdles.tripoli.gui.constants.ConstantsTripoliApp; +import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.mcmcPlots.MCMCPlotsController; +import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.mcmcPlots.MCMCPlotsControllerInterface; +import org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots.sessionPlots.BlockRatioCyclesSessionPlot; +import org.cirdles.tripoli.sessions.analysis.Analysis; +import org.cirdles.tripoli.sessions.analysis.AnalysisInterface; +import org.cirdles.tripoli.sessions.analysis.massSpectrometerModels.dataModels.mcmc.EnsemblesStore; import java.util.List; import java.util.stream.Collectors; +import static org.cirdles.tripoli.constants.TripoliConstants.*; +import static org.cirdles.tripoli.sessions.analysis.massSpectrometerModels.dataModels.mcmc.BlockEnsemblesPlotter.blockEnsemblePlotEngine; + /** * @author James F. Bowring */ @@ -34,25 +46,41 @@ public class PlotWallPane extends Pane { public static final double gridCellDim = 2.0; public static final double toolBarHeight = 35.0; public static double menuOffset = 30.0; - private String iD; + private final String iD; + private final boolean[] zoomFlagsXY = new boolean[2]; + private final AnalysisInterface analysis; + private final MCMCPlotsControllerInterface mcmcPlotsControllerInterface; + AnalysisManagerCallbackI analysisManagerCallbackI; private boolean logScale; + private ConstantsTripoliApp.PlotLayoutStyle plotLayoutStyle; - private boolean[] zoomFlagsXY = new boolean[2]; - - private PlotWallPane(String iD) { + private PlotWallPane(String iD, AnalysisInterface analysis, MCMCPlotsControllerInterface mcmcPlotsControllerInterface, AnalysisManagerCallbackI analysisManagerCallbackI) { this.iD = iD; zoomFlagsXY[0] = true; zoomFlagsXY[1] = true; + this.analysis = analysis; + this.mcmcPlotsControllerInterface = mcmcPlotsControllerInterface; + this.analysisManagerCallbackI = analysisManagerCallbackI; + plotLayoutStyle = ConstantsTripoliApp.PlotLayoutStyle.TILE; + } - public static PlotWallPane createPlotWallPane(String iD) { - if (iD == null) { - return new PlotWallPane("NONE"); + public static PlotWallPane createPlotWallPane( + String iD, + AnalysisInterface analysis, + MCMCPlotsControllerInterface mcmcPlotsControllerInterface, + AnalysisManagerCallbackI analysisManagerCallbackI) { + if (null == iD) { + return new PlotWallPane("NONE", analysis, mcmcPlotsControllerInterface, analysisManagerCallbackI); } else { - return new PlotWallPane(iD); + return new PlotWallPane(iD, analysis, mcmcPlotsControllerInterface, analysisManagerCallbackI); } } + public AnalysisInterface getAnalysis() { + return analysis; + } + public void tilePlots() { List plotPanes = getChildren() .stream() @@ -62,10 +90,12 @@ public void tilePlots() { double widthTileCount = Math.min(5, plotPanes.size()); double heightTileCount = Math.ceil(plotPanes.size() / widthTileCount); - double displayWidth = ((getParent().getBoundsInParent().getWidth() - gridCellDim * 2.0) / widthTileCount); + double parentWidth = Math.max(((AnchorPane) getParent()).getPrefWidth(), ((AnchorPane) getParent()).getMinWidth()); + double displayWidth = (parentWidth - gridCellDim * 2.0) / widthTileCount; double tileWidth = displayWidth - displayWidth % gridCellDim; - double displayHeight = ((getParent().getBoundsInParent().getHeight() - toolBarHeight - gridCellDim * heightTileCount) / heightTileCount); + double parentHeight = Math.max(((AnchorPane) getParent()).getPrefHeight(), ((AnchorPane) getParent()).getMinHeight()); + double displayHeight = (parentHeight - toolBarHeight - gridCellDim * heightTileCount) / heightTileCount; double tileHeight = displayHeight - displayHeight % gridCellDim; int plotIndex = 0; @@ -79,24 +109,45 @@ public void tilePlots() { plotIndex++; } + + plotLayoutStyle = ConstantsTripoliApp.PlotLayoutStyle.TILE; } - public void stackPlots() { - double tileWidth; - double displayHeight; - if (iD.compareToIgnoreCase("OGTripoliSession") == 0) { - tileWidth = ((AnchorPane) getParent()).getPrefWidth() - gridCellDim * 2.0; - displayHeight = (((AnchorPane) getParent()).getPrefHeight() - toolBarHeight) / getCountOfPlots(); - } else { - tileWidth = (getParent().getBoundsInParent().getWidth() - gridCellDim * 2.0); - displayHeight = (getParent().getBoundsInParent().getHeight() - toolBarHeight) / getCountOfPlots(); + public void clearTripoliPanes() { + List plotPanes = getChildren() + .stream() + .filter(plot -> plot instanceof TripoliPlotPane) + .collect(Collectors.toList()); + for (Node plotPane : plotPanes) { + getChildren().remove(plotPane); } + } - double tileHeight = displayHeight - displayHeight % gridCellDim; + public void stackPlots() { + if (null != getParent()) { + List plotPanes = getChildren() + .stream() + .filter(plot -> plot instanceof TripoliPlotPane) + .collect(Collectors.toList()); + double tileWidth; + double displayHeight; + if (0 == iD.compareToIgnoreCase("OGTripoliSession")) { + double parentWidth = Math.max(((AnchorPane) getParent()).getPrefWidth(), ((AnchorPane) getParent()).getMinWidth()); + tileWidth = parentWidth - gridCellDim * 2.0; + double parentHeight = Math.max(((AnchorPane) getParent()).getPrefHeight(), ((AnchorPane) getParent()).getMinHeight()); + displayHeight = (parentHeight - toolBarHeight) / getCountOfPlots(); + } else { + double parentWidth = Math.max(((AnchorPane) getParent()).getPrefWidth(), ((AnchorPane) getParent()).getMinWidth()); + tileWidth = (parentWidth - gridCellDim * 2.0); + + double parentHeight = Math.max(((AnchorPane) getParent()).getPrefHeight(), ((AnchorPane) getParent()).getMinHeight()); + displayHeight = (parentHeight - toolBarHeight) / getCountOfPlots(); + } - int plotIndex = 0; - for (Node plotPane : getChildren()) { - if (plotPane instanceof TripoliPlotPane) { + double tileHeight = displayHeight - displayHeight % gridCellDim; + + int plotIndex = 0; + for (Node plotPane : plotPanes) { plotPane.setLayoutY(gridCellDim + toolBarHeight + tileHeight * plotIndex); ((Pane) plotPane).setPrefHeight(tileHeight); plotPane.setLayoutX(gridCellDim); @@ -107,15 +158,19 @@ public void stackPlots() { plotIndex++; } } + plotLayoutStyle = ConstantsTripoliApp.PlotLayoutStyle.STACK; } public void cascadePlots() { double cascadeLap = 20.0; - double displayWidth = getParent().getBoundsInParent().getWidth() - cascadeLap * (getCountOfPlots() - 1); + + double parentWidth = Math.max(((AnchorPane) getParent()).getPrefWidth(), ((AnchorPane) getParent()).getMinWidth()); + double displayWidth = parentWidth - cascadeLap * (getCountOfPlots() - 1); double tileWidth = displayWidth - gridCellDim; - double displayHeight = getParent().getBoundsInParent().getHeight() - toolBarHeight - cascadeLap * (getCountOfPlots() - 1); + double parentHeight = Math.max(((AnchorPane) getParent()).getPrefHeight(), ((AnchorPane) getParent()).getMinHeight()); + double displayHeight = parentHeight - toolBarHeight - cascadeLap * (getCountOfPlots() - 1); double tileHeight = displayHeight - gridCellDim; int plotIndex = 0; @@ -131,6 +186,15 @@ public void cascadePlots() { plotIndex++; } } + plotLayoutStyle = ConstantsTripoliApp.PlotLayoutStyle.CASCADE; + } + + public void repeatLayoutStyle() { + switch (plotLayoutStyle) { + case TILE -> tilePlots(); + case STACK -> stackPlots(); + case CASCADE -> cascadePlots(); + } } public void restoreAllPlots() { @@ -157,6 +221,21 @@ public void toggleRatiosLogRatios() { } } + public void applyBurnIn() { + int burnIn = (int) analysis.getMapOfBlockIdToPlots().get(MCMCPlotsController.currentBlockID)[5][0].getShadeWidthForModelConvergence(); + int blockID = MCMCPlotsController.currentBlockID; + analysis.getMapOfBlockIdToModelsBurnCount().put(blockID, burnIn); + blockEnsemblePlotEngine(blockID, analysis); + mcmcPlotsControllerInterface.plotEnsemblesEngine(analysis.getMapOfBlockIdToPlots().get(blockID)); + mcmcPlotsControllerInterface.plotRatioSessionEngine(); + EnsemblesStore.produceSummaryModelFromEnsembleStore(blockID, analysis); + + // fire up OGTripoli style session plots + if (null != analysisManagerCallbackI) { + analysisManagerCallbackI.reviewAndSculptDataAction(); + } + } + private int getCountOfPlots() { List plots = getChildren() .stream() @@ -169,25 +248,41 @@ public void buildToolBar() { ToolBar toolBar = new ToolBar(); toolBar.setPrefHeight(toolBarHeight); - Button button0 = new Button("Restore Plots"); - button0.setOnAction(event -> restoreAllPlots()); + Button restoreButton = new Button("Restore Plots"); + restoreButton.setOnAction(event -> restoreAllPlots()); + toolBar.getItems().add(restoreButton); - Button button1 = new Button("Tile Plots"); - button1.setOnAction(event -> tilePlots()); + if ((0 != iD.compareToIgnoreCase(PLOT_TAB_CONVERGE)) + && (0 != iD.compareToIgnoreCase(PLOT_TAB_CONVERGE_INTENSITY))) { + Button statsButton = new Button("Toggle Plots' Stats"); + statsButton.setOnAction(event -> toggleShowStatsAllPlots()); + toolBar.getItems().add(statsButton); - Button button2 = new Button("Stack Plots"); - button2.setOnAction(event -> stackPlots()); + Button ratioLogsButton = new Button("Toggle Ratios / LogRatios"); + ratioLogsButton.setOnAction(event -> toggleRatiosLogRatios()); + toolBar.getItems().add(ratioLogsButton); + } - Button button3 = new Button("Cascade Plots"); - button3.setOnAction(event -> cascadePlots()); + if (0 != iD.compareToIgnoreCase(PLOT_TAB_CONVERGE_INTENSITY)) { + Button tileButton = new Button("Tile Plots"); + tileButton.setOnAction(event -> tilePlots()); + toolBar.getItems().add(tileButton); - Button button4 = new Button("Toggle Plots' Stats"); - button4.setOnAction(event -> toggleShowStatsAllPlots()); + Button stackButton = new Button("Stack Plots"); + stackButton.setOnAction(event -> stackPlots()); + toolBar.getItems().add(stackButton); - Button button5 = new Button("Toggle Ratios / LogRatios"); - button5.setOnAction(event -> toggleRatiosLogRatios()); + Button cascadeButton = new Button("Cascade Plots"); + cascadeButton.setOnAction(event -> cascadePlots()); + toolBar.getItems().add(cascadeButton); + } + + if (0 == iD.compareToIgnoreCase(PLOT_TAB_ENSEMBLES)) { + Button button6 = new Button("Apply BurnIn"); + button6.setOnAction(event -> applyBurnIn()); + toolBar.getItems().addAll(button6); + } - toolBar.getItems().addAll(button0, button5, button4, button1, button2, button3); getChildren().addAll(toolBar); } @@ -196,6 +291,14 @@ public void buildScaleControlsToolbar() { toolBar.setPrefHeight(toolBarHeight); toolBar.setLayoutY(0.0); + Button button0 = new Button("Restore Plots"); + button0.setOnAction(event -> restoreAllPlots()); + toolBar.getItems().add(button0); + + Button button1 = new Button("Toggle Stats"); + button1.setOnAction(event -> toggleShowStatsAllPlots()); + toolBar.getItems().add(button1); + Label labelScale = new Label("Scale:"); labelScale.setAlignment(Pos.CENTER_RIGHT); labelScale.setPrefWidth(60); @@ -223,7 +326,7 @@ public void buildScaleControlsToolbar() { countsRB.selectedProperty().addListener( (ObservableValue ov, Boolean oldVal, Boolean newVal) -> { if (newVal) { - zoomFlagsXY[0] = false; + zoomFlagsXY[0] = true; zoomFlagsXY[1] = true; } resetZoom(); @@ -272,4 +375,59 @@ private void resetZoom() { } } } + + public void synchronizeRatioPlotsScroll(double zoomChunkX, double zoomChunkY) { + ObservableList children = getChildren(); + for (Node child : children) { + if (child instanceof TripoliPlotPane) { + BlockRatioCyclesSessionPlot childPlot = (BlockRatioCyclesSessionPlot) ((TripoliPlotPane) child).getChildren().get(0); + childPlot.setZoomChunkX(zoomChunkX); + childPlot.setZoomChunkY(zoomChunkY); + childPlot.adjustZoom(); + } + } + } + + public void synchronizeRatioPlotsDrag(double x, double y) { + ObservableList children = getChildren(); + for (Node child : children) { + if (child instanceof TripoliPlotPane) { + BlockRatioCyclesSessionPlot childPlot = (BlockRatioCyclesSessionPlot) ((TripoliPlotPane) child).getChildren().get(0); + childPlot.adjustOffsetsForDrag(x, y); + } + } + } + + public void synchronizeConvergencePlotsShade(int blockID, double shadeWidth) { + ((Analysis) analysis).updateShadeWidthsForConvergenceLinePlots(blockID, shadeWidth); + ObservableList children = getChildren(); + for (Node child : children) { + if ((child instanceof TripoliPlotPane) && (((TripoliPlotPane) child).getChildren().get(0) instanceof AbstractPlot)) { + ((AbstractPlot) ((TripoliPlotPane) child).getChildren().get(0)).repaint(); + } + } + } + + public void synchronizeMouseStartsOnPress(double x, double y) { + ObservableList children = getChildren(); + for (Node child : children) { + if (child instanceof TripoliPlotPane) { + BlockRatioCyclesSessionPlot childPlot = (BlockRatioCyclesSessionPlot) ((TripoliPlotPane) child).getChildren().get(0); + childPlot.adjustMouseStartsForPress(x, y); + } + } + } + + public void synchronizeBlockToggle(int blockID) { + ObservableList children = getChildren(); + for (Node child : children) { + if (child instanceof TripoliPlotPane) { + BlockRatioCyclesSessionPlot childPlot = (BlockRatioCyclesSessionPlot) ((TripoliPlotPane) child).getChildren().get(0); + childPlot.getMapBlockIdToBlockRatioCyclesRecord().put( + blockID, + childPlot.getMapBlockIdToBlockRatioCyclesRecord().get(blockID).toggleBlockIncluded()); + childPlot.repaint(); + } + } + } } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPaneOGTripoli.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPaneOGTripoli.java index 8f9d820e..a79a5a20 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPaneOGTripoli.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/PlotWallPaneOGTripoli.java @@ -67,8 +67,10 @@ public void stackPlots() { double tileWidth; double displayHeight; if (iD.compareToIgnoreCase("OGTripoliSession") == 0) { - tileWidth = ((AnchorPane) getParent()).getPrefWidth() - gridCellDim * 2.0; - displayHeight = (((AnchorPane) getParent()).getPrefHeight() - toolBarHeight * 2.0); + double parentWidth = Math.max(((AnchorPane) getParent()).getPrefWidth(), ((AnchorPane) getParent()).getMinWidth()); + tileWidth = parentWidth - gridCellDim * 2.0; + double parentHeight = Math.max(((AnchorPane) getParent()).getPrefHeight(), ((AnchorPane) getParent()).getMinHeight()); + displayHeight = (parentHeight - toolBarHeight); } else { tileWidth = (getParent().getBoundsInParent().getWidth() - gridCellDim * 1.0); displayHeight = (getParent().getBoundsInParent().getHeight() - toolBarHeight); diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TicGeneratorForAxes.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TicGeneratorForAxes.java index 41f88eab..2127bc84 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TicGeneratorForAxes.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TicGeneratorForAxes.java @@ -54,7 +54,7 @@ public static BigDecimal[] generateTics(double axisMin, double axisMax, int numb nfrac = (int) StrictMath.max(-StrictMath.floor(StrictMath.log10(d)), 0); - BigDecimal[] tics = new BigDecimal[0]; + BigDecimal[] tics; try { tics = new BigDecimal[(int) ((ticMax + 0.5 * d - ticMin) / d) + 1]; @@ -64,6 +64,26 @@ public static BigDecimal[] generateTics(double axisMin, double axisMax, int numb index++; } } catch (Exception e) { + tics = new BigDecimal[0]; + } + + return formatTicsWhenAllInteger(tics); + } + + private static boolean isIntegerValue(BigDecimal bd) { + return 0 == bd.signum() || 0 >= bd.scale() || 0 >= bd.stripTrailingZeros().scale(); + } + + private static BigDecimal[] formatTicsWhenAllInteger(BigDecimal[] origTics) { + BigDecimal[] tics = new BigDecimal[origTics.length]; + for (int i = 0; i < origTics.length; i++) { + if (isIntegerValue(origTics[i])) { + tics[i] = origTics[i].setScale(0); + } else { + // at least one non-integer + tics = origTics.clone(); + break; + } } return tics; @@ -76,9 +96,7 @@ public static BigDecimal[] generateTics(double axisMin, double axisMax, int numb * @return */ public static double generateMarginAdjustment(double min, double max, double marginStretchFactor) { - return marginStretchFactor * (max - min); - } private static double niceNum(double x, boolean round) { diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TripoliPlotPane.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TripoliPlotPane.java index 37a14011..dd67c4b7 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TripoliPlotPane.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/TripoliPlotPane.java @@ -16,6 +16,8 @@ package org.cirdles.tripoli.gui.dataViews.plots; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; import javafx.scene.Cursor; import javafx.scene.control.ColorPicker; @@ -135,8 +137,19 @@ private TripoliPlotPane(Pane plotWallPane) { public static TripoliPlotPane makePlotPane(Pane plotWallPane) { TripoliPlotPane tripoliPlotPane = new TripoliPlotPane(plotWallPane); - tripoliPlotPane.setPrefSize(minPlotWidth, minPlotHeight); - tripoliPlotPane.setLayoutX(40.0); + +// tripoliPlotPane.prefWidthProperty().bind(plotWallPane.widthProperty()); +// tripoliPlotPane.prefHeightProperty().bind(plotWallPane.heightProperty()); + + tripoliPlotPane.widthProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Number oldValue, Number newValue) { + ((AbstractPlot) tripoliPlotPane.getChildren().get(0)).setWidthF((Double) newValue); + ((AbstractPlot) tripoliPlotPane.getChildren().get(0)).refreshPanel(false, false); + } + }); + + tripoliPlotPane.setLayoutX(0.0); tripoliPlotPane.setLayoutY(40.0); tripoliPlotPane.initializePlotPane(); @@ -157,14 +170,14 @@ private void toggleFullSize() { if (null == plotLocation) { plotLocation = new PlotLocation(getLayoutX(), getLayoutY(), getPrefWidth(), getPrefHeight()); setLayoutX(gridCellDim); - setPrefWidth(plotWallPane.getWidth() - 2 * gridCellDim); +// setPrefWidth(plotWallPane.getWidth() - 2 * gridCellDim); setLayoutY(gridCellDim); - setPrefHeight(plotWallPane.getHeight() - 2 * gridCellDim); +// setPrefHeight(plotWallPane.getHeight() - 2 * gridCellDim); } else { setLayoutX(plotLocation.x()); - setPrefWidth(plotLocation.w()); +// setPrefWidth(plotLocation.w()); setLayoutY(plotLocation.y()); - setPrefHeight(plotLocation.h()); +// setPrefHeight(plotLocation.h()); plotLocation = null; } updatePlot(); @@ -172,9 +185,9 @@ private void toggleFullSize() { public void snapToGrid() { setLayoutX(getLayoutX() - (getLayoutX() % gridCellDim)); - setPrefWidth(getPrefWidth() - (getPrefWidth() % gridCellDim)); +// setPrefWidth(getPrefWidth() - (getPrefWidth() % gridCellDim)); setLayoutY(getLayoutY() - (getLayoutY() % gridCellDim)); - setPrefHeight(getPrefHeight() - (getPrefHeight() % gridCellDim)); +// setPrefHeight(getPrefHeight() - (getPrefHeight() % gridCellDim)); updatePlot(); } @@ -194,9 +207,9 @@ public void addPlot(AbstractPlot plot) { plot.setWidthF(getWidth()); plot.setHeightF(getHeight()); - plot.widthProperty().bind(prefWidthProperty()); + plot.widthProperty().bind(widthProperty()); widthProperty().addListener((observable, oldValue, newValue) -> { - plot.setWidthF(newValue.doubleValue()); +// plot.setWidthF(newValue.doubleValue()); plot.updatePlotSize(); plot.repaint(); }); diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotBuildersTask.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotBuildersTask.java index 34a2c9aa..8bd07bd5 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotBuildersTask.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotBuildersTask.java @@ -21,7 +21,7 @@ import org.cirdles.tripoli.sessions.analysis.AnalysisInterface; import org.cirdles.tripoli.utilities.callbacks.LoggingCallbackInterface; -import static org.cirdles.tripoli.sessions.analysis.massSpectrometerModels.dataModels.mcmc.SingleBlockDataModelPlot.PLOT_INDEX_RATIOS; +import static org.cirdles.tripoli.constants.TripoliConstants.*; /** * @author James F. Bowring @@ -29,7 +29,7 @@ public class MCMCPlotBuildersTask extends Task implements LoggingCallbackInterface, PlotBuildersTaskInterface { public static AnalysisInterface analysis; private final int blockID; - // ensemble plots + // plotBuilders private PlotBuilder[] ratiosHistogramBuilder; private PlotBuilder[] baselineHistogramBuilder; private PlotBuilder[] dalyFaradayGainHistogramBuilder; @@ -53,10 +53,17 @@ public class MCMCPlotBuildersTask extends Task implements LoggingCallbac private PlotBuilder[] observedDataWithSubsetsLineBuilder; private PlotBuilder[] peakShapesBuilder; + // TODO: refactor to all plotBuilders + private PlotBuilder[][] plotBuilders; + public MCMCPlotBuildersTask(int blockID) { this.blockID = blockID; } + public PlotBuilder[][] getPlotBuilders() { + return plotBuilders; + } + public boolean healthyPlotbuilder() { return (ratiosHistogramBuilder != null); } @@ -81,11 +88,6 @@ public PlotBuilder[] getDalyFaradayGainHistogramBuilder() { return dalyFaradayGainHistogramBuilder.clone(); } -// @Override -// public PlotBuilder[] getSignalNoiseHistogramBuilder() { -// return signalNoiseHistogramBuilder.clone(); -// } - @Override public PlotBuilder[] getMeanIntensityVsKnotsMultiLineBuilder() { return meanIntensityVsKnotsMultiLineBuilder.clone(); @@ -126,43 +128,36 @@ public PlotBuilder[] getConvergeIntensityLinesBuilder() { return convergeIntensityLinesBuilder; } -// @Override -// public PlotBuilder[] getConvergeNoiseFaradayLineBuilder() { -// return convergeNoiseFaradayLineBuilder.clone(); -// } - public PlotBuilder[] getObservedDataWithSubsetsLineBuilder() { return observedDataWithSubsetsLineBuilder; } @Override public synchronized String call() throws Exception { - PlotBuilder[][] plots = analysis.updatePlotsByBlock(blockID, this); - + plotBuilders = analysis.updatePlotsByBlock(blockID, this); peakShapesBuilder = analysis.updatePeakPlotsByBlock(blockID); - ratiosHistogramBuilder = plots[PLOT_INDEX_RATIOS]; - baselineHistogramBuilder = plots[1]; - dalyFaradayGainHistogramBuilder = plots[2]; -// signalNoiseHistogramBuilder = plots[3]; - meanIntensityVsKnotsMultiLineBuilder = plots[4]; + ratiosHistogramBuilder = plotBuilders[PLOT_INDEX_RATIOS]; + baselineHistogramBuilder = plotBuilders[PLOT_INDEX_BASELINES]; + dalyFaradayGainHistogramBuilder = plotBuilders[PLOT_INDEX_DFGAINS]; + meanIntensityVsKnotsMultiLineBuilder = plotBuilders[PLOT_INDEX_MEANINTENSITIES]; - convergeRatioLineBuilder = plots[5]; + convergeRatioLineBuilder = plotBuilders[5]; - convergeBLFaradayLineBuilder = plots[6]; + convergeBLFaradayLineBuilder = plotBuilders[6]; - convergeErrWeightedMisfitLineBuilder = plots[8]; - convergeErrRawMisfitLineBuilder = plots[9]; - convergeIntensityLinesBuilder = plots[10]; + convergeErrWeightedMisfitLineBuilder = plotBuilders[8]; + convergeErrRawMisfitLineBuilder = plotBuilders[9]; + convergeIntensityLinesBuilder = plotBuilders[10]; - //convergeNoiseFaradayLineBuilder = plots[11]; + //convergeNoiseFaradayLineBuilder = plotBuilders[11]; - observedDataLineBuilder = plots[13]; - residualDataLineBuilder = plots[14]; + observedDataLineBuilder = plotBuilders[13]; + residualDataLineBuilder = plotBuilders[14]; - observedDataWithSubsetsLineBuilder = plots[15]; + observedDataWithSubsetsLineBuilder = plotBuilders[15]; - return analysis.getDataFilePathString() + "Block # " + blockID + "\n\n\tDONE - view tabs for various plots"; + return analysis.getDataFilePathString() + "Block # " + blockID + "\n\n\tDONE - view tabs for various plotBuilders"; } @Override diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsController.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsController.java index 6587a57b..a5fe7fbd 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsController.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsController.java @@ -4,6 +4,7 @@ import javafx.collections.ObservableList; import javafx.concurrent.Service; import javafx.concurrent.Task; +import javafx.event.Event; import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.input.MouseButton; @@ -13,10 +14,7 @@ import javafx.scene.layout.VBox; import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; -import org.cirdles.tripoli.gui.AnalysisManagerCallbackI; -import org.cirdles.tripoli.gui.OGTripoliPlotsWindow; -import org.cirdles.tripoli.gui.OGTripoliViewController; -import org.cirdles.tripoli.gui.TripoliGUI; +import org.cirdles.tripoli.gui.*; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; import org.cirdles.tripoli.gui.dataViews.plots.PlotWallPane; import org.cirdles.tripoli.gui.dataViews.plots.TripoliPlotPane; @@ -29,6 +27,7 @@ import org.cirdles.tripoli.plots.linePlots.*; import org.cirdles.tripoli.plots.sessionPlots.HistogramSessionBuilder; import org.cirdles.tripoli.plots.sessionPlots.PeakCentreSessionBuilder; +import org.cirdles.tripoli.sessions.analysis.Analysis; import org.cirdles.tripoli.sessions.analysis.AnalysisInterface; import org.cirdles.tripoli.sessions.analysis.massSpectrometerModels.dataModels.mcmc.AllBlockInitForOGTripoli; import org.cirdles.tripoli.sessions.analysis.massSpectrometerModels.dataModels.mcmc.MCMCProcess; @@ -37,6 +36,7 @@ import java.net.URL; import java.util.*; +import static org.cirdles.tripoli.constants.TripoliConstants.*; import static org.cirdles.tripoli.gui.dataViews.plots.TripoliPlotPane.minPlotHeight; import static org.cirdles.tripoli.gui.dataViews.plots.TripoliPlotPane.minPlotWidth; import static org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.mcmcPlots.MCMCPlotsWindow.PLOT_WINDOW_HEIGHT; @@ -44,38 +44,34 @@ import static org.cirdles.tripoli.plots.sessionPlots.HistogramSessionBuilder.initializeHistogramSession; import static org.cirdles.tripoli.plots.sessionPlots.PeakCentreSessionBuilder.initializePeakCentreSession; import static org.cirdles.tripoli.sessions.analysis.Analysis.*; -import static org.cirdles.tripoli.sessions.analysis.massSpectrometerModels.dataModels.mcmc.SingleBlockDataModelPlot.PLOT_INDEX_RATIOS; -public class MCMCPlotsController { +public class MCMCPlotsController implements MCMCPlotsControllerInterface { - private static final int TAB_HEIGHT = 35; + private static final int TOOLBAR_HEIGHT = 30; public static AnalysisInterface analysis; + public static int currentBlockID = 0; public static AnalysisManagerCallbackI analysisManagerCallbackI; - public static OGTripoliPlotsWindow ogTripoliPlotsWindow; private static int MAX_BLOCK_COUNT = 2000; + @FXML - public AnchorPane dataFitPlotsAnchorPane; - @FXML - public AnchorPane convergeErrorPlotsAnchorPane; - @FXML - public AnchorPane beamShapeAnchorPane; + public AnchorPane logAnchorPane; @FXML - public AnchorPane ratioSessionAnchorPane; + public ProgressBar progressBar; @FXML - public AnchorPane peakSessionAnchorPane; + public Tab convergencesTab; @FXML - public AnchorPane logAnchorPane; + public Tab convergeErrorTab; @FXML - public ProgressBar progressBar; + public Tab convergeIntensityTab; + private Service[] services; @FXML private ResourceBundle resources; @FXML private URL location; - @FXML - private AnchorPane convergeIntensityAnchorPane; + @FXML private TextArea eventLogTextArea; @@ -95,7 +91,28 @@ public class MCMCPlotsController { @FXML private AnchorPane convergePlotsAnchorPane; @FXML + private AnchorPane convergeErrorPlotsAnchorPane; + @FXML + private AnchorPane convergeIntensityAnchorPane; + @FXML private AnchorPane ensemblePlotsAnchorPane; + @FXML + private AnchorPane dataFitPlotsAnchorPane; + @FXML + private AnchorPane beamShapeAnchorPane; + @FXML + private AnchorPane ratioSessionAnchorPane; + @FXML + private AnchorPane peakSessionAnchorPane; + + + private PlotWallPane convergePlotsWallPane; + private PlotWallPane convergeErrorPlotsWallPane; + private PlotWallPane convergeIntensityPlotsWallPane; + private PlotWallPane ensemblePlotsWallPane; + private PlotWallPane dataFitPlotsWallPane; + private PlotWallPane ratiosSessionPlotsWallPane; + private ListView listViewOfBlocks = new ListView<>(); @@ -107,7 +124,25 @@ public void plotIncomingAction() { void initialize() { eventLogTextArea.setText("Using MCMC with max of 100000 iterations"); masterVBox.setPrefSize(PLOT_WINDOW_WIDTH, PLOT_WINDOW_HEIGHT); - toolbar.setPrefSize(PLOT_WINDOW_WIDTH, 30.0); + toolbar.setPrefSize(PLOT_WINDOW_WIDTH, TOOLBAR_HEIGHT); + + plotTabPane.widthProperty().addListener((observable, oldValue, newValue) -> { + convergePlotsAnchorPane.setMinWidth((Double) newValue); + convergeErrorPlotsAnchorPane.setMinWidth((Double) newValue); + convergeIntensityAnchorPane.setMinWidth((Double) newValue); + ensemblePlotsAnchorPane.setMinWidth((Double) newValue); + dataFitPlotsAnchorPane.setMinWidth((Double) newValue); + ratioSessionAnchorPane.setMinWidth((Double) newValue); + }); + + plotTabPane.heightProperty().addListener((observable, oldValue, newValue) -> { + convergePlotsAnchorPane.setMinHeight(((Double) newValue) - TOOLBAR_HEIGHT); + convergeErrorPlotsAnchorPane.setMinHeight(((Double) newValue) - TOOLBAR_HEIGHT); + convergeIntensityAnchorPane.setMinHeight((Double) newValue - TOOLBAR_HEIGHT); + ensemblePlotsAnchorPane.setMinHeight((Double) newValue - TOOLBAR_HEIGHT); + dataFitPlotsAnchorPane.setMinHeight((Double) newValue - TOOLBAR_HEIGHT); + ratioSessionAnchorPane.setMinHeight((Double) newValue - TOOLBAR_HEIGHT); + }); plotTabPane.prefWidthProperty().bind(masterVBox.widthProperty()); plotTabPane.prefHeightProperty().bind(masterVBox.heightProperty()); @@ -120,7 +155,7 @@ private void populateListOfAvailableBlocks() { List blocksByName = new ArrayList<>(); for (Integer blockID : analysis.getMapOfBlockIdToProcessStatus().keySet()) { if (SKIP != analysis.getMapOfBlockIdToProcessStatus().get(blockID)) { - blocksByName.add("Block # " + blockID); + blocksByName.add("" + blockID); } } @@ -192,13 +227,13 @@ public synchronized void processDataFileAndShowPlotsOfMCMC(AnalysisInterface ana // fire up OGTripoli style session plots AllBlockInitForOGTripoli.PlottingData plottingData = analysis.assemblePostProcessPlottingData(); // ogTripoli view - if (null != ogTripoliPlotsWindow) { - ogTripoliPlotsWindow.close(); + if (null != AnalysisManagerController.ogTripoliPlotsWindow) { + AnalysisManagerController.ogTripoliPlotsWindow.close(); } - ogTripoliPlotsWindow = new OGTripoliPlotsWindow(TripoliGUI.primaryStage);//, this); + AnalysisManagerController.ogTripoliPlotsWindow = new OGTripoliPlotsWindow(TripoliGUI.primaryStage, analysisManagerCallbackI); OGTripoliViewController.analysis = analysis; OGTripoliViewController.plottingData = plottingData; - ogTripoliPlotsWindow.loadPlotsWindow(); + AnalysisManagerController.ogTripoliPlotsWindow.loadPlotsWindow(); } } }); @@ -230,7 +265,7 @@ public synchronized void processDataFileAndShowPlotsOfMCMC(AnalysisInterface ana } @FXML - private void plotRatioSessionEngine() { + public void plotRatioSessionEngine() { Map mapOfBlockIdToPlots = analysis.getMapOfBlockIdToPlots(); Map> mapRatioNameToSessionRecords = new TreeMap<>(); Iterator> iterator = mapOfBlockIdToPlots.entrySet().iterator(); @@ -252,11 +287,25 @@ private void plotRatioSessionEngine() { } } - ratioSessionAnchorPane.getChildren().removeAll(); - PlotWallPane ratiosSessionPlotsWallPane = PlotWallPane.createPlotWallPane(null); - ratiosSessionPlotsWallPane.buildToolBar(); - ratiosSessionPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - ratioSessionAnchorPane.getChildren().add(ratiosSessionPlotsWallPane); + plotTabPane.widthProperty().addListener((observable, oldValue, newValue) -> { + ratiosSessionPlotsWallPane.repeatLayoutStyle(); + }); + plotTabPane.heightProperty().addListener((observable, oldValue, newValue) -> { + ratiosSessionPlotsWallPane.repeatLayoutStyle(); + }); + + + if (ratioSessionAnchorPane.getChildren().isEmpty()) { + ratiosSessionPlotsWallPane = PlotWallPane.createPlotWallPane(null, analysis, this, analysisManagerCallbackI); + ratiosSessionPlotsWallPane.buildToolBar(); + ratiosSessionPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); + ratiosSessionPlotsWallPane.prefWidthProperty().bind(ratioSessionAnchorPane.widthProperty()); + ratiosSessionPlotsWallPane.prefHeightProperty().bind(ratioSessionAnchorPane.heightProperty()); + ratioSessionAnchorPane.getChildren().add(ratiosSessionPlotsWallPane); + } else { + ratiosSessionPlotsWallPane = (PlotWallPane) ratioSessionAnchorPane.getChildren().get(0); + ratiosSessionPlotsWallPane.clearTripoliPanes(); + } for (Map.Entry> entry : mapRatioNameToSessionRecords.entrySet()) { HistogramSessionBuilder histogramSessionBuilder = initializeHistogramSession( analysis.getMapOfBlockIdToProcessStatus().size(), entry.getValue(), entry.getValue().get(0).title(), "Block ID", "Ratio"); @@ -289,7 +338,7 @@ private void plotPeakSessionEngine() { } // TODO add peak session pane to fxml and controller peakSessionAnchorPane.getChildren().removeAll(); - PlotWallPane peakSessionPlotWallPlane = PlotWallPane.createPlotWallPane(null); + PlotWallPane peakSessionPlotWallPlane = PlotWallPane.createPlotWallPane(null, analysis, this, null); peakSessionPlotWallPlane.buildToolBar(); peakSessionPlotWallPlane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); peakSessionAnchorPane.getChildren().add(peakSessionPlotWallPlane); @@ -311,24 +360,18 @@ private void plotPeakSessionEngine() { private synchronized void plotBlockEngine(Task plotBuildersTaska) { analysisManagerCallbackI.callbackRefreshBlocksStatus(); - ensemblePlotsAnchorPane.getChildren().removeAll(); - convergePlotsAnchorPane.getChildren().removeAll(); - dataFitPlotsAnchorPane.getChildren().removeAll(); - convergeErrorPlotsAnchorPane.getChildren().removeAll(); - convergeIntensityAnchorPane.getChildren().removeAll(); - beamShapeAnchorPane.getChildren().removeAll(); + + if (!beamShapeAnchorPane.getChildren().isEmpty()) { + beamShapeAnchorPane.getChildren().remove(0); + } PlotBuildersTaskInterface plotBuildersTask = (PlotBuildersTaskInterface) plotBuildersTaska; + PlotBuilder[] peakShapeOverlayBuilder = plotBuildersTask.getPeakShapesBuilder(); - PlotBuilder[] ratiosHistogramBuilder = plotBuildersTask.getRatiosHistogramBuilder(); - PlotBuilder[] baselineHistogramBuilder = plotBuildersTask.getBaselineHistogramBuilder(); - PlotBuilder[] dalyFaradayHistogramBuilder = plotBuildersTask.getDalyFaradayGainHistogramBuilder(); - //PlotBuilder[] signalNoiseHistogramBuilder = plotBuildersTask.getSignalNoiseHistogramBuilder(); - PlotBuilder[] intensityLinePlotBuilder = plotBuildersTask.getMeanIntensityVsKnotsMultiLineBuilder(); PlotBuilder[] convergeRatioPlotBuilder = plotBuildersTask.getConvergeRatioLineBuilder(); PlotBuilder[] convergeBLFaradayLineBuilder = plotBuildersTask.getConvergeBLFaradayLineBuilder(); -// PlotBuilder[] convergeNoiseFaradayLineBuilder = plotBuildersTask.getConvergeNoiseFaradayLineBuilder(); + PlotBuilder[] convergeErrWeightedMisfitBuilder = plotBuildersTask.getConvergeErrWeightedMisfitLineBuilder(); PlotBuilder[] convergeErrRawMisfitBuilder = plotBuildersTask.getConvergeErrRawMisfitLineBuilder(); @@ -340,58 +383,124 @@ private synchronized void plotBlockEngine(Task plotBuildersTaska) { PlotBuilder[] observedDataWithSubsetsLineBuilder = plotBuildersTask.getObservedDataWithSubsetsLineBuilder(); - // plotting revision +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - PlotWallPane ensemblePlotsWallPane = PlotWallPane.createPlotWallPane(null); - ensemblePlotsWallPane.buildToolBar(); - ensemblePlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - ensemblePlotsAnchorPane.getChildren().add(ensemblePlotsWallPane); - produceTripoliRatioHistogramPlots(ratiosHistogramBuilder, ensemblePlotsWallPane); - produceTripoliHistogramPlots(baselineHistogramBuilder, ensemblePlotsWallPane); - produceTripoliHistogramPlots(dalyFaradayHistogramBuilder, ensemblePlotsWallPane); - //produceTripoliHistogramPlots(signalNoiseHistogramBuilder, ensemblePlotsWallPane); - produceTripoliMultiLinePlots(intensityLinePlotBuilder, ensemblePlotsWallPane); - ensemblePlotsWallPane.setPrefSize(ensemblePlotsAnchorPane.getPrefWidth(), ensemblePlotsAnchorPane.getPrefHeight()); - ensemblePlotsWallPane.tilePlots(); + // plotting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + plotTabPane.widthProperty().addListener((observable, oldValue, newValue) -> { + convergePlotsWallPane.repeatLayoutStyle(); + convergeErrorPlotsWallPane.repeatLayoutStyle(); + convergeIntensityPlotsWallPane.repeatLayoutStyle(); + ensemblePlotsWallPane.repeatLayoutStyle(); + dataFitPlotsWallPane.repeatLayoutStyle(); + }); + plotTabPane.heightProperty().addListener((observable, oldValue, newValue) -> { + convergePlotsWallPane.repeatLayoutStyle(); + convergeErrorPlotsWallPane.repeatLayoutStyle(); + convergeIntensityPlotsWallPane.repeatLayoutStyle(); + ensemblePlotsWallPane.repeatLayoutStyle(); + dataFitPlotsWallPane.repeatLayoutStyle(); + }); - PlotWallPane convergePlotsWallPane = PlotWallPane.createPlotWallPane(null); - convergePlotsWallPane.buildToolBar(); - convergePlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - convergePlotsAnchorPane.getChildren().add(convergePlotsWallPane); + + if (convergePlotsAnchorPane.getChildren().isEmpty()) { + convergePlotsWallPane = PlotWallPane.createPlotWallPane(PLOT_TAB_CONVERGE, analysis, this, null); + convergePlotsWallPane.buildToolBar(); + convergePlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); + convergePlotsWallPane.prefWidthProperty().bind(convergePlotsAnchorPane.widthProperty()); + convergePlotsWallPane.prefHeightProperty().bind(convergePlotsAnchorPane.heightProperty()); + convergePlotsAnchorPane.getChildren().add(convergePlotsWallPane); + } else { + convergePlotsWallPane = (PlotWallPane) convergePlotsAnchorPane.getChildren().get(0); + convergePlotsWallPane.clearTripoliPanes(); + } produceTripoliLinePlots(convergeRatioPlotBuilder, convergePlotsWallPane); produceTripoliLinePlots(convergeBLFaradayLineBuilder, convergePlotsWallPane); -// produceTripoliLinePlots(convergeNoiseFaradayLineBuilder, convergePlotsWallPane); convergePlotsWallPane.tilePlots(); - PlotWallPane dataFitPlotsWallPane = PlotWallPane.createPlotWallPane(null); - dataFitPlotsWallPane.buildToolBar(); - dataFitPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - dataFitPlotsAnchorPane.getChildren().add(dataFitPlotsWallPane); - produceTripoliBasicScatterAndLinePlots(observedDataPlotBuilder, dataFitPlotsWallPane); - produceTripoliBasicScatterAndLinePlots(observedDataWithSubsetsLineBuilder, dataFitPlotsWallPane); - produceTripoliBasicScatterAndLinePlots(residualDataPlotBuilder, dataFitPlotsWallPane); - dataFitPlotsWallPane.stackPlots(); - PlotWallPane convergeErrorPlotsWallPane = PlotWallPane.createPlotWallPane(null); - convergeErrorPlotsWallPane.buildToolBar(); - convergeErrorPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - convergeErrorPlotsAnchorPane.getChildren().add(convergeErrorPlotsWallPane); + if (convergeErrorPlotsAnchorPane.getChildren().isEmpty()) { + convergeErrorPlotsWallPane = PlotWallPane.createPlotWallPane(PLOT_TAB_CONVERGE, analysis, this, null); + convergeErrorPlotsWallPane.buildToolBar(); + convergeErrorPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); + convergeErrorPlotsWallPane.prefWidthProperty().bind(convergeErrorPlotsAnchorPane.widthProperty()); + convergeErrorPlotsWallPane.prefHeightProperty().bind(convergeErrorPlotsAnchorPane.heightProperty()); + convergeErrorPlotsAnchorPane.getChildren().add(convergeErrorPlotsWallPane); + } else { + convergeErrorPlotsWallPane = (PlotWallPane) convergeErrorPlotsAnchorPane.getChildren().get(0); + convergeErrorPlotsWallPane.clearTripoliPanes(); + } produceTripoliLinePlots(convergeErrRawMisfitBuilder, convergeErrorPlotsWallPane); produceTripoliLinePlots(convergeErrWeightedMisfitBuilder, convergeErrorPlotsWallPane); convergeErrorPlotsWallPane.tilePlots(); - PlotWallPane convergeIntensityPlotsWallPane = PlotWallPane.createPlotWallPane(null); - convergeIntensityPlotsWallPane.buildToolBar(); - convergeIntensityPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - convergeIntensityAnchorPane.getChildren().add(convergeIntensityPlotsWallPane); + + if (convergeIntensityAnchorPane.getChildren().isEmpty()) { + convergeIntensityPlotsWallPane = PlotWallPane.createPlotWallPane(PLOT_TAB_CONVERGE_INTENSITY, analysis, this, null); + convergeIntensityPlotsWallPane.buildToolBar(); + convergeIntensityPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); + convergeIntensityPlotsWallPane.prefWidthProperty().bind(convergeIntensityAnchorPane.widthProperty()); + convergeIntensityPlotsWallPane.prefHeightProperty().bind(convergeIntensityAnchorPane.heightProperty()); + convergeIntensityAnchorPane.getChildren().add(convergeIntensityPlotsWallPane); + } else { + convergeIntensityPlotsWallPane = (PlotWallPane) convergeIntensityAnchorPane.getChildren().get(0); + convergeIntensityPlotsWallPane.clearTripoliPanes(); + } produceTripoliMultiLineIntensityPlots(convergeIntensityLinesBuilder, convergeIntensityPlotsWallPane); convergeIntensityPlotsWallPane.tilePlots(); - PlotWallPane peakShapeOverlayPlotWallPane = PlotWallPane.createPlotWallPane(null); - peakShapeOverlayPlotWallPane.buildToolBar(); - peakShapeOverlayPlotWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); - beamShapeAnchorPane.getChildren().add(peakShapeOverlayPlotWallPane); - producePeakShapesOverlayPlot(peakShapeOverlayBuilder, peakShapeOverlayPlotWallPane); - peakShapeOverlayPlotWallPane.tilePlots(); + + plotEnsemblesEngine(((MCMCPlotBuildersTask) plotBuildersTask).getPlotBuilders()); + + + if (dataFitPlotsAnchorPane.getChildren().isEmpty()) { + dataFitPlotsWallPane = PlotWallPane.createPlotWallPane(null, analysis, this, null); + dataFitPlotsWallPane.buildToolBar(); + dataFitPlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); + dataFitPlotsWallPane.prefWidthProperty().bind(dataFitPlotsAnchorPane.widthProperty()); + dataFitPlotsWallPane.prefHeightProperty().bind(dataFitPlotsAnchorPane.heightProperty()); + dataFitPlotsAnchorPane.getChildren().add(dataFitPlotsWallPane); + } else { + dataFitPlotsWallPane = (PlotWallPane) dataFitPlotsAnchorPane.getChildren().get(0); + dataFitPlotsWallPane.clearTripoliPanes(); + } + produceTripoliBasicScatterAndLinePlots(observedDataPlotBuilder, dataFitPlotsWallPane); + produceTripoliBasicScatterAndLinePlots(observedDataWithSubsetsLineBuilder, dataFitPlotsWallPane); + produceTripoliBasicScatterAndLinePlots(residualDataPlotBuilder, dataFitPlotsWallPane); + dataFitPlotsWallPane.stackPlots(); + + +// PlotWallPane peakShapeOverlayPlotWallPane = PlotWallPane.createPlotWallPane(null, analysis, this, null); +// peakShapeOverlayPlotWallPane.buildToolBar(); +// peakShapeOverlayPlotWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); +// beamShapeAnchorPane.getChildren().add(peakShapeOverlayPlotWallPane); +// producePeakShapesOverlayPlot(peakShapeOverlayBuilder, peakShapeOverlayPlotWallPane); +// peakShapeOverlayPlotWallPane.tilePlots(); + } + + + public void plotEnsemblesEngine(PlotBuilder[][] plotBuilders) { + PlotBuilder[] ratiosHistogramBuilder = plotBuilders[PLOT_INDEX_RATIOS]; + PlotBuilder[] baselineHistogramBuilder = plotBuilders[PLOT_INDEX_BASELINES]; + PlotBuilder[] dalyFaradayHistogramBuilder = plotBuilders[PLOT_INDEX_DFGAINS]; + PlotBuilder[] intensityLinePlotBuilder = plotBuilders[PLOT_INDEX_MEANINTENSITIES]; + + if (ensemblePlotsAnchorPane.getChildren().isEmpty()) { + ensemblePlotsWallPane = PlotWallPane.createPlotWallPane(PLOT_TAB_ENSEMBLES, analysis, this, analysisManagerCallbackI); + ensemblePlotsWallPane.buildToolBar(); + ensemblePlotsWallPane.setBackground(new Background(new BackgroundFill(Paint.valueOf("LINEN"), null, null))); + ensemblePlotsWallPane.prefWidthProperty().bind(ensemblePlotsAnchorPane.widthProperty()); + ensemblePlotsWallPane.prefHeightProperty().bind(ensemblePlotsAnchorPane.heightProperty()); + ensemblePlotsAnchorPane.getChildren().add(ensemblePlotsWallPane); + } else { + ensemblePlotsWallPane = (PlotWallPane) ensemblePlotsAnchorPane.getChildren().get(0); + ensemblePlotsWallPane.clearTripoliPanes(); + } + produceTripoliRatioHistogramPlots(ratiosHistogramBuilder, ensemblePlotsWallPane); + produceTripoliHistogramPlots(baselineHistogramBuilder, ensemblePlotsWallPane); + produceTripoliHistogramPlots(dalyFaradayHistogramBuilder, ensemblePlotsWallPane); + produceTripoliMultiLinePlots(intensityLinePlotBuilder, ensemblePlotsWallPane); + ensemblePlotsWallPane.repeatLayoutStyle(); + + listViewOfBlocks.refresh(); } private synchronized void showLogsEngine(int blockNumber) { @@ -402,6 +511,7 @@ private synchronized void showLogsEngine(int blockNumber) { logAnchorPane.getChildren().add(logTextArea); } + private void produceTripoliRatioHistogramPlots(PlotBuilder[] plotBuilder, PlotWallPane plotWallPane) { for (int i = 0; i < plotBuilder.length; i++) { if (plotBuilder[i].isDisplayed()) { @@ -415,7 +525,8 @@ private void produceTripoliRatioHistogramPlots(PlotBuilder[] plotBuilder, PlotWa plotRecord, invertedPlotRecord, logRatioHistogramRecord, logInvertedRatioHistogramRecord, - analysis.getAnalysisMethod()); + analysis.getAnalysisMethod(), + plotWallPane); tripoliPlotPane.addPlot(plot); } } @@ -426,7 +537,7 @@ private void produceTripoliHistogramPlots(PlotBuilder[] plotBuilder, PlotWallPan if (plotBuilder[i].isDisplayed()) { HistogramRecord plotRecord = ((HistogramBuilder) plotBuilder[i]).getHistogramRecord(); TripoliPlotPane tripoliPlotPane = TripoliPlotPane.makePlotPane(plotWallPane); - AbstractPlot plot = HistogramSinglePlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), plotRecord); + AbstractPlot plot = HistogramSinglePlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), plotRecord, plotWallPane); tripoliPlotPane.addPlot(plot); } } @@ -435,7 +546,7 @@ private void produceTripoliHistogramPlots(PlotBuilder[] plotBuilder, PlotWallPan private void produceTripoliLinePlots(PlotBuilder[] plotBuilder, PlotWallPane plotWallPane) { for (int i = 0; i < plotBuilder.length; i++) { TripoliPlotPane tripoliPlotPane = TripoliPlotPane.makePlotPane(plotWallPane); - AbstractPlot plot = LinePlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), (LinePlotBuilder) plotBuilder[i]); + AbstractPlot plot = LinePlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), (LinePlotBuilder) plotBuilder[i], plotWallPane); tripoliPlotPane.addPlot(plot); } } @@ -451,7 +562,7 @@ private void produceTripoliMultiLinePlots(PlotBuilder[] plotBuilder, PlotWallPan private void produceTripoliMultiLineIntensityPlots(PlotBuilder[] plotBuilder, PlotWallPane plotWallPane) { for (int i = 0; i < plotBuilder.length; i++) { TripoliPlotPane tripoliPlotPane = TripoliPlotPane.makePlotPane(plotWallPane); - AbstractPlot plot = MultiLineIntensityPlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), (MultiLinePlotBuilder) plotBuilder[i]); + AbstractPlot plot = MultiLineIntensityPlot.generatePlot(new Rectangle(minPlotWidth, minPlotHeight), (MultiLinePlotBuilder) plotBuilder[i], plotWallPane); tripoliPlotPane.addPlot(plot); } } @@ -473,33 +584,47 @@ private void producePeakShapesOverlayPlot(PlotBuilder[] plotBuilder, PlotWallPan tripoliPlotPane.addPlot(plot); } } - } - public void viewSelectedBlockAction() { int blockIndex = listViewOfBlocks.getSelectionModel().getSelectedIndex(); viewSelectedBlock(blockIndex); } public void viewSelectedBlock(int blockIndex) { + currentBlockID = blockIndex + 1; Task mcmcPlotBuildersTask = ((MCMCUpdatesService) services[blockIndex]).getPlotBuilderTask(); if ((null != mcmcPlotBuildersTask) && mcmcPlotBuildersTask.isDone() && ((MCMCPlotBuildersTask) mcmcPlotBuildersTask).healthyPlotbuilder()) { plotBlockEngine(mcmcPlotBuildersTask); showLogsEngine(blockIndex); + listViewOfBlocks.refresh(); + } + } + + public void convergeTabSelected(Event event) { + Tab tab = (Tab) event.getSource(); + if (tab.isSelected() && !((AnchorPane) tab.getContent()).getChildren().isEmpty()) { + ((PlotWallPane) ((AnchorPane) tab.getContent()).getChildren().get(0)).restoreAllPlots(); } } static class BlockDisplayID extends ListCell { @Override - protected void updateItem(String blockID, boolean empty) { - super.updateItem(blockID, empty); - if (null == blockID || empty) { + protected void updateItem(String blockIDtext, boolean empty) { + super.updateItem(blockIDtext, empty); + if (null == blockIDtext || empty) { setText(null); } else { - setText(blockID); + int blockID = Integer.parseInt(blockIDtext); + if (((Analysis) analysis).getMapBlockIDToEnsembles().isEmpty()) { + setText("Block# " + blockID); + } else { + setText("Block# " + blockID + + " {BurnIn = " + ((Analysis) analysis).getMapOfBlockIdToModelsBurnCount().get(blockID) + + " of " + ((Analysis) analysis).getMapBlockIDToEnsembles().get(blockID).size() + " models}"); + } } } } diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsControllerInterface.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsControllerInterface.java new file mode 100644 index 00000000..13015343 --- /dev/null +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/mcmcPlots/MCMCPlotsControllerInterface.java @@ -0,0 +1,9 @@ +package org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.mcmcPlots; + +import org.cirdles.tripoli.plots.PlotBuilder; + +public interface MCMCPlotsControllerInterface { + public void plotEnsemblesEngine(PlotBuilder[][] plotBuilders); + + public void plotRatioSessionEngine(); +} \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/peakShapePlots/PeakShapeDemoPlotsControllerTest.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/peakShapePlots/PeakShapeDemoPlotsControllerTest.java index 4d26eebc..d6fdbc7d 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/peakShapePlots/PeakShapeDemoPlotsControllerTest.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/peakShapePlots/PeakShapeDemoPlotsControllerTest.java @@ -64,7 +64,7 @@ public class PeakShapeDemoPlotsControllerTest { AbstractPlot peakCentreLinePlot; - PlotWallPane ensemblePlotsWallPane = PlotWallPane.createPlotWallPane(null); + PlotWallPane ensemblePlotsWallPane = PlotWallPane.createPlotWallPane(null, null, null, null); @FXML private ScrollPane resourceListScrollPane; diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/HistogramSinglePlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/HistogramSinglePlot.java index b2e1ea97..1af31060 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/HistogramSinglePlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/HistogramSinglePlot.java @@ -21,6 +21,7 @@ import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; +import org.cirdles.tripoli.gui.dataViews.plots.PlotWallPane; import org.cirdles.tripoli.gui.dataViews.plots.TicGeneratorForAxes; import org.cirdles.tripoli.plots.histograms.HistogramRecord; @@ -31,8 +32,9 @@ public class HistogramSinglePlot extends AbstractPlot { protected HistogramRecord histogramRecord; protected double binWidth; + private PlotWallPane parentWallPane; - protected HistogramSinglePlot(Rectangle bounds, HistogramRecord histogramRecord) { + protected HistogramSinglePlot(Rectangle bounds, HistogramRecord histogramRecord, PlotWallPane parentWallPane) { super(bounds, 40, 25, new String[]{histogramRecord.title()[0] @@ -41,12 +43,17 @@ protected HistogramSinglePlot(Rectangle bounds, HistogramRecord histogramRecord) histogramRecord.xAxisLabel(), histogramRecord.yAxisLabel()); this.histogramRecord = histogramRecord; + this.parentWallPane = parentWallPane; // these can be changed by user in plot binWidth = histogramRecord.binWidth(); } - public static AbstractPlot generatePlot(Rectangle bounds, HistogramRecord histogramRecord) { - return new HistogramSinglePlot(bounds, histogramRecord); + public static AbstractPlot generatePlot(Rectangle bounds, HistogramRecord histogramRecord, PlotWallPane parentWallPane) { + return new HistogramSinglePlot(bounds, histogramRecord, parentWallPane); + } + + public PlotWallPane getParentWallPane() { + return parentWallPane; } @Override @@ -79,10 +86,7 @@ public void paint(GraphicsContext g2d) { } public void prepareExtents(boolean reScaleX, boolean reScaleY) { - double xMarginStretch = TicGeneratorForAxes.generateMarginAdjustment(minX, maxX, 0.05); - if (0.0 == xMarginStretch) { - xMarginStretch = maxX * 0.01; - } + double xMarginStretch = TicGeneratorForAxes.generateMarginAdjustment(minX, maxX, 0.0); minX -= xMarginStretch; maxX += xMarginStretch; diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/LinePlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/LinePlot.java index c1844738..b97c9e96 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/LinePlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/LinePlot.java @@ -1,34 +1,44 @@ package org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots; import javafx.scene.canvas.GraphicsContext; +import javafx.scene.paint.Color; +import javafx.scene.shape.ArcType; import javafx.scene.shape.Rectangle; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; +import org.cirdles.tripoli.gui.dataViews.plots.PlotWallPane; import org.cirdles.tripoli.gui.dataViews.plots.TicGeneratorForAxes; import org.cirdles.tripoli.plots.linePlots.LinePlotBuilder; +import static org.cirdles.tripoli.gui.constants.ConstantsTripoliApp.TRIPOLI_MOVING_SHADE; + public class LinePlot extends AbstractPlot { - private final LinePlotBuilder linePlotBuilder; + private PlotWallPane parentWallPane; - private LinePlot(Rectangle bounds, LinePlotBuilder linePlotBuilder) { + private LinePlot(Rectangle bounds, LinePlotBuilder plotBuilder, PlotWallPane parentWallPane) { super(bounds, 75, 25, - linePlotBuilder.getTitle(), - linePlotBuilder.getxAxisLabel(), - linePlotBuilder.getyAxisLabel()); - this.linePlotBuilder = linePlotBuilder; + plotBuilder.getTitle(), + plotBuilder.getxAxisLabel(), + plotBuilder.getyAxisLabel()); + this.plotBuilder = plotBuilder; + this.parentWallPane = parentWallPane; + } + + public static AbstractPlot generatePlot(Rectangle bounds, LinePlotBuilder linePlotBuilder, PlotWallPane parentWallPane) { + return new LinePlot(bounds, linePlotBuilder, parentWallPane); } - public static AbstractPlot generatePlot(Rectangle bounds, LinePlotBuilder linePlotBuilder) { - return new LinePlot(bounds, linePlotBuilder); + public PlotWallPane getParentWallPane() { + return parentWallPane; } @Override public void preparePanel(boolean reScaleX, boolean reScaleY) { - xAxisData = linePlotBuilder.getxData(); + xAxisData = ((LinePlotBuilder) plotBuilder).getxData(); minX = xAxisData[0]; maxX = xAxisData[xAxisData.length - 1]; - yAxisData = linePlotBuilder.getyData(); + yAxisData = ((LinePlotBuilder) plotBuilder).getyData(); minY = Double.MAX_VALUE; maxY = -Double.MAX_VALUE; @@ -65,7 +75,7 @@ public void prepareExtents(boolean reScaleX, boolean reScaleY) { @Override public void plotData(GraphicsContext g2d) { - g2d.setLineWidth(2.0); + g2d.setLineWidth(1.0); // new line plot g2d.setStroke(dataColor.color()); g2d.beginPath(); @@ -90,4 +100,13 @@ public void plotData(GraphicsContext g2d) { public void plotStats(GraphicsContext g2d) { } + + public void plotLeftShade(GraphicsContext g2d) { + g2d.setFill(TRIPOLI_MOVING_SHADE); + g2d.fillRect(mapX(0), mapY(maxY), mapX(plotBuilder.getShadeWidthForModelConvergence()) - mapX(0), mapY(minY) - mapY(maxY)); + + g2d.setFill(Color.RED); + g2d.fillArc(mapX(plotBuilder.getShadeWidthForModelConvergence()) - 40, (mapY(minY) - mapY(maxY)) / 2 + mapY(maxY) - 20, 40, 40, -75, 150, ArcType.CHORD); + } + } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/MultiLineIntensityPlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/MultiLineIntensityPlot.java index a92748d7..fc39427c 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/MultiLineIntensityPlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/MultiLineIntensityPlot.java @@ -2,44 +2,54 @@ import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; +import javafx.scene.shape.ArcType; import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; import javafx.scene.text.Text; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; +import org.cirdles.tripoli.gui.dataViews.plots.PlotWallPane; import org.cirdles.tripoli.gui.dataViews.plots.TicGeneratorForAxes; import org.cirdles.tripoli.plots.linePlots.MultiLinePlotBuilder; +import static org.cirdles.tripoli.gui.constants.ConstantsTripoliApp.TRIPOLI_MOVING_SHADE; + public class MultiLineIntensityPlot extends AbstractPlot { - private final MultiLinePlotBuilder multiLinePlotBuilder; private double[][] xData; private double[][] yData; + private PlotWallPane parentWallPane; + /** * @param bounds - * @param multiLinePlotBuilder + * @param plotBuilder */ - private MultiLineIntensityPlot(Rectangle bounds, MultiLinePlotBuilder multiLinePlotBuilder) { + private MultiLineIntensityPlot(Rectangle bounds, MultiLinePlotBuilder plotBuilder, PlotWallPane parentWallPane) { super(bounds, 75, 25, - multiLinePlotBuilder.getTitle(), - multiLinePlotBuilder.getxAxisLabel(), - multiLinePlotBuilder.getyAxisLabel()); - this.multiLinePlotBuilder = multiLinePlotBuilder; + plotBuilder.getTitle(), + plotBuilder.getxAxisLabel(), + plotBuilder.getyAxisLabel()); + this.plotBuilder = plotBuilder; + this.parentWallPane = parentWallPane; } - public static AbstractPlot generatePlot(Rectangle bounds, MultiLinePlotBuilder multiLinePlotBuilder) { - return new MultiLineIntensityPlot(bounds, multiLinePlotBuilder); + public static AbstractPlot generatePlot(Rectangle bounds, MultiLinePlotBuilder multiLinePlotBuilder, PlotWallPane parentWallPane) { + return new MultiLineIntensityPlot(bounds, multiLinePlotBuilder, parentWallPane); + } + + public PlotWallPane getParentWallPane() { + return parentWallPane; } @Override public void preparePanel(boolean reScaleX, boolean reScaleY) { - xData = multiLinePlotBuilder.getxData(); + xData = ((MultiLinePlotBuilder) plotBuilder).getxData(); xAxisData = xData[0]; minX = (xData[0][0]); maxX = (xData[0][xData[0].length - 1]); - yData = multiLinePlotBuilder.getyData(); + yData = ((MultiLinePlotBuilder) plotBuilder).getyData(); minY = Double.MAX_VALUE; maxY = -Double.MAX_VALUE; @@ -71,36 +81,6 @@ public void prepareExtents(boolean reScaleX, boolean reScaleY) { minY -= yMarginStretch; } -// @Override -// public void calculateTics() { -// // logarithmic ticsX -// List xTicsList = new ArrayList<>(); -// int limitLog = (int) xData[0][xData[0].length - 1]; -// for (int logIndex = 1; logIndex <= limitLog; logIndex = logIndex * 10) { -// xTicsList.add(Math.log(logIndex)); -// } -// ticsX = new BigDecimal[xTicsList.size()]; -// for (int i = 0; i < xTicsList.size(); i++) { -// ticsX[i] = new BigDecimal(Double.toString(xTicsList.get(i))); -// } -// -// if (0 == ticsX.length) { -// ticsX = new BigDecimal[2]; -// ticsX[0] = new BigDecimal(Double.toString(minX)); -// ticsX[ticsX.length - 1] = new BigDecimal(Double.toString(maxX)); -// } -// -// ticsY = TicGeneratorForAxes.generateTics(getDisplayMinY(), getDisplayMaxY(), (int) (plotHeight / 15.0)); -// if (0 == ticsY.length) { -// ticsY = new BigDecimal[2]; -// ticsY[0] = new BigDecimal(Double.toString(minY)); -// ticsY[ticsY.length - 1] = new BigDecimal(Double.toString(maxY)); -// } -// -// zoomChunkX = getDisplayRangeX() / 100.0; -// zoomChunkY = getDisplayRangeY() / 100.0; -// } - @Override public void paint(GraphicsContext g2d) { super.paint(g2d); @@ -144,57 +124,6 @@ public void plotData(GraphicsContext g2d) { } g2d.stroke(); } - -// if (1 < ticsY.length) { -// // border and fill -// g2d.setLineWidth(0.5); -// g2d.setStroke(Paint.valueOf("BLACK")); -// g2d.strokeRect( -// mapX(minX), -// mapY(ticsY[ticsY.length - 1].doubleValue()), -// graphWidth, -// StrictMath.abs(mapY(ticsY[ticsY.length - 1].doubleValue()) - mapY(ticsY[0].doubleValue()))); -// -// g2d.setFill(Paint.valueOf("BLACK")); -// -// // ticsY -// float verticalTextShift = 3.2f; -// g2d.setFont(Font.font("SansSerif", 10)); -// if (null != ticsY) { -// for (BigDecimal bigDecimal : ticsY) { -// g2d.strokeLine( -// mapX(minX), mapY(bigDecimal.doubleValue()), mapX(maxX), mapY(bigDecimal.doubleValue())); -// -// // left side -// text.setText(bigDecimal.toString()); -// textWidth = (int) text.getLayoutBounds().getWidth(); -// g2d.fillText(text.getText(),// -// (float) mapX(minX) - textWidth - 5.0f, -// (float) mapY(bigDecimal.doubleValue()) + verticalTextShift); -// -// } -// // ticsX -// if (null != ticsX) { -// for (BigDecimal bigDecimal : ticsX) { -// try { -// g2d.strokeLine( -// mapX(bigDecimal.doubleValue()), -// mapY(ticsY[0].doubleValue()), -// mapX(bigDecimal.doubleValue()), -// mapY(ticsY[0].doubleValue()) + 5); -// -// // bottom -// String xText = (new BigDecimal(Double.toString(Math.exp(bigDecimal.doubleValue())))).setScale(-1, RoundingMode.HALF_UP).toPlainString(); -// g2d.fillText(xText, -// (float) mapX(bigDecimal.doubleValue()) - 5.0f, -// (float) mapY(ticsY[0].doubleValue()) + 15); -// -// } catch (Exception ignored) { -// } -// } -// } -// } -// } } /** @@ -204,4 +133,12 @@ public void plotData(GraphicsContext g2d) { public void plotStats(GraphicsContext g2d) { } + + public void plotLeftShade(GraphicsContext g2d) { + g2d.setFill(TRIPOLI_MOVING_SHADE); + g2d.fillRect(mapX(0), mapY(maxY), mapX(plotBuilder.getShadeWidthForModelConvergence()) - mapX(0), mapY(minY) - mapY(maxY)); + + g2d.setFill(Color.RED); + g2d.fillArc(mapX(plotBuilder.getShadeWidthForModelConvergence()) - 40, (mapY(minY) - mapY(maxY)) / 2 + mapY(maxY) - 20, 40, 40, -75, 150, ArcType.CHORD); + } } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/RatioHistogramPlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/RatioHistogramPlot.java index aadf0b41..92ac2baa 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/RatioHistogramPlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/RatioHistogramPlot.java @@ -22,6 +22,7 @@ import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; +import org.cirdles.tripoli.gui.dataViews.plots.PlotWallPane; import org.cirdles.tripoli.gui.dataViews.plots.TicGeneratorForAxes; import org.cirdles.tripoli.plots.histograms.HistogramRecord; import org.cirdles.tripoli.sessions.analysis.methods.AnalysisMethod; @@ -44,8 +45,9 @@ private RatioHistogramPlot( HistogramRecord invertedRatioHistogramRecord, HistogramRecord logRatioHistogramRecord, HistogramRecord logInvertedRatioHistogramRecord, - AnalysisMethod analysisMethod) { - super(bounds, histogramRecord); + AnalysisMethod analysisMethod, + PlotWallPane parentWallPane) { + super(bounds, histogramRecord, parentWallPane); this.analysisMethod = analysisMethod; // these can be changed by user in plot @@ -65,8 +67,9 @@ public static AbstractPlot generatePlot( HistogramRecord invertedRatioHistogramRecord, HistogramRecord logRatioHistogramRecord, HistogramRecord logInvertedRatioHistogramRecord, - AnalysisMethod analysisMethod) { - return new RatioHistogramPlot(bounds, ratioHistogramRecord, invertedRatioHistogramRecord, logRatioHistogramRecord, logInvertedRatioHistogramRecord, analysisMethod); + AnalysisMethod analysisMethod, + PlotWallPane parentWallPane) { + return new RatioHistogramPlot(bounds, ratioHistogramRecord, invertedRatioHistogramRecord, logRatioHistogramRecord, logInvertedRatioHistogramRecord, analysisMethod, parentWallPane); } private void extendPlotContextMenu() { diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/BlockRatioCyclesSessionPlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/BlockRatioCyclesSessionPlot.java index cb7f3c03..a95a470d 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/BlockRatioCyclesSessionPlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/BlockRatioCyclesSessionPlot.java @@ -16,15 +16,15 @@ package org.cirdles.tripoli.gui.dataViews.plots.plotsControllers.tripoliPlots.sessionPlots; -import javafx.collections.ObservableList; import javafx.scene.canvas.GraphicsContext; +import javafx.scene.control.ContextMenu; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.cirdles.tripoli.gui.dataViews.plots.AbstractPlot; +import org.cirdles.tripoli.gui.dataViews.plots.PlotWallPane; import org.cirdles.tripoli.gui.dataViews.plots.TicGeneratorForAxes; -import org.cirdles.tripoli.gui.dataViews.plots.TripoliPlotPane; import org.cirdles.tripoli.plots.compoundPlots.BlockRatioCyclesRecord; import org.cirdles.tripoli.plots.sessionPlots.BlockRatioCyclesSessionRecord; @@ -38,6 +38,7 @@ */ public class BlockRatioCyclesSessionPlot extends AbstractPlot { + private final BlockRatioCyclesSessionRecord blockRatioCyclesSessionRecord; private Map mapBlockIdToBlockRatioCyclesRecord; private double[] oneSigmaForCycles; @@ -45,10 +46,11 @@ public class BlockRatioCyclesSessionPlot extends AbstractPlot { private double sessionOneSigma; private boolean logScale; private boolean[] zoomFlagsXY; + private PlotWallPane parentWallPane; - private BlockRatioCyclesSessionPlot(Rectangle bounds, BlockRatioCyclesSessionRecord blockRatioCyclesSessionRecord) { + private BlockRatioCyclesSessionPlot(Rectangle bounds, BlockRatioCyclesSessionRecord blockRatioCyclesSessionRecord, PlotWallPane parentWallPane) { super(bounds, - 100, 25, + 75, 25, new String[]{blockRatioCyclesSessionRecord.title()[0] + " " + "X\u0305" + "=" + String.format("%8.8g", blockRatioCyclesSessionRecord.sessionMean()).trim() , "\u00B1" + String.format("%8.5g", blockRatioCyclesSessionRecord.sessionOneSigma()).trim()}, @@ -57,10 +59,19 @@ private BlockRatioCyclesSessionPlot(Rectangle bounds, BlockRatioCyclesSessionRec this.blockRatioCyclesSessionRecord = blockRatioCyclesSessionRecord; this.logScale = false; this.zoomFlagsXY = new boolean[]{true, true}; + this.parentWallPane = parentWallPane; + } + + public static AbstractPlot generatePlot(Rectangle bounds, BlockRatioCyclesSessionRecord blockRatioCyclesSessionRecord, PlotWallPane parentWallPane) { + return new BlockRatioCyclesSessionPlot(bounds, blockRatioCyclesSessionRecord, parentWallPane); + } + + public BlockRatioCyclesSessionRecord getBlockRatioCyclesSessionRecord() { + return blockRatioCyclesSessionRecord; } - public static AbstractPlot generatePlot(Rectangle bounds, BlockRatioCyclesSessionRecord blockRatioCyclesSessionRecord) { - return new BlockRatioCyclesSessionPlot(bounds, blockRatioCyclesSessionRecord); + public PlotWallPane getParentWallPane() { + return parentWallPane; } public void setLogScale(boolean logScale) { @@ -248,27 +259,8 @@ public void calcStats() { , "\u00B1" + String.format("%8.5g", sessionOneSigma).trim()}; } - public void performPrimaryClick(double mouseX, double mouseY) { - // determine blockID - double xValue = convertMouseXToValue(mouseX); - int blockId = (int) ((xValue - 0.7) / blockRatioCyclesSessionRecord.cyclesPerBlock()) + 1; - if (null != mapBlockIdToBlockRatioCyclesRecord.get(blockId)) { -// mapBlockIdToBlockRatioCyclesRecord.put( -// blockId, -// mapBlockIdToBlockRatioCyclesRecord.get(blockId).toggleBlockIncluded()); -// repaint(); -// } - - ObservableList tripoliPlotPanes = this.getParent().getParent().getChildrenUnmodifiable(); - for (Object child : tripoliPlotPanes) { - if (child instanceof TripoliPlotPane) { - BlockRatioCyclesSessionPlot tripoliPlot = (BlockRatioCyclesSessionPlot) ((TripoliPlotPane) child).getChildren().get(0); - tripoliPlot.getMapBlockIdToBlockRatioCyclesRecord().put( - blockId, - mapBlockIdToBlockRatioCyclesRecord.get(blockId).toggleBlockIncluded()); - tripoliPlot.repaint(); - } - } - } + public void setupPlotContextMenu() { + // no menu for now + plotContextMenu = new ContextMenu(); } } \ No newline at end of file diff --git a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/HistogramSessionPlot.java b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/HistogramSessionPlot.java index 01b0d24d..fe7a1279 100644 --- a/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/HistogramSessionPlot.java +++ b/TripoliApp/src/main/java/org/cirdles/tripoli/gui/dataViews/plots/plotsControllers/tripoliPlots/sessionPlots/HistogramSessionPlot.java @@ -34,7 +34,7 @@ public class HistogramSessionPlot extends AbstractPlot { private HistogramSessionPlot(Rectangle bounds, HistogramSessionRecord histogramSessionRecord) { super(bounds, - 40, 25, + 75, 25, new String[]{histogramSessionRecord.title()[0] + " " + "X\u0305" + "=" + String.format("%8.5g", histogramSessionRecord.sessionMean()).trim() , "\u00B1" + String.format("%8.5g", histogramSessionRecord.sessionOneSigma()).trim()}, diff --git a/TripoliApp/src/main/resources/org/cirdles/tripoli/gui/AnalysesManager.fxml b/TripoliApp/src/main/resources/org/cirdles/tripoli/gui/AnalysesManager.fxml index ced3bd14..0cdaf0ae 100644 --- a/TripoliApp/src/main/resources/org/cirdles/tripoli/gui/AnalysesManager.fxml +++ b/TripoliApp/src/main/resources/org/cirdles/tripoli/gui/AnalysesManager.fxml @@ -89,7 +89,7 @@