From f15a5890729eeb12d748b54d5809fc69dbd30a2c Mon Sep 17 00:00:00 2001 From: lsagona Date: Fri, 21 Aug 2020 14:01:30 +0200 Subject: [PATCH] add better chart --- build.gradle | 4 + src/main/kotlin/application/App.kt | 10 + .../application/controller/DataPanelController.kt | 207 +++++++++++++------- src/main/kotlin/application/model/Message.kt | 8 +- src/main/resources/gui/dataPanel.fxml | 35 ++-- src/main/resources/gui/windows.fxml | 28 ++- 6 files changed, 173 insertions(+), 119 deletions(-) diff --git a/build.gradle b/build.gradle index a3b9534..d05fa30 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,9 @@ version '1.0-SNAPSHOT' repositories { mavenCentral() + maven { + url "https://jitpack.io" + } } dependencies { @@ -17,6 +20,7 @@ dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3' + compile 'com.github.jasrodis:javafx-dataviewer-wrapper:-SNAPSHOT' } compileKotlin { diff --git a/src/main/kotlin/application/App.kt b/src/main/kotlin/application/App.kt index 8dfb14d..c38bd1c 100644 --- a/src/main/kotlin/application/App.kt +++ b/src/main/kotlin/application/App.kt @@ -1,12 +1,16 @@ package application import javafx.application.Application +import javafx.application.Platform +import javafx.event.EventHandler import javafx.fxml.FXMLLoader import javafx.scene.Parent import javafx.scene.Scene import javafx.stage.Stage +import javafx.stage.WindowEvent import jfxtras.styles.jmetro.JMetro import jfxtras.styles.jmetro.Style +import kotlin.system.exitProcess class App : Application() { var style : Style = Style.LIGHT @@ -19,9 +23,15 @@ class App : Application() { JMetro(scene, style) primaryStage!!.scene = scene primaryStage.title = "Maritime Visualisation" + primaryStage.onCloseRequest = EventHandler { closeApplication() } primaryStage.show() } + private fun closeApplication() { + Platform.exit() + exitProcess(0) + } + companion object { @JvmStatic fun main(args: Array) { diff --git a/src/main/kotlin/application/controller/DataPanelController.kt b/src/main/kotlin/application/controller/DataPanelController.kt index de69ab5..c844171 100644 --- a/src/main/kotlin/application/controller/DataPanelController.kt +++ b/src/main/kotlin/application/controller/DataPanelController.kt @@ -5,13 +5,17 @@ import javafx.collections.FXCollections import javafx.collections.ObservableList import javafx.fxml.FXML import javafx.fxml.Initializable -import javafx.scene.chart.CategoryAxis -import javafx.scene.chart.NumberAxis -import javafx.scene.chart.ScatterChart -import javafx.scene.chart.XYChart.Data -import javafx.scene.chart.XYChart.Series import javafx.scene.control.ListCell import javafx.scene.control.ListView +import javafx.scene.layout.StackPane +import org.charts.dataviewer.api.config.DataViewerConfiguration +import org.charts.dataviewer.api.data.PlotData +import org.charts.dataviewer.api.trace.LineTrace +import org.charts.dataviewer.api.trace.ScatterTrace +import org.charts.dataviewer.javafx.JavaFxDataViewer +import org.charts.dataviewer.utils.TraceColour +import org.charts.dataviewer.utils.TraceMode +import org.charts.dataviewer.utils.TraceVisibility import java.net.URL import java.util.* @@ -20,36 +24,48 @@ class DataPanelController : Initializable, SelectedVesselListener { private var dataList: ObservableList>> = FXCollections.observableArrayList() private lateinit var timeData: ArrayList - @FXML - var dataListView = ListView>>() - - @FXML - var xaxisNumber: CategoryAxis = CategoryAxis() - - @FXML - var yaxisNumber: NumberAxis = NumberAxis() - - @FXML - lateinit var scatterChartNumber: ScatterChart @FXML - var xaxisCategory: CategoryAxis = CategoryAxis() + var dataListView = ListView>>() - @FXML - var yaxisCategory: CategoryAxis = CategoryAxis() +// @FXML +// var stackPanePlot = StackPane() @FXML - lateinit var scatterChartCategory: ScatterChart + var dataViewer = JavaFxDataViewer() + +// @FXML +// var xaxisNumber: CategoryAxis = CategoryAxis() +// +// @FXML +// var yaxisNumber: NumberAxis = NumberAxis() +// +// @FXML +// lateinit var scatterChartNumber: ScatterChart +// +// @FXML +// var xaxisCategory: CategoryAxis = CategoryAxis() +// +// @FXML +// var yaxisCategory: CategoryAxis = CategoryAxis() +// +// @FXML +// lateinit var scatterChartCategory: ScatterChart override fun initialize(location: URL?, resources: ResourceBundle?) { - xaxisNumber.animated = false - yaxisNumber.animated = false - xaxisCategory.animated = false - yaxisCategory.animated = false +// xaxisNumber.animated = false +// yaxisNumber.animated = false +// xaxisCategory.animated = false +// yaxisCategory.animated = false setObservableSelectedVesselListener() dataListView.items = dataList + val plotData = PlotData() + plotData.addTrace(createScatterTrace()) + val config = DataViewerConfiguration() + config.showLegend(true) + config.setLegendInsidePlot(false) dataListView.setCellFactory { object : ListCell>?>() { @@ -65,61 +81,104 @@ class DataPanelController : Initializable, SelectedVesselListener { } dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> - if (newValue == null){ - scatterChartCategory.data.clear() - scatterChartNumber.data.clear() + if (newValue == null) { + plotData.allTraces.clear() + config.setxAxisTitle("") + config.setyAxisTitle("") + dataViewer.resetPlot() + return@addListener } - val serieNumber = Series() - val serieString = Series() val getValueVisitorX = GetValueVisitor() val getValueVisitorY = GetValueVisitor() + val arrayListStringX = arrayListOf() + val arrayListDoubleX = arrayListOf() + val arrayListStringY = arrayListOf() + val arrayListDoubleY = arrayListOf() - for (x in 0 until newValue?.second?.size!!) { + for (x in 0 until newValue.second.size) { timeData[x]?.accept(getValueVisitorX) newValue.second[x]?.accept(getValueVisitorY) - if (getValueVisitorY.value.toDoubleOrNull() == null){ - serieString.data.add(Data(getValueVisitorX.value, getValueVisitorY.value)) - } else{ - serieNumber.data.add(Data(getValueVisitorX.value, getValueVisitorY.value.toDouble())) + if (getValueVisitorY.value.toDoubleOrNull() == null) { + arrayListStringX.add(getValueVisitorX.value) + arrayListStringY.add(getValueVisitorY.value) + } else { + arrayListStringX.add(getValueVisitorX.value) + arrayListDoubleY.add(getValueVisitorY.value.toDouble()) } - } - scatterChartNumber.data.clear() - scatterChartCategory.data.clear() - - if (getValueVisitorY.value.toDoubleOrNull() == null){ - serieString.data.add(Data(getValueVisitorX.value, getValueVisitorY.value)) - scatterChartCategory.data.addAll(serieString) - setChartCategoryVisible() - xaxisCategory.label = "Date" - yaxisCategory.label = newValue.first - } else{ - serieNumber.data.add(Data(getValueVisitorX.value, getValueVisitorY.value.toDouble())) - scatterChartNumber.data.addAll(serieNumber) - setChartNumberVisible() - xaxisNumber.label = "Date" - yaxisNumber.label = newValue.first + val scatterTrace = ScatterTrace() + scatterTrace.traceColour = TraceColour.RED + scatterTrace.traceVisibility = TraceVisibility.TRUE + + val serieStringX: Array = arrayListStringX.toTypedArray() +// val serieDoubleX: Array = arrayListDoubleX.toTypedArray() + val serieStringY: Array = arrayListStringY.toTypedArray() + val serieDoubleY: Array = arrayListDoubleY.toTypedArray() + + if (getValueVisitorY.value.toDoubleOrNull() == null) { + scatterTrace.setxArray(serieStringX) + scatterTrace.setyArray(serieStringY) + } else { + scatterTrace.setxArray(serieStringX) + scatterTrace.setyArray(serieDoubleY) } + config.setxAxisTitle("Date") + config.setyAxisTitle(newValue.first) + dataViewer.resetPlot() + plotData.allTraces.clear() + plotData.addTrace(scatterTrace) + dataViewer.updateConfiguration(config) + dataViewer.updatePlot(plotData) + } + plotData.allTraces.clear() +// plotData.addTrace(createScatterTrace()) + config.setxAxisTitle("") + config.setyAxisTitle("") + config.plotTitle = "No data selected" + dataViewer.updateConfiguration(config) + dataViewer.updatePlot(plotData) + +// stackPanePlot.children.add(dataViewer) + } - private fun setChartCategoryVisible(){ - scatterChartCategory.isVisible = true - scatterChartNumber.isVisible = false + private fun createScatterTrace(): ScatterTrace<*>? { + val scatterTrace = ScatterTrace() + scatterTrace.setxArray(arrayOf("asdf", "fdsa", "asdfffe", "asdfe", "asfee3")) + scatterTrace.setyArray(arrayOf("pppp", "koojoi", "pp", "ii", "rty", "ert")) + scatterTrace.traceName = "MyScatterTrace" + scatterTrace.traceColour = TraceColour.PURPLE + scatterTrace.traceMode = TraceMode.MARKERS + return scatterTrace } - private fun setChartNumberVisible(){ - scatterChartCategory.isVisible = false - scatterChartNumber.isVisible = true + fun createLineTrace(): LineTrace<*>? { + val lineTrace = LineTrace() + lineTrace.setxArray(arrayOf("asdf", "fdsa", "asdfffe", "asdfe", "asfee3")) + lineTrace.setyArray(arrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0)) + lineTrace.traceName = "MyLineTrace" + lineTrace.traceColour = TraceColour.PURPLE + return lineTrace } +// private fun setChartCategoryVisible() { +// scatterChartCategory.isVisible = true +// scatterChartNumber.isVisible = false +// } +// +// private fun setChartNumberVisible() { +// scatterChartCategory.isVisible = false +// scatterChartNumber.isVisible = true +// } + private fun setObservableSelectedVesselListener() { observableSelectedVessel.listeners.add(this) } @@ -166,63 +225,63 @@ class DataPanelController : Initializable, SelectedVesselListener { return allHeading } - private fun populatVesselName(vessel: Vessel): ArrayList { + private fun populateVesselName(vessel: Vessel): ArrayList { val allVesselName: ArrayList = vessel.getAllVesselName() allVesselName.sortBy { (it as VesselName).value } return allVesselName } - private fun populatIMO(vessel: Vessel): ArrayList { + private fun populateIMO(vessel: Vessel): ArrayList { val allIMO: ArrayList = vessel.getAllIMO() allIMO.sortBy { (it as IMO).value } return allIMO } - private fun populatCallSign(vessel: Vessel): ArrayList { + private fun populateCallSign(vessel: Vessel): ArrayList { val allCallSign: ArrayList = vessel.getAllCallSign() allCallSign.sortBy { (it as CallSign).value } return allCallSign } - private fun populatVesselType(vessel: Vessel): ArrayList { + private fun populateVesselType(vessel: Vessel): ArrayList { val allVesselType: ArrayList = vessel.getAllVesselType() allVesselType.sortBy { (it as VesselType).value } return allVesselType } - private fun populatStatus(vessel: Vessel): ArrayList { + private fun populateStatus(vessel: Vessel): ArrayList { val allStatus: ArrayList = vessel.getAllStatus() allStatus.sortBy { (it as Status).value } return allStatus } - private fun populatLength(vessel: Vessel): ArrayList { + private fun populateLength(vessel: Vessel): ArrayList { val allLength: ArrayList = vessel.getAllLength() allLength.sortBy { (it as Length).value } return allLength } - private fun populatWidth(vessel: Vessel): ArrayList { + private fun populateWidth(vessel: Vessel): ArrayList { val allWidth: ArrayList = vessel.getAllWidth() allWidth.sortBy { (it as Width).value } return allWidth } - private fun populatDraft(vessel: Vessel): ArrayList { + private fun populateDraft(vessel: Vessel): ArrayList { val allDraft: ArrayList = vessel.getAllDraft() allDraft.sortBy { (it as Draft).value } return allDraft } - private fun populatCargo(vessel: Vessel): ArrayList { + private fun populateCargo(vessel: Vessel): ArrayList { val allCargo: ArrayList = vessel.getAllCargo() allCargo.sortBy { (it as Cargo).value } @@ -244,23 +303,23 @@ class DataPanelController : Initializable, SelectedVesselListener { data.add(Pair("Heading", populateHeading(vessel))) - data.add(Pair("Vessel Name", populatVesselName(vessel))) + data.add(Pair("Vessel Name", populateVesselName(vessel))) - data.add(Pair("IMO", populatIMO(vessel))) + data.add(Pair("IMO", populateIMO(vessel))) - data.add(Pair("Call Sign", populatCallSign(vessel))) + data.add(Pair("Call Sign", populateCallSign(vessel))) - data.add(Pair("Vessel Type", populatVesselType(vessel))) + data.add(Pair("Vessel Type", populateVesselType(vessel))) - data.add(Pair("Status", populatStatus(vessel))) + data.add(Pair("Status", populateStatus(vessel))) - data.add(Pair("Length", populatLength(vessel))) + data.add(Pair("Length", populateLength(vessel))) - data.add(Pair("Width", populatWidth(vessel))) + data.add(Pair("Width", populateWidth(vessel))) - data.add(Pair("Draft", populatDraft(vessel))) + data.add(Pair("Draft", populateDraft(vessel))) - data.add(Pair("Cargo", populatCargo(vessel))) + data.add(Pair("Cargo", populateCargo(vessel))) dataList.addAll(data) } diff --git a/src/main/kotlin/application/model/Message.kt b/src/main/kotlin/application/model/Message.kt index 8bb3bec..d3ce810 100644 --- a/src/main/kotlin/application/model/Message.kt +++ b/src/main/kotlin/application/model/Message.kt @@ -10,11 +10,11 @@ class Message(split: List) { val speedOverGround = SpeedOverGround(split[4].toDoubleOrNull()) val courseOverGround = CourseOverGround(split[5].toDoubleOrNull()) val heading = Heading(split[6].toDoubleOrNull()) - val vesselName = VesselName(split[7]) - val imo = IMO(split[8]) - val callSign = CallSign(split[9]) + val vesselName = VesselName(if (split[7] == "") null else split[7]) + val imo = IMO(if (split[8] == "") null else split[8]) + val callSign = CallSign(if (split[9] == "") null else split[9]) val vesselType = VesselType(split[10].toIntOrNull()) - val status = Status(split[11]) + val status = Status(if (split[11] == "") null else split[11]) val length = Length(split[12].toDoubleOrNull()) val width = Width(split[13].toDoubleOrNull()) val draft = Draft(split[14].toDoubleOrNull()) diff --git a/src/main/resources/gui/dataPanel.fxml b/src/main/resources/gui/dataPanel.fxml index c49b85d..6619887 100644 --- a/src/main/resources/gui/dataPanel.fxml +++ b/src/main/resources/gui/dataPanel.fxml @@ -1,29 +1,16 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/main/resources/gui/windows.fxml b/src/main/resources/gui/windows.fxml index d105195..f10236b 100644 --- a/src/main/resources/gui/windows.fxml +++ b/src/main/resources/gui/windows.fxml @@ -1,37 +1,31 @@ - + - - + + + - - + + - + - + - - + + - + -- 1.7.10.4