From 7e4ee768d2ab3e69d3ff35555fbaab104120e98c Mon Sep 17 00:00:00 2001 From: Jamie Mac Date: Mon, 29 Jul 2024 16:04:46 +0100 Subject: [PATCH] Updates to the data map for JavaFX --- src/dataMap/layoutFX/DataMapScrollPane.java | 101 ++++++++ src/dataMap/layoutFX/DataStreamPaneFX.java | 4 + src/dataMap/layoutFX/ScrollingDataPaneFX.java | 226 +++++++++--------- .../acousticScroller/ScrollBarPane.java | 6 +- 4 files changed, 227 insertions(+), 110 deletions(-) create mode 100644 src/dataMap/layoutFX/DataMapScrollPane.java diff --git a/src/dataMap/layoutFX/DataMapScrollPane.java b/src/dataMap/layoutFX/DataMapScrollPane.java new file mode 100644 index 00000000..126a616d --- /dev/null +++ b/src/dataMap/layoutFX/DataMapScrollPane.java @@ -0,0 +1,101 @@ +package dataMap.layoutFX; + +import java.util.ArrayList; + +import PamController.OfflineDataStore; +import PamController.PamController; +import dataMap.DataMapControl; +import dataMap.OfflineDataMap; +import dataMap.OfflineDataMapPoint; +import javafx.scene.paint.Color; +import pamViewFX.fxNodes.pamScrollers.acousticScroller.ScrollBarPane; + +/** + * A scroll bar whihc shows a summary fo the data. + */ +public class DataMapScrollPane extends ScrollBarPane { + + private DataMapControl dataMapControl; + + public DataMapScrollPane(DataMapControl dataMapControl) { + super(); + this.dataMapControl=dataMapControl; + } + + /** + * Paint a summary of the data + */ + public void paintDataSummary() { + + ArrayList offlineDataStores = PamController.getInstance().findOfflineDataStores(); + OfflineDataStore aSource; + + Color color = Color.DODGERBLUE; + + this.getDrawCanvas().getGraphicsContext2D().setStroke(color); + this.getDrawCanvas().getGraphicsContext2D().setGlobalAlpha(0.3); + + for (int i = 0; i < offlineDataStores.size(); i++) { + aSource = offlineDataStores.get(i); + paintOfflineDataSource(aSource); + } + } + + /** + * Paint the data on the canvas. + * @param dataSource - the dta source. + */ + private void paintOfflineDataSource(OfflineDataStore dataSource) { + if (dataMapControl.getMappedDataBlocks()==null) return; + + OfflineDataMap aMap; + for (int i = 0; i < dataMapControl.getMappedDataBlocks().size(); i++) { + aMap = dataMapControl.getMappedDataBlocks().get(i).getOfflineDataMap(dataSource); + if (aMap == null) { + continue; + } + long lastTime; + OfflineDataMapPoint aPoint; + for (int j=0; j dataStreamPanels = new ArrayList(); - + /** * Split pane whihc holds different graphs. */ private PamVBox dataPanePanes; private ArrayList offlineDataStores; - + /** * Time stamp in millis of start of datamap display */ @@ -72,24 +72,24 @@ public class ScrollingDataPaneFX extends PamBorderPane { * Time stamp in millis of end of datamap display */ private long screenEndMillis = -1; - + private double screenSeconds; /** * Scroll bar for time (horizontal) */ - private ScrollBarPane timeScrollBar; + private DataMapScrollPane timeScrollBar; /** * Settings strip at top of the display. Shows all sorts of detailed info such cursor position and start and end times. */ private SettingsStripFX settingsStrip; - + /** * Shows the start time of the scroll position */ private Label scrollEndLabel; - + /** * Shows the end time of the scroll position. */ @@ -120,13 +120,13 @@ public class ScrollingDataPaneFX extends PamBorderPane { * @return the scrolling pane. */ private Node createScrollingDataPane() { - + holder=new PamBorderPane(); //create the main scroll pane mainScrollPane = new PamScrollPane(); - - + + //create the split pane to hold the graphs. dataPanePanes=new PamVBox(); //dataPanePanes.setOrientation(Orientation.VERTICAL); @@ -135,42 +135,42 @@ public class ScrollingDataPaneFX extends PamBorderPane { mainScrollPane.setContent(dataPanePanes); //we have a custom scroll bar for horizontal stuff. -// mainScrollPane.setHbarPolicy(ScrollBarPolicy.NEVER); - -// ///TEMP/// -// Button buttonTest=new Button("Test Map"); -// buttonTest.setOnAction((action)->{ -// this.dataMapControl.findDataSources(); -// }); -// holder.setTop(buttonTest); -// ////////// - - -// PamButton test = new PamButton("Test"); -// test.setOnAction((action)->{ -// updateScrollBar(); -// }); -// holder.setLeft(test); + // mainScrollPane.setHbarPolicy(ScrollBarPolicy.NEVER); + + // ///TEMP/// + // Button buttonTest=new Button("Test Map"); + // buttonTest.setOnAction((action)->{ + // this.dataMapControl.findDataSources(); + // }); + // holder.setTop(buttonTest); + // ////////// + + + // PamButton test = new PamButton("Test"); + // test.setOnAction((action)->{ + // updateScrollBar(); + // }); + // holder.setLeft(test); + - //finally make sure the scroll bar recalculates stuff when holder changes size holder.widthProperty().addListener((change)->{ notifyScrollChange(300); }); - - + + dateAxis = new PamDateAxis(); dateAxis.setAutoRanging(false); dateAxis.setLabel("Time"); dateAxis.setSide(Side.TOP); dateAxis.setAnimated(false); dateAxis.setMinHeight(50); -// dateAxis.prefWidthProperty().bind(scrollingDataPanel.widthProperty()); -// dateAxis.setStyle("-fx-background-color: ORANGE;"); + // dateAxis.prefWidthProperty().bind(scrollingDataPanel.widthProperty()); + // dateAxis.setStyle("-fx-background-color: ORANGE;"); dateAxis.setForceZeroInRange(false); - - + + PamVBox vBox = new PamVBox(); vBox.getChildren().add(createScrollBar()); vBox.getChildren().add(dateAxis); @@ -182,7 +182,7 @@ public class ScrollingDataPaneFX extends PamBorderPane { return holder; } - + /** * Updates the scrollbar. @@ -190,19 +190,19 @@ public class ScrollingDataPaneFX extends PamBorderPane { public void updateScrollBar() { setupScrollBar(); updateScrollBarText(); - + calcStartEndMillis(); updateScrollBarText(); notifyScrollChange(); } - + /** * Create the horizontal scroll bar for scrolling through time. * @return the horizontal scroll bar. */ private PamBorderPane createScrollBar(){ PamBorderPane holder=new PamBorderPane(); - + //create a pane to show start and end times PamBorderPane timeLabelPane=new PamBorderPane(); scrollStartLabel=new Label(); @@ -213,27 +213,27 @@ public class ScrollingDataPaneFX extends PamBorderPane { scrollEndLabel.setText(PamCalendar.formatDateTime(screenEndMillis)); timeLabelPane.setPadding(new Insets(2, 10, 2, 10)); //bit of padding to look better - + //create the scroll bar and listeners. - timeScrollBar=new ScrollBarPane(); + timeScrollBar=new DataMapScrollPane(this.dataMapControl); timeScrollBar.addValueListener((obs_val, old_val, new_val)->{ System.out.println("Scroll bar seconds: " + timeScrollBar.getCurrentValue() + " vis amount: " + timeScrollBar.visibleAmountProperty().get()); calcStartEndMillis(); updateScrollBarText(); notifyScrollChange(); }); - + timeScrollBar.getTextBox().setPrefColumnCount(15); timeScrollBar.getTextBox().setPrefWidth(100); timeScrollBar.setPrefHeight(50); - + holder.setCenter(timeScrollBar); holder.setBottom(timeLabelPane); - + return holder; } - + /** * Calculate the start and millis based on scroll position and screen seconds. */ @@ -241,10 +241,10 @@ public class ScrollingDataPaneFX extends PamBorderPane { screenStartMillis = (long) (dataMapControl.getFirstTime() + timeScrollBar.getCurrentValue()); screenEndMillis = (long) (screenStartMillis + timeScrollBar.getVisibleAmount()); - + getPixelsPerHour(); } - + /** * Update the text in the scroll bar. Shows the start and end time of the current screen. */ @@ -262,13 +262,13 @@ public class ScrollingDataPaneFX extends PamBorderPane { dataStreamPanels.get(i).scrollChanged(); } settingsStrip.scrollChanged(); - + updateDateAxis(); } - + Timeline timeline; long lastTime = 0; - + /** * Notify all panels and the settings strip that the scroll bar moved - but have a timer to wait to not call too often. */ @@ -286,11 +286,11 @@ public class ScrollingDataPaneFX extends PamBorderPane { timeline.play(); return; } - + lastTime=currentTime; - + updateDateAxis(); - + } private void updateDateAxis() { @@ -298,7 +298,7 @@ public class ScrollingDataPaneFX extends PamBorderPane { dateAxis.setUpperBound(screenEndMillis); dateAxis.setLowerBound(screenStartMillis); double[] ticks = dateAxis.recalculateTicks(); -// System.out.println("Ticks: " + (ticks[3]/1000/3600) + "hours"); + // System.out.println("Ticks: " + (ticks[3]/1000/3600) + "hours"); dateAxis.setTickUnit(ticks[3]); } @@ -307,30 +307,30 @@ public class ScrollingDataPaneFX extends PamBorderPane { * @return the number of DataStreamPanes created. */ public synchronized int createDataGraphs() { - //clear the panes from list and split pane. - dataStreamPanels.clear(); - dataPanePanes.getChildren().clear(); - - //now create new set of data stream panes. - ArrayList dataBlocks = dataMapControl.getMappedDataBlocks(); - if (dataBlocks == null) { - System.out.println("DataMapPaneFX:Create Data Graphs: Datablocks are null"); - return 0; - } - DataStreamPaneFX aStreamPanel; - for (int i = 0; i < dataBlocks.size(); i++) { - aStreamPanel = new DataStreamPaneFX(dataMapControl, this, dataBlocks.get(i)); - dataStreamPanels.add(aStreamPanel); - dataStreamPanels.get(i).setMinHeight(DATASTREAMPANE_HEIGHT); - //now add to a split pane. - //SplitPane.setResizableWithParent(aStreamPanel, true); - dataPanePanes.getChildren().add(aStreamPanel); - //dataPanePanes.setDividerPosition(0,1.0/dataBlocks.size()); - } + //clear the panes from list and split pane. + dataStreamPanels.clear(); + dataPanePanes.getChildren().clear(); - return dataBlocks.size(); + //now create new set of data stream panes. + ArrayList dataBlocks = dataMapControl.getMappedDataBlocks(); + if (dataBlocks == null) { + System.out.println("DataMapPaneFX:Create Data Graphs: Datablocks are null"); + return 0; + } + DataStreamPaneFX aStreamPanel; + for (int i = 0; i < dataBlocks.size(); i++) { + aStreamPanel = new DataStreamPaneFX(dataMapControl, this, dataBlocks.get(i)); + dataStreamPanels.add(aStreamPanel); + dataStreamPanels.get(i).setMinHeight(DATASTREAMPANE_HEIGHT); + //now add to a split pane. + //SplitPane.setResizableWithParent(aStreamPanel, true); + dataPanePanes.getChildren().add(aStreamPanel); + //dataPanePanes.setDividerPosition(0,1.0/dataBlocks.size()); + } + + return dataBlocks.size(); } - + /*** * Get the number of panes which are expanded. @@ -354,7 +354,7 @@ public class ScrollingDataPaneFX extends PamBorderPane { createDataGraphs(); setupScrollBar(); } - + private void setupScrollBar() { /** * Do scrolling in seconds - will give up to 68 years with a @@ -364,33 +364,41 @@ public class ScrollingDataPaneFX extends PamBorderPane { long dataStart = dataMapControl.getFirstTime(); long dataEnd = dataMapControl.getLastTime(); double dataSeconds = ((dataEnd-dataStart)/1000) + 1; - - + double pixsPerHour = getPixelsPerHour(); double pixsPerSecond = pixsPerHour / 3600; double screenWidth = getPlotWidth(); screenSeconds = screenWidth / Math.min(600. / 3600, pixsPerSecond); - -// if (dataStart == Long.MAX_VALUE || screenSeconds >= dataSeconds) { -// System.out.println("dataSeconds1: "+dataSeconds+ " pixsPerHour: " +pixsPerHour+" screenWidth: "+screenWidth+" screenSeconds "+screenSeconds+ " holder width: "+holder.getWidth()); -// /* -// * hide the scroll bar and stretch the display to fit the window -// */ -// timeScrollBar.setVisible(true); -// screenStartMillis = dataStart; -// screenEndMillis = dataEnd; -// } -// else { - System.out.println("dataSeconds2: "+dataSeconds+ " pixsPerHour: " +pixsPerHour+" screenWidth: "+screenWidth+" screenSeconds "+screenSeconds+" holder width: "+holder.getWidth()); - timeScrollBar.setVisible(true); - timeScrollBar.setMinVal(0); - timeScrollBar.setMaxVal(Math.max(dataSeconds, screenSeconds)*1000L); - timeScrollBar.setBlockIncrement(Math.max(1, screenSeconds * 4/5)); -// timeScrollBar.setUnitIncrement(Math.max(1, screenSeconds / 20)); - timeScrollBar.setVisibleAmount(screenSeconds*1000L); - timeScrollBar.setCurrentValue(currentPos); -// } + + + + // if (dataStart == Long.MAX_VALUE || screenSeconds >= dataSeconds) { + // System.out.println("dataSeconds1: "+dataSeconds+ " pixsPerHour: " +pixsPerHour+" screenWidth: "+screenWidth+" screenSeconds "+screenSeconds+ " holder width: "+holder.getWidth()); + // /* + // * hide the scroll bar and stretch the display to fit the window + // */ + // timeScrollBar.setVisible(true); + // screenStartMillis = dataStart; + // screenEndMillis = dataEnd; + // } + // else { + System.out.println("dataSeconds2: "+dataSeconds+ " pixsPerHour: " +pixsPerHour+" screenWidth: "+screenWidth+" screenSeconds "+screenSeconds+" holder width: "+holder.getWidth()); + timeScrollBar.setVisible(true); + timeScrollBar.setMinVal(0); + timeScrollBar.setMaxVal(Math.max(dataSeconds, screenSeconds)*1000L); + timeScrollBar.setBlockIncrement(Math.max(1, screenSeconds * 4/5)); + // timeScrollBar.setUnitIncrement(Math.max(1, screenSeconds / 20)); + timeScrollBar.setVisibleAmount(screenSeconds*1000L); + timeScrollBar.setCurrentValue(currentPos); + + //now paint the canvas to show the data. + try { + timeScrollBar.paintDataSummary(); + } + catch (Exception e) { + e.printStackTrace(); + } } @@ -401,11 +409,11 @@ public class ScrollingDataPaneFX extends PamBorderPane { private double getPlotWidth() { //HACK- seems like there is a lyout delay in datstream panes. return this.holder.getWidth()-DataStreamPaneFX.axisPrefWidth; -// if (dataStreamPanels.size()>0){ -// dataStreamPanels.get(0).layout(); -// return dataStreamPanels.get(0).getDataGraph().getPlotWidth(); -// } -// return 0; + // if (dataStreamPanels.size()>0){ + // dataStreamPanels.get(0).layout(); + // return dataStreamPanels.get(0).getDataGraph().getPlotWidth(); + // } + // return 0; } public void scrollToData(PamDataBlock dataBlock) { @@ -427,14 +435,14 @@ public class ScrollingDataPaneFX extends PamBorderPane { public long getScreenEndMillis() { return screenEndMillis; } - - + + public double getPixelsPerHour() { System.out.println("Pixels per hour: " + dataMapControl.dataMapParameters.getPixeslPerHour() + " " + this.getPlotWidth()/(this.timeScrollBar.getVisibleAmount()/1000./3600.)); //return dataMapControl.dataMapParameters.getPixeslPerHour(); - + return this.getPlotWidth()/(this.timeScrollBar.getVisibleAmount()/1000./3600.); - + } /** @@ -443,7 +451,7 @@ public class ScrollingDataPaneFX extends PamBorderPane { public double getScreenSeconds() { return screenSeconds; } - + /** * Get a colour for the datastream. * @param dataSource diff --git a/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java b/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java index 8e7ec484..f9196cb0 100644 --- a/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java +++ b/src/pamViewFX/fxNodes/pamScrollers/acousticScroller/ScrollBarPane.java @@ -312,6 +312,7 @@ public class ScrollBarPane extends PamBorderPane { rightDrag.getChildren().add(rightdragLine); rectangle.getChildren().add(rightDrag); + rectangle.setCursor(Cursor.OPEN_HAND); //Change cursor to hand //now set behaviours leftDrag.setOnMousePressed((event)->{ @@ -366,15 +367,17 @@ public class ScrollBarPane extends PamBorderPane { }); //now set behaviours - rightDrag.setOnMousePressed((event)->{ + rightDrag.setOnMousePressed((event)->{ leftLayoutX=rectangle.getLayoutX(); isChanging.set(true); + rectangle.setCursor(Cursor.CLOSED_HAND); //Change cursor to hand dragStarted(event, rightDrag); }); rightDrag.setOnMouseReleased((event)->{ currentValueProperty.setValue(calcScrollBarVal(rectangle.getLayoutX())); isChanging.set(false); + rectangle.setCursor(Cursor.OPEN_HAND); //Change cursor to hand dragging(event); }); @@ -426,6 +429,7 @@ public class ScrollBarPane extends PamBorderPane { rectangle.setOnMouseDragged((event)->{ rectangleDragged(event); }); + return rectangle; }