Commit f15a5890729eeb12d748b54d5809fc69dbd30a2c
1 parent
513c0341c5
Exists in
master
and in
1 other branch
add better chart
Showing 6 changed files with 173 additions and 119 deletions Inline Diff
build.gradle
View file @
f15a589
plugins { | 1 | 1 | plugins { | |
id 'java' | 2 | 2 | id 'java' | |
id 'org.jetbrains.kotlin.jvm' version '1.3.72' | 3 | 3 | id 'org.jetbrains.kotlin.jvm' version '1.3.72' | |
} | 4 | 4 | } | |
5 | 5 | |||
group 'marivisu' | 6 | 6 | group 'marivisu' | |
version '1.0-SNAPSHOT' | 7 | 7 | version '1.0-SNAPSHOT' | |
8 | 8 | |||
repositories { | 9 | 9 | repositories { | |
mavenCentral() | 10 | 10 | mavenCentral() | |
11 | maven { | |||
12 | url "https://jitpack.io" | |||
13 | } | |||
} | 11 | 14 | } | |
12 | 15 | |||
dependencies { | 13 | 16 | dependencies { | |
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | 14 | 17 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" | |
implementation 'org.jfxtras:jmetro:8.6.9' | 15 | 18 | implementation 'org.jfxtras:jmetro:8.6.9' | |
implementation 'org.slf4j:slf4j-api:1.7.30' | 16 | 19 | implementation 'org.slf4j:slf4j-api:1.7.30' | |
testCompile group: 'junit', name: 'junit', version: '4.12' | 17 | 20 | testCompile group: 'junit', name: 'junit', version: '4.12' | |
testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' | 18 | 21 | testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' | |
compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3' | 19 | 22 | compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3' | |
23 | compile 'com.github.jasrodis:javafx-dataviewer-wrapper:-SNAPSHOT' | |||
} | 20 | 24 | } | |
21 | 25 | |||
compileKotlin { | 22 | 26 | compileKotlin { | |
kotlinOptions.jvmTarget = "1.8" | 23 | 27 | kotlinOptions.jvmTarget = "1.8" |
src/main/kotlin/application/App.kt
View file @
f15a589
package application | 1 | 1 | package application | |
2 | 2 | |||
import javafx.application.Application | 3 | 3 | import javafx.application.Application | |
4 | import javafx.application.Platform | |||
5 | import javafx.event.EventHandler | |||
import javafx.fxml.FXMLLoader | 4 | 6 | import javafx.fxml.FXMLLoader | |
import javafx.scene.Parent | 5 | 7 | import javafx.scene.Parent | |
import javafx.scene.Scene | 6 | 8 | import javafx.scene.Scene | |
import javafx.stage.Stage | 7 | 9 | import javafx.stage.Stage | |
10 | import javafx.stage.WindowEvent | |||
import jfxtras.styles.jmetro.JMetro | 8 | 11 | import jfxtras.styles.jmetro.JMetro | |
import jfxtras.styles.jmetro.Style | 9 | 12 | import jfxtras.styles.jmetro.Style | |
13 | import kotlin.system.exitProcess | |||
10 | 14 | |||
class App : Application() { | 11 | 15 | class App : Application() { | |
var style : Style = Style.LIGHT | 12 | 16 | var style : Style = Style.LIGHT | |
13 | 17 | |||
override fun start(primaryStage: Stage?) { | 14 | 18 | override fun start(primaryStage: Stage?) { | |
15 | 19 | |||
val fxmlLoader = FXMLLoader(App::class.java.getResource("/gui/windows.fxml")) | 16 | 20 | val fxmlLoader = FXMLLoader(App::class.java.getResource("/gui/windows.fxml")) | |
val parent: Parent = fxmlLoader.load() | 17 | 21 | val parent: Parent = fxmlLoader.load() | |
val scene = Scene(parent) | 18 | 22 | val scene = Scene(parent) | |
JMetro(scene, style) | 19 | 23 | JMetro(scene, style) | |
primaryStage!!.scene = scene | 20 | 24 | primaryStage!!.scene = scene | |
primaryStage.title = "Maritime Visualisation" | 21 | 25 | primaryStage.title = "Maritime Visualisation" | |
26 | primaryStage.onCloseRequest = EventHandler { closeApplication() } | |||
primaryStage.show() | 22 | 27 | primaryStage.show() | |
28 | } | |||
29 | ||||
30 | private fun closeApplication() { | |||
31 | Platform.exit() | |||
32 | exitProcess(0) | |||
} | 23 | 33 | } | |
24 | 34 | |||
companion object { | 25 | 35 | companion object { | |
@JvmStatic | 26 | 36 | @JvmStatic |
src/main/kotlin/application/controller/DataPanelController.kt
View file @
f15a589
package application.controller | 1 | 1 | package application.controller | |
2 | 2 | |||
import application.model.* | 3 | 3 | import application.model.* | |
import javafx.collections.FXCollections | 4 | 4 | import javafx.collections.FXCollections | |
import javafx.collections.ObservableList | 5 | 5 | import javafx.collections.ObservableList | |
import javafx.fxml.FXML | 6 | 6 | import javafx.fxml.FXML | |
import javafx.fxml.Initializable | 7 | 7 | import javafx.fxml.Initializable | |
import javafx.scene.chart.CategoryAxis | 8 | |||
import javafx.scene.chart.NumberAxis | 9 | |||
import javafx.scene.chart.ScatterChart | 10 | |||
import javafx.scene.chart.XYChart.Data | 11 | |||
import javafx.scene.chart.XYChart.Series | 12 | |||
import javafx.scene.control.ListCell | 13 | 8 | import javafx.scene.control.ListCell | |
import javafx.scene.control.ListView | 14 | 9 | import javafx.scene.control.ListView | |
10 | import javafx.scene.layout.StackPane | |||
11 | import org.charts.dataviewer.api.config.DataViewerConfiguration | |||
12 | import org.charts.dataviewer.api.data.PlotData | |||
13 | import org.charts.dataviewer.api.trace.LineTrace | |||
14 | import org.charts.dataviewer.api.trace.ScatterTrace | |||
15 | import org.charts.dataviewer.javafx.JavaFxDataViewer | |||
16 | import org.charts.dataviewer.utils.TraceColour | |||
17 | import org.charts.dataviewer.utils.TraceMode | |||
18 | import org.charts.dataviewer.utils.TraceVisibility | |||
import java.net.URL | 15 | 19 | import java.net.URL | |
import java.util.* | 16 | 20 | import java.util.* | |
17 | 21 | |||
18 | 22 | |||
class DataPanelController : Initializable, SelectedVesselListener { | 19 | 23 | class DataPanelController : Initializable, SelectedVesselListener { | |
private var dataList: ObservableList<Pair<String, ArrayList<MessageData?>>> = FXCollections.observableArrayList() | 20 | 24 | private var dataList: ObservableList<Pair<String, ArrayList<MessageData?>>> = FXCollections.observableArrayList() | |
private lateinit var timeData: ArrayList<MessageData?> | 21 | 25 | private lateinit var timeData: ArrayList<MessageData?> | |
22 | 26 | |||
27 | ||||
@FXML | 23 | 28 | @FXML | |
var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>() | 24 | 29 | var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>() | |
25 | 30 | |||
@FXML | 26 | 31 | // @FXML | |
var xaxisNumber: CategoryAxis = CategoryAxis() | 27 | 32 | // var stackPanePlot = StackPane() | |
28 | 33 | |||
@FXML | 29 | 34 | @FXML | |
var yaxisNumber: NumberAxis = NumberAxis() | 30 | 35 | var dataViewer = JavaFxDataViewer() | |
31 | 36 | |||
@FXML | 32 | 37 | // @FXML | |
lateinit var scatterChartNumber: ScatterChart<String, Number> | 33 | 38 | // var xaxisNumber: CategoryAxis = CategoryAxis() | |
39 | // | |||
40 | // @FXML | |||
41 | // var yaxisNumber: NumberAxis = NumberAxis() | |||
42 | // | |||
43 | // @FXML | |||
44 | // lateinit var scatterChartNumber: ScatterChart<String, Number> | |||
45 | // | |||
46 | // @FXML | |||
47 | // var xaxisCategory: CategoryAxis = CategoryAxis() | |||
48 | // | |||
49 | // @FXML | |||
50 | // var yaxisCategory: CategoryAxis = CategoryAxis() | |||
51 | // | |||
52 | // @FXML | |||
53 | // lateinit var scatterChartCategory: ScatterChart<String, String> | |||
34 | 54 | |||
@FXML | 35 | |||
var xaxisCategory: CategoryAxis = CategoryAxis() | 36 | |||
37 | ||||
@FXML | 38 | |||
var yaxisCategory: CategoryAxis = CategoryAxis() | 39 | |||
40 | ||||
@FXML | 41 | |||
lateinit var scatterChartCategory: ScatterChart<String, String> | 42 | |||
43 | ||||
override fun initialize(location: URL?, resources: ResourceBundle?) { | 44 | 55 | override fun initialize(location: URL?, resources: ResourceBundle?) { | |
xaxisNumber.animated = false | 45 | 56 | // xaxisNumber.animated = false | |
yaxisNumber.animated = false | 46 | 57 | // yaxisNumber.animated = false | |
xaxisCategory.animated = false | 47 | 58 | // xaxisCategory.animated = false | |
yaxisCategory.animated = false | 48 | 59 | // yaxisCategory.animated = false | |
setObservableSelectedVesselListener() | 49 | 60 | setObservableSelectedVesselListener() | |
dataListView.items = dataList | 50 | 61 | dataListView.items = dataList | |
51 | 62 | |||
52 | 63 | |||
64 | val plotData = PlotData() | |||
65 | plotData.addTrace(createScatterTrace()) | |||
66 | val config = DataViewerConfiguration() | |||
67 | config.showLegend(true) | |||
68 | config.setLegendInsidePlot(false) | |||
53 | 69 | |||
dataListView.setCellFactory { | 54 | 70 | dataListView.setCellFactory { | |
object : ListCell<Pair<String, ArrayList<MessageData?>>?>() { | 55 | 71 | object : ListCell<Pair<String, ArrayList<MessageData?>>?>() { | |
override fun updateItem(item: Pair<String, ArrayList<MessageData?>>?, empty: Boolean) { | 56 | 72 | override fun updateItem(item: Pair<String, ArrayList<MessageData?>>?, empty: Boolean) { | |
super.updateItem(item, empty) | 57 | 73 | super.updateItem(item, empty) | |
text = if (empty) { | 58 | 74 | text = if (empty) { | |
null | 59 | 75 | null | |
} else { | 60 | 76 | } else { | |
item?.first | 61 | 77 | item?.first | |
} | 62 | 78 | } | |
} | 63 | 79 | } | |
} | 64 | 80 | } | |
} | 65 | 81 | } | |
66 | 82 | |||
dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> | 67 | 83 | dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> | |
if (newValue == null){ | 68 | 84 | if (newValue == null) { | |
scatterChartCategory.data.clear() | 69 | 85 | plotData.allTraces.clear() | |
scatterChartNumber.data.clear() | 70 | 86 | config.setxAxisTitle("") | |
87 | config.setyAxisTitle("") | |||
88 | dataViewer.resetPlot() | |||
89 | ||||
return@addListener | 71 | 90 | return@addListener | |
} | 72 | 91 | } | |
val serieNumber = Series<String, Number>() | 73 | |||
val serieString = Series<String, String>() | 74 | |||
75 | 92 | |||
val getValueVisitorX = GetValueVisitor() | 76 | 93 | val getValueVisitorX = GetValueVisitor() | |
val getValueVisitorY = GetValueVisitor() | 77 | 94 | val getValueVisitorY = GetValueVisitor() | |
78 | 95 | |||
96 | val arrayListStringX = arrayListOf<String>() | |||
97 | val arrayListDoubleX = arrayListOf<Double>() | |||
98 | val arrayListStringY = arrayListOf<String>() | |||
99 | val arrayListDoubleY = arrayListOf<Double>() | |||
79 | 100 | |||
for (x in 0 until newValue?.second?.size!!) { | 80 | 101 | for (x in 0 until newValue.second.size) { | |
timeData[x]?.accept(getValueVisitorX) | 81 | 102 | timeData[x]?.accept(getValueVisitorX) | |
newValue.second[x]?.accept(getValueVisitorY) | 82 | 103 | newValue.second[x]?.accept(getValueVisitorY) | |
83 | 104 | |||
if (getValueVisitorY.value.toDoubleOrNull() == null){ | 84 | 105 | if (getValueVisitorY.value.toDoubleOrNull() == null) { | |
serieString.data.add(Data<String, String>(getValueVisitorX.value, getValueVisitorY.value)) | 85 | 106 | arrayListStringX.add(getValueVisitorX.value) | |
} else{ | 86 | 107 | arrayListStringY.add(getValueVisitorY.value) | |
serieNumber.data.add(Data<String, Number>(getValueVisitorX.value, getValueVisitorY.value.toDouble())) | 87 | 108 | } else { | |
109 | arrayListStringX.add(getValueVisitorX.value) | |||
110 | arrayListDoubleY.add(getValueVisitorY.value.toDouble()) | |||
} | 88 | 111 | } | |
89 | ||||
} | 90 | 112 | } | |
91 | 113 | |||
scatterChartNumber.data.clear() | 92 | 114 | val scatterTrace = ScatterTrace<Any>() | |
scatterChartCategory.data.clear() | 93 | 115 | scatterTrace.traceColour = TraceColour.RED | |
116 | scatterTrace.traceVisibility = TraceVisibility.TRUE | |||
94 | 117 | |||
if (getValueVisitorY.value.toDoubleOrNull() == null){ | 95 | 118 | val serieStringX: Array<String> = arrayListStringX.toTypedArray() | |
serieString.data.add(Data<String, String>(getValueVisitorX.value, getValueVisitorY.value)) | 96 | 119 | // val serieDoubleX: Array<Double> = arrayListDoubleX.toTypedArray() | |
scatterChartCategory.data.addAll(serieString) | 97 | 120 | val serieStringY: Array<String> = arrayListStringY.toTypedArray() | |
setChartCategoryVisible() | 98 | 121 | val serieDoubleY: Array<Double> = arrayListDoubleY.toTypedArray() | |
xaxisCategory.label = "Date" | 99 | 122 | ||
yaxisCategory.label = newValue.first | 100 | 123 | if (getValueVisitorY.value.toDoubleOrNull() == null) { | |
} else{ | 101 | 124 | scatterTrace.setxArray(serieStringX) | |
serieNumber.data.add(Data<String, Number>(getValueVisitorX.value, getValueVisitorY.value.toDouble())) | 102 | 125 | scatterTrace.setyArray(serieStringY) | |
scatterChartNumber.data.addAll(serieNumber) | 103 | 126 | } else { | |
setChartNumberVisible() | 104 | 127 | scatterTrace.setxArray(serieStringX) | |
xaxisNumber.label = "Date" | 105 | 128 | scatterTrace.setyArray(serieDoubleY) | |
yaxisNumber.label = newValue.first | 106 | |||
} | 107 | 129 | } | |
108 | 130 | |||
131 | config.setxAxisTitle("Date") | |||
132 | config.setyAxisTitle(newValue.first) | |||
133 | dataViewer.resetPlot() | |||
134 | plotData.allTraces.clear() | |||
135 | plotData.addTrace(scatterTrace) | |||
136 | dataViewer.updateConfiguration(config) | |||
137 | dataViewer.updatePlot(plotData) | |||
138 | ||||
} | 109 | 139 | } | |
110 | 140 | |||
141 | plotData.allTraces.clear() | |||
142 | // plotData.addTrace(createScatterTrace()) | |||
143 | config.setxAxisTitle("") | |||
144 | config.setyAxisTitle("") | |||
145 | config.plotTitle = "No data selected" | |||
146 | dataViewer.updateConfiguration(config) | |||
147 | dataViewer.updatePlot(plotData) | |||
148 | ||||
149 | // stackPanePlot.children.add(dataViewer) | |||
150 | ||||
} | 111 | 151 | } | |
112 | 152 | |||
private fun setChartCategoryVisible(){ | 113 | 153 | private fun createScatterTrace(): ScatterTrace<*>? { | |
scatterChartCategory.isVisible = true | 114 | 154 | val scatterTrace = ScatterTrace<Any>() | |
scatterChartNumber.isVisible = false | 115 | 155 | scatterTrace.setxArray(arrayOf("asdf", "fdsa", "asdfffe", "asdfe", "asfee3")) | |
156 | scatterTrace.setyArray(arrayOf("pppp", "koojoi", "pp", "ii", "rty", "ert")) | |||
157 | scatterTrace.traceName = "MyScatterTrace" | |||
158 | scatterTrace.traceColour = TraceColour.PURPLE | |||
159 | scatterTrace.traceMode = TraceMode.MARKERS | |||
160 | return scatterTrace | |||
} | 116 | 161 | } | |
117 | 162 | |||
private fun setChartNumberVisible(){ | 118 | 163 | fun createLineTrace(): LineTrace<*>? { | |
scatterChartCategory.isVisible = false | 119 | 164 | val lineTrace = LineTrace<Any>() | |
scatterChartNumber.isVisible = true | 120 | 165 | lineTrace.setxArray(arrayOf("asdf", "fdsa", "asdfffe", "asdfe", "asfee3")) | |
166 | lineTrace.setyArray(arrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0)) | |||
167 | lineTrace.traceName = "MyLineTrace" | |||
168 | lineTrace.traceColour = TraceColour.PURPLE | |||
169 | return lineTrace | |||
} | 121 | 170 | } | |
122 | 171 | |||
172 | // private fun setChartCategoryVisible() { | |||
173 | // scatterChartCategory.isVisible = true | |||
174 | // scatterChartNumber.isVisible = false | |||
175 | // } | |||
176 | // | |||
177 | // private fun setChartNumberVisible() { | |||
178 | // scatterChartCategory.isVisible = false | |||
179 | // scatterChartNumber.isVisible = true | |||
180 | // } | |||
181 | ||||
private fun setObservableSelectedVesselListener() { | 123 | 182 | private fun setObservableSelectedVesselListener() { | |
observableSelectedVessel.listeners.add(this) | 124 | 183 | observableSelectedVessel.listeners.add(this) | |
} | 125 | 184 | } | |
126 | 185 | |||
private fun populateTime(vessel: Vessel): ArrayList<MessageData?> { | 127 | 186 | private fun populateTime(vessel: Vessel): ArrayList<MessageData?> { | |
val allTime: ArrayList<MessageData?> = vessel.getAllTime() | 128 | 187 | val allTime: ArrayList<MessageData?> = vessel.getAllTime() | |
allTime.sortBy { (it as Time).value } | 129 | 188 | allTime.sortBy { (it as Time).value } | |
130 | 189 | |||
return allTime | 131 | 190 | return allTime | |
} | 132 | 191 | } | |
133 | 192 | |||
private fun populateLatitude(vessel: Vessel): ArrayList<MessageData?> { | 134 | 193 | private fun populateLatitude(vessel: Vessel): ArrayList<MessageData?> { | |
val allLatitude: ArrayList<MessageData?> = vessel.getAllLatitude() | 135 | 194 | val allLatitude: ArrayList<MessageData?> = vessel.getAllLatitude() | |
allLatitude.sortBy { (it as Latitude).value } | 136 | 195 | allLatitude.sortBy { (it as Latitude).value } | |
137 | 196 | |||
return allLatitude | 138 | 197 | return allLatitude | |
} | 139 | 198 | } | |
140 | 199 | |||
private fun populateLongitude(vessel: Vessel): ArrayList<MessageData?> { | 141 | 200 | private fun populateLongitude(vessel: Vessel): ArrayList<MessageData?> { | |
val allLongitude: ArrayList<MessageData?> = vessel.getAllLongitude() | 142 | 201 | val allLongitude: ArrayList<MessageData?> = vessel.getAllLongitude() | |
allLongitude.sortBy { (it as Longitude).value } | 143 | 202 | allLongitude.sortBy { (it as Longitude).value } | |
144 | 203 | |||
return allLongitude | 145 | 204 | return allLongitude | |
} | 146 | 205 | } | |
147 | 206 | |||
private fun populateSpeedOverGround(vessel: Vessel): ArrayList<MessageData?> { | 148 | 207 | private fun populateSpeedOverGround(vessel: Vessel): ArrayList<MessageData?> { | |
val allSpeedOverGround: ArrayList<MessageData?> = vessel.getAllSpeedOverGround() | 149 | 208 | val allSpeedOverGround: ArrayList<MessageData?> = vessel.getAllSpeedOverGround() | |
allSpeedOverGround.sortBy { (it as SpeedOverGround).value } | 150 | 209 | allSpeedOverGround.sortBy { (it as SpeedOverGround).value } | |
151 | 210 | |||
return allSpeedOverGround | 152 | 211 | return allSpeedOverGround | |
} | 153 | 212 | } | |
154 | 213 | |||
private fun populateCourseOverGround(vessel: Vessel): ArrayList<MessageData?> { | 155 | 214 | private fun populateCourseOverGround(vessel: Vessel): ArrayList<MessageData?> { | |
val allCourseOverGround: ArrayList<MessageData?> = vessel.getAllCourseOverGround() | 156 | 215 | val allCourseOverGround: ArrayList<MessageData?> = vessel.getAllCourseOverGround() | |
allCourseOverGround.sortBy { (it as CourseOverGround).value } | 157 | 216 | allCourseOverGround.sortBy { (it as CourseOverGround).value } | |
158 | 217 | |||
return allCourseOverGround | 159 | 218 | return allCourseOverGround | |
} | 160 | 219 | } | |
161 | 220 | |||
private fun populateHeading(vessel: Vessel): ArrayList<MessageData?> { | 162 | 221 | private fun populateHeading(vessel: Vessel): ArrayList<MessageData?> { | |
val allHeading: ArrayList<MessageData?> = vessel.getAllHeading() | 163 | 222 | val allHeading: ArrayList<MessageData?> = vessel.getAllHeading() | |
allHeading.sortBy { (it as Heading).value } | 164 | 223 | allHeading.sortBy { (it as Heading).value } | |
165 | 224 | |||
return allHeading | 166 | 225 | return allHeading | |
} | 167 | 226 | } | |
168 | 227 | |||
private fun populatVesselName(vessel: Vessel): ArrayList<MessageData?> { | 169 | 228 | private fun populateVesselName(vessel: Vessel): ArrayList<MessageData?> { | |
val allVesselName: ArrayList<MessageData?> = vessel.getAllVesselName() | 170 | 229 | val allVesselName: ArrayList<MessageData?> = vessel.getAllVesselName() | |
allVesselName.sortBy { (it as VesselName).value } | 171 | 230 | allVesselName.sortBy { (it as VesselName).value } | |
172 | 231 | |||
return allVesselName | 173 | 232 | return allVesselName | |
} | 174 | 233 | } | |
175 | 234 | |||
private fun populatIMO(vessel: Vessel): ArrayList<MessageData?> { | 176 | 235 | private fun populateIMO(vessel: Vessel): ArrayList<MessageData?> { | |
val allIMO: ArrayList<MessageData?> = vessel.getAllIMO() | 177 | 236 | val allIMO: ArrayList<MessageData?> = vessel.getAllIMO() | |
allIMO.sortBy { (it as IMO).value } | 178 | 237 | allIMO.sortBy { (it as IMO).value } | |
179 | 238 | |||
return allIMO | 180 | 239 | return allIMO | |
} | 181 | 240 | } | |
182 | 241 | |||
private fun populatCallSign(vessel: Vessel): ArrayList<MessageData?> { | 183 | 242 | private fun populateCallSign(vessel: Vessel): ArrayList<MessageData?> { | |
val allCallSign: ArrayList<MessageData?> = vessel.getAllCallSign() | 184 | 243 | val allCallSign: ArrayList<MessageData?> = vessel.getAllCallSign() | |
allCallSign.sortBy { (it as CallSign).value } | 185 | 244 | allCallSign.sortBy { (it as CallSign).value } | |
186 | 245 | |||
return allCallSign | 187 | 246 | return allCallSign | |
} | 188 | 247 | } | |
189 | 248 | |||
private fun populatVesselType(vessel: Vessel): ArrayList<MessageData?> { | 190 | 249 | private fun populateVesselType(vessel: Vessel): ArrayList<MessageData?> { | |
val allVesselType: ArrayList<MessageData?> = vessel.getAllVesselType() | 191 | 250 | val allVesselType: ArrayList<MessageData?> = vessel.getAllVesselType() | |
allVesselType.sortBy { (it as VesselType).value } | 192 | 251 | allVesselType.sortBy { (it as VesselType).value } | |
193 | 252 | |||
return allVesselType | 194 | 253 | return allVesselType | |
} | 195 | 254 | } | |
196 | 255 | |||
private fun populatStatus(vessel: Vessel): ArrayList<MessageData?> { | 197 | 256 | private fun populateStatus(vessel: Vessel): ArrayList<MessageData?> { | |
val allStatus: ArrayList<MessageData?> = vessel.getAllStatus() | 198 | 257 | val allStatus: ArrayList<MessageData?> = vessel.getAllStatus() | |
allStatus.sortBy { (it as Status).value } | 199 | 258 | allStatus.sortBy { (it as Status).value } | |
200 | 259 | |||
return allStatus | 201 | 260 | return allStatus | |
} | 202 | 261 | } | |
203 | 262 | |||
private fun populatLength(vessel: Vessel): ArrayList<MessageData?> { | 204 | 263 | private fun populateLength(vessel: Vessel): ArrayList<MessageData?> { | |
val allLength: ArrayList<MessageData?> = vessel.getAllLength() | 205 | 264 | val allLength: ArrayList<MessageData?> = vessel.getAllLength() | |
allLength.sortBy { (it as Length).value } | 206 | 265 | allLength.sortBy { (it as Length).value } | |
207 | 266 | |||
return allLength | 208 | 267 | return allLength | |
} | 209 | 268 | } | |
210 | 269 | |||
private fun populatWidth(vessel: Vessel): ArrayList<MessageData?> { | 211 | 270 | private fun populateWidth(vessel: Vessel): ArrayList<MessageData?> { | |
val allWidth: ArrayList<MessageData?> = vessel.getAllWidth() | 212 | 271 | val allWidth: ArrayList<MessageData?> = vessel.getAllWidth() | |
allWidth.sortBy { (it as Width).value } | 213 | 272 | allWidth.sortBy { (it as Width).value } | |
214 | 273 | |||
return allWidth | 215 | 274 | return allWidth | |
} | 216 | 275 | } | |
217 | 276 | |||
private fun populatDraft(vessel: Vessel): ArrayList<MessageData?> { | 218 | 277 | private fun populateDraft(vessel: Vessel): ArrayList<MessageData?> { | |
val allDraft: ArrayList<MessageData?> = vessel.getAllDraft() | 219 | 278 | val allDraft: ArrayList<MessageData?> = vessel.getAllDraft() | |
allDraft.sortBy { (it as Draft).value } | 220 | 279 | allDraft.sortBy { (it as Draft).value } | |
221 | 280 | |||
return allDraft | 222 | 281 | return allDraft | |
} | 223 | 282 | } | |
224 | 283 | |||
private fun populatCargo(vessel: Vessel): ArrayList<MessageData?> { | 225 | 284 | private fun populateCargo(vessel: Vessel): ArrayList<MessageData?> { | |
val allCargo: ArrayList<MessageData?> = vessel.getAllCargo() | 226 | 285 | val allCargo: ArrayList<MessageData?> = vessel.getAllCargo() | |
allCargo.sortBy { (it as Cargo).value } | 227 | 286 | allCargo.sortBy { (it as Cargo).value } | |
228 | 287 | |||
return allCargo | 229 | 288 | return allCargo | |
} | 230 | 289 | } | |
231 | 290 | |||
private fun populateDataList(vessel: Vessel) { | 232 | 291 | private fun populateDataList(vessel: Vessel) { | |
val data = arrayListOf<Pair<String, ArrayList<MessageData?>>>() | 233 | 292 | val data = arrayListOf<Pair<String, ArrayList<MessageData?>>>() | |
234 | 293 | |||
timeData = populateTime(vessel) | 235 | 294 | timeData = populateTime(vessel) | |
236 | 295 | |||
data.add(Pair("Latitude", populateLatitude(vessel))) | 237 | 296 | data.add(Pair("Latitude", populateLatitude(vessel))) | |
238 | 297 | |||
data.add(Pair("Longitude", populateLongitude(vessel))) | 239 | 298 | data.add(Pair("Longitude", populateLongitude(vessel))) | |
240 | 299 | |||
data.add(Pair("Speed Over Ground", populateSpeedOverGround(vessel))) | 241 | 300 | data.add(Pair("Speed Over Ground", populateSpeedOverGround(vessel))) | |
242 | 301 | |||
data.add(Pair("Course Over Ground", populateCourseOverGround(vessel))) | 243 | 302 | data.add(Pair("Course Over Ground", populateCourseOverGround(vessel))) | |
244 | 303 | |||
data.add(Pair("Heading", populateHeading(vessel))) | 245 | 304 | data.add(Pair("Heading", populateHeading(vessel))) | |
246 | 305 | |||
data.add(Pair("Vessel Name", populatVesselName(vessel))) | 247 | 306 | data.add(Pair("Vessel Name", populateVesselName(vessel))) | |
248 | 307 | |||
data.add(Pair("IMO", populatIMO(vessel))) | 249 | 308 | data.add(Pair("IMO", populateIMO(vessel))) | |
250 | 309 | |||
data.add(Pair("Call Sign", populatCallSign(vessel))) | 251 | 310 | data.add(Pair("Call Sign", populateCallSign(vessel))) |
src/main/kotlin/application/model/Message.kt
View file @
f15a589
package application.model | 1 | 1 | package application.model | |
2 | 2 | |||
import java.time.LocalDateTime | 3 | 3 | import java.time.LocalDateTime | |
4 | 4 | |||
class Message(split: List<String>) { | 5 | 5 | class Message(split: List<String>) { | |
val mmsi = MMSI(split[0].toIntOrNull()) | 6 | 6 | val mmsi = MMSI(split[0].toIntOrNull()) | |
val time = Time(LocalDateTime.parse(split[1])) | 7 | 7 | val time = Time(LocalDateTime.parse(split[1])) | |
val latitude = Latitude(split[2].toDoubleOrNull()) | 8 | 8 | val latitude = Latitude(split[2].toDoubleOrNull()) | |
val longitude = Longitude(split[3].toDoubleOrNull()) | 9 | 9 | val longitude = Longitude(split[3].toDoubleOrNull()) | |
val speedOverGround = SpeedOverGround(split[4].toDoubleOrNull()) | 10 | 10 | val speedOverGround = SpeedOverGround(split[4].toDoubleOrNull()) | |
val courseOverGround = CourseOverGround(split[5].toDoubleOrNull()) | 11 | 11 | val courseOverGround = CourseOverGround(split[5].toDoubleOrNull()) | |
val heading = Heading(split[6].toDoubleOrNull()) | 12 | 12 | val heading = Heading(split[6].toDoubleOrNull()) | |
val vesselName = VesselName(split[7]) | 13 | 13 | val vesselName = VesselName(if (split[7] == "") null else split[7]) | |
val imo = IMO(split[8]) | 14 | 14 | val imo = IMO(if (split[8] == "") null else split[8]) | |
val callSign = CallSign(split[9]) | 15 | 15 | val callSign = CallSign(if (split[9] == "") null else split[9]) | |
val vesselType = VesselType(split[10].toIntOrNull()) | 16 | 16 | val vesselType = VesselType(split[10].toIntOrNull()) | |
val status = Status(split[11]) | 17 | 17 | val status = Status(if (split[11] == "") null else split[11]) | |
val length = Length(split[12].toDoubleOrNull()) | 18 | 18 | val length = Length(split[12].toDoubleOrNull()) | |
val width = Width(split[13].toDoubleOrNull()) | 19 | 19 | val width = Width(split[13].toDoubleOrNull()) | |
val draft = Draft(split[14].toDoubleOrNull()) | 20 | 20 | val draft = Draft(split[14].toDoubleOrNull()) | |
val cargo = Cargo(split[15].toIntOrNull()) | 21 | 21 | val cargo = Cargo(split[15].toIntOrNull()) | |
22 | 22 | |||
23 | 23 | |||
fun getHexColorStroke(): String { | 24 | 24 | fun getHexColorStroke(): String { | |
var hex = Integer.toHexString(this.mmsi.value!!) | 25 | 25 | var hex = Integer.toHexString(this.mmsi.value!!) | |
if (hex.length > 6) { | 26 | 26 | if (hex.length > 6) { | |
hex = hex.substring(hex.length - 6) | 27 | 27 | hex = hex.substring(hex.length - 6) | |
} | 28 | 28 | } | |
return hex | 29 | 29 | return hex | |
} | 30 | 30 | } | |
} | 31 | 31 | } |
src/main/resources/gui/dataPanel.fxml
View file @
f15a589
<?xml version="1.0" encoding="UTF-8"?> | 1 | 1 | <?xml version="1.0" encoding="UTF-8"?> | |
2 | 2 | |||
<?import javafx.scene.chart.*?> | 3 | 3 | <?import javafx.scene.control.ListView?> | |
<?import javafx.scene.control.*?> | 4 | 4 | <?import javafx.scene.control.SplitPane?> | |
<?import javafx.scene.layout.*?> | 5 | 5 | <?import javafx.scene.layout.*?> | |
6 | 6 | <?import org.charts.dataviewer.javafx.JavaFxDataViewer?> | ||
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.DataPanelController"> | 7 | 7 | <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.241" | |
<SplitPane dividerPositions="0.1705685618729097" prefHeight="212.0" prefWidth="254.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> | 8 | 8 | xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.DataPanelController"> | |
<ListView fx:id="dataListView" layoutX="-73.0" layoutY="14.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> | 9 | 9 | <SplitPane dividerPositions="0.1705685618729097" prefHeight="212.0" prefWidth="254.0" AnchorPane.bottomAnchor="0.0" | |
<StackPane prefHeight="150.0" prefWidth="200.0"> | 10 | 10 | AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> | |
<ScatterChart fx:id="scatterChartNumber"> | 11 | 11 | <ListView fx:id="dataListView" layoutX="-73.0" layoutY="14.0" prefHeight="200.0" prefWidth="200.0" | |
<xAxis> | 12 | 12 | AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" | |
<CategoryAxis side="BOTTOM" fx:id="xaxisNumber" /> | 13 | 13 | AnchorPane.topAnchor="0.0"/> | |
</xAxis> | 14 | 14 | <JavaFxDataViewer fx:id="dataViewer"/> | |
<yAxis> | 15 | |||
<NumberAxis fx:id="yaxisNumber" side="LEFT" /> | 16 | |||
</yAxis> | 17 | |||
</ScatterChart> | 18 | |||
<ScatterChart fx:id="scatterChartCategory" visible="false"> | 19 | |||
<xAxis> | 20 | |||
<CategoryAxis side="BOTTOM" fx:id="xaxisCategory" /> | 21 | |||
</xAxis> | 22 | |||
<yAxis> | 23 | |||
<CategoryAxis fx:id="yaxisCategory" side="LEFT" /> | 24 | |||
</yAxis> | 25 | |||
</ScatterChart> | 26 | |||
</StackPane> | 27 | |||
</SplitPane> | 28 | 15 | </SplitPane> | |
</AnchorPane> | 29 | 16 | </AnchorPane> | |
30 | 17 | |||
src/main/resources/gui/windows.fxml
View file @
f15a589
<?xml version="1.0" encoding="UTF-8"?> | 1 | 1 | <?xml version="1.0" encoding="UTF-8"?> | |
2 | 2 | |||
<?import javafx.scene.control.SplitPane?> | 3 | 3 | <?import javafx.scene.control.*?> | |
<?import javafx.scene.layout.*?> | 4 | 4 | <?import javafx.scene.layout.*?> | |
<?import javafx.scene.shape.Line?> | 5 | 5 | <?import javafx.scene.shape.*?> | |
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" | 6 | 6 | ||
prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1"> | 7 | 7 | <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"> | |
<children> | 8 | 8 | <children> | |
<fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" | 9 | 9 | <fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> | |
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/> | 10 | 10 | <SplitPane dividerPositions="0.13772954924874792" layoutY="39.0" prefHeight="865.0" prefWidth="1194.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0"> | |
<SplitPane dividerPositions="0.13772954924874792" layoutY="39.0" prefHeight="865.0" prefWidth="1194.0" | 11 | |||
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" | 12 | |||
AnchorPane.topAnchor="35.0"> | 13 | |||
<items> | 14 | 11 | <items> | |
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | 15 | 12 | <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | |
<children> | 16 | 13 | <children> | |
<fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0" | 17 | 14 | <fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> | |
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/> | 18 | |||
</children> | 19 | 15 | </children> | |
</AnchorPane> | 20 | 16 | </AnchorPane> | |
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | 21 | 17 | <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> | |
<children> | 22 | 18 | <children> | |
<SplitPane dividerPositions="0.536" layoutX="127.0" layoutY="74.0" orientation="VERTICAL" | 23 | 19 | <SplitPane dividerPositions="0.536" layoutX="127.0" layoutY="74.0" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> | |
prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" | 24 | |||
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> | 25 | |||
<items> | 26 | 20 | <items> | |
<fx:include source="mapPanel.fxml"/> | 27 | 21 | <fx:include source="mapPanel.fxml" /> | |
<fx:include source="dataPanel.fxml"/> | 28 | 22 | <fx:include source="dataPanel.fxml" /> | |
</items> | 29 | 23 | </items> | |
</SplitPane> | 30 | 24 | </SplitPane> | |
</children> | 31 | 25 | </children> | |
</AnchorPane> | 32 | 26 | </AnchorPane> | |
</items> | 33 | 27 | </items> | |
</SplitPane> | 34 | 28 | </SplitPane> | |
<Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0"/> | 35 | 29 | <Line endX="3000.0" layoutX="101.0" layoutY="35.0" startX="-100.0" AnchorPane.leftAnchor="-3.0" AnchorPane.rightAnchor="0.0" /> | |
</children> | 36 | 30 | </children> | |
</AnchorPane> | 37 | 31 | </AnchorPane> | |
38 | 32 | |||