ADD: added small details view on click on an entity
This commit is contained in:
5317
webapp/package-lock.json
generated
5317
webapp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -7,12 +7,14 @@
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"react": "^18.2.0",
|
||||
"react-container-dimensions": "^1.4.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-scripts": "^5.0.1",
|
||||
"react-use-websocket": "^4.3.1",
|
||||
"sass": "^1.66.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
"web-vitals": "^2.1.4",
|
||||
"websocket": "^1.0.34"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
||||
@@ -1,66 +1,74 @@
|
||||
// App.js
|
||||
import React, { Component } from "react";
|
||||
import "./App.css";
|
||||
import { connect, sendMsg } from "./components/api/index";
|
||||
// import { connect, sendMsg } from "./components/api/index";
|
||||
import Header from './components/Header';
|
||||
import Controls from "./components/control/controls";
|
||||
// import ChatHistory from "./components/ChatHistory/ChatHistory.jsx";
|
||||
|
||||
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
|
||||
const client = new W3CWebSocket("ws://localhost:8008/");
|
||||
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
Entities: [
|
||||
// { id: 1, name: "Apple", position: [51.505, -0.10],Type: "Friend" },
|
||||
// { id: 2, name: "Oranges", position: [51.505, -0.11],Type: "Hostile"},
|
||||
// { id: 3, name: "Grapes", position: [51.505, -0.12],Type: "Friend"}
|
||||
],
|
||||
|
||||
|
||||
}
|
||||
state = {
|
||||
Entities: [],
|
||||
EntityOnFocus: []
|
||||
}
|
||||
componentDidMount() {
|
||||
|
||||
connect((msg) => {
|
||||
console.log("New Message")
|
||||
|
||||
var jsonMSG;
|
||||
try {
|
||||
jsonMSG = JSON.parse(msg.data);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
if(jsonMSG["Type"] == "COP"){
|
||||
console.log(msg.data)
|
||||
var Entities = Array.from(jsonMSG["Entities"])
|
||||
if(Array.isArray(Entities))
|
||||
{
|
||||
this.setState({
|
||||
Entities:Entities
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// this.state.Entities = jsonMSG
|
||||
// var jsonmsg = JSON.parse(msg);
|
||||
// this.setState(prevState => ({
|
||||
// // chatHistory: [...this.state.History, msg]
|
||||
// // chatHistory: [...this.state.History, msg]
|
||||
|
||||
// }))
|
||||
|
||||
console.log(this.state.Entities);
|
||||
});
|
||||
componentDidMount() {
|
||||
|
||||
client.onopen = () => {
|
||||
console.log("Websocket Client for Map Connected");
|
||||
};
|
||||
|
||||
client.onmessage = (message) => {
|
||||
const dataFromServer = JSON.parse(message.data);
|
||||
console.log('reply: ', dataFromServer);
|
||||
|
||||
if(dataFromServer.Type === "COP")
|
||||
{
|
||||
this.setState((state) => ({
|
||||
Entities: dataFromServer.Entities
|
||||
})
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// connect((msg) => {
|
||||
// console.log("New Message")
|
||||
|
||||
// var jsonMSG;
|
||||
// try {
|
||||
// jsonMSG = JSON.parse(msg.data);
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// }
|
||||
|
||||
// if(jsonMSG["Type"] == "COP"){
|
||||
// console.log(msg.data)
|
||||
// var Entities = Array.from(jsonMSG["Entities"])
|
||||
// if(Array.isArray(Entities))
|
||||
// {
|
||||
// this.setState({
|
||||
// Entities:Entities
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// console.log(this.state.Entities);
|
||||
// });
|
||||
|
||||
|
||||
}
|
||||
|
||||
updateMap()
|
||||
updateEntities()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
@@ -68,12 +76,18 @@ class App extends Component {
|
||||
Data: "COP"
|
||||
|
||||
}
|
||||
sendMsg(JSON.stringify(msg));
|
||||
client.send(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
MapIntervalCallback = () => {
|
||||
this.updateMap()
|
||||
setEntityOnFocus(Entity)
|
||||
{
|
||||
// console.log(Entity);
|
||||
this.setState({
|
||||
EntityOnFocus: Entity
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const {name} = this.state;
|
||||
@@ -82,13 +96,13 @@ class App extends Component {
|
||||
<Header />
|
||||
<div className="Content">
|
||||
|
||||
<Controls Entities= {this.state.Entities} />
|
||||
<Controls Entities= {this.state.Entities} updateEntities = {this.updateEntities} EntityOnFocus = {this.state.EntityOnFocus} />
|
||||
{/* <ChatHistory History={this.state.History} /> */}
|
||||
{/* <div>
|
||||
{name}
|
||||
|
||||
</div> */}
|
||||
<OpenSeaMap Entities= {this.state.Entities} parentCallback = {this.MapIntervalCallback}/>
|
||||
<OpenSeaMap Entities= {this.state.Entities} updateEntities = {this.updateEntities} setEntityOnFocus = {this.setEntityOnFocus.bind(this)}/>
|
||||
</div>
|
||||
|
||||
{/* <button onClick={this.send}>Hit</button> */}
|
||||
|
||||
@@ -3,7 +3,7 @@ import "./header.scss";
|
||||
|
||||
const Header = () => (
|
||||
<div className="header">
|
||||
<h2>Cloud Simulator</h2>
|
||||
<font className="caption">Cloud Simulator</font>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -6,5 +6,10 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
height: 70px;
|
||||
|
||||
}
|
||||
|
||||
.caption{
|
||||
font-size: 40px;
|
||||
}
|
||||
@@ -3,19 +3,31 @@
|
||||
import React, { Component } from "react";
|
||||
import { MapContainer, TileLayer,Marker, Popup } from 'react-leaflet'
|
||||
import { friend,Hostile, iconShip,createIcon } from "./icon";
|
||||
import "./OpenSeaMap.scss"
|
||||
import { sendMsg } from '../api';
|
||||
|
||||
import "./OpenSeaMap.scss";
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket";
|
||||
import ContainerDimensions from 'react-container-dimensions';
|
||||
const client = new W3CWebSocket("ws://localhost:8008/");
|
||||
|
||||
// import icon from 'leaflet/dist/images/marker-icon.png';
|
||||
class OpenSeaMap extends Component {
|
||||
|
||||
componentDidMount() {
|
||||
// setInterval(() => this.setState({ time: Date.now()}), 1000)
|
||||
setInterval(() => this.props.parentCallback(), 3000)
|
||||
|
||||
|
||||
}
|
||||
|
||||
updateDimensions() {
|
||||
const height = window.innerWidth >= 992 ? window.innerHeight : 400
|
||||
this.setState({ height: height })
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.updateDimensions()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.updateDimensions.bind(this))
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.updateDimensions.bind(this))
|
||||
}
|
||||
|
||||
|
||||
handleClick(e)
|
||||
@@ -29,11 +41,12 @@ class OpenSeaMap extends Component {
|
||||
var icon;
|
||||
icon = createIcon(entity.Type,entity.Side)
|
||||
return (
|
||||
<Marker name={entity.Name} key={index} icon={icon} position={entity.position}
|
||||
<Marker name={entity.Name} key={index} icon={icon} position={entity.position} data={entity.id}
|
||||
|
||||
eventHandlers={{
|
||||
click: (e) => {
|
||||
console.log(e.target.options.name); // will print 'FooBar' in console
|
||||
console.log(e.target.options.data); // will print 'FooBar' in console
|
||||
this.props.setEntityOnFocus(e.target.options.data);
|
||||
},
|
||||
}} >
|
||||
|
||||
@@ -54,7 +67,7 @@ class OpenSeaMap extends Component {
|
||||
// ));
|
||||
|
||||
return (
|
||||
<div className='map' >
|
||||
<div className='map' style={{ height: this.state.height }} >
|
||||
<MapContainer MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true}>
|
||||
<TileLayer
|
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
|
||||
@@ -65,7 +78,7 @@ class OpenSeaMap extends Component {
|
||||
this.makeIcon(index,pos)
|
||||
))}
|
||||
</MapContainer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
// @import url('https://unpkg.com/leaflet@1.5.1/dist/leaflet.css');
|
||||
.leaflet-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
|
||||
.map {
|
||||
padding-top: 1%;
|
||||
height: 800px;
|
||||
width: 76%;
|
||||
// display: flex;
|
||||
padding-top: 10px;
|
||||
// height: 750px;
|
||||
width: 79%;
|
||||
// padding-left: 20%;
|
||||
float: left;
|
||||
// height: 80%;
|
||||
}
|
||||
|
||||
// .leaflet-marker-icon{
|
||||
|
||||
@@ -16,7 +16,7 @@ const AirLetter = "A";
|
||||
const SurfaceLetter = "S";
|
||||
const SubsurfaceLetter = "U";
|
||||
|
||||
const Size = 25;
|
||||
// const Size = 25;
|
||||
|
||||
function createIcon(Type , Side )
|
||||
{
|
||||
|
||||
25
webapp/src/components/control/EntityControl.jsx
Normal file
25
webapp/src/components/control/EntityControl.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from "react"
|
||||
import './controls.css'
|
||||
|
||||
function EntityControl(Entity)
|
||||
{
|
||||
|
||||
|
||||
console.log(Entity)
|
||||
// console.log(EntityOnFocus)
|
||||
return (
|
||||
<div className="ControlsComponent">
|
||||
<div>
|
||||
<div className="ControlHeader">Name</div>
|
||||
<div className="ControlValues">{Entity.Entity.Name}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="ControlHeader">Course</div>
|
||||
<div className="ControlValues">{Entity.Entity.Course}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EntityControl;
|
||||
@@ -1,5 +1,18 @@
|
||||
.controls{
|
||||
display: flex;
|
||||
/* display: flex; */
|
||||
width: 20%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ControlsComponent{
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.ControlHeader{
|
||||
float: left;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.ControlValues{
|
||||
float: left;
|
||||
}
|
||||
@@ -1,32 +1,55 @@
|
||||
import React from 'react';
|
||||
import './controls.css'
|
||||
import { sendMsg } from '../api';
|
||||
// import { sendMsg } from '../api';
|
||||
import Tracklist from './Tracklist'
|
||||
import EntityControl from './EntityControl';
|
||||
import {w3cwebsocket as W3CWebSocket} from "websocket"
|
||||
|
||||
const client = new W3CWebSocket("ws://localhost:8008/");
|
||||
|
||||
class Controls extends React.Component
|
||||
{
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.ws = props.ws;
|
||||
|
||||
// This binding is necessary to make `this` work in the callback
|
||||
}
|
||||
getMessage()
|
||||
state = {
|
||||
EntityOnFocus: this.props.EntityOnFocus
|
||||
}
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
var msg =
|
||||
{
|
||||
Type: "Request",
|
||||
Data: "COP"
|
||||
client.onopen = () => {
|
||||
console.log("Websocket Client Connected");
|
||||
};
|
||||
|
||||
client.onmessage = (message) => {
|
||||
const dataFromServer = JSON.parse(message.data);
|
||||
console.log('reply', dataFromServer);
|
||||
}
|
||||
sendMsg(JSON.stringify(msg));
|
||||
console.log("test");
|
||||
|
||||
}
|
||||
render() {
|
||||
|
||||
|
||||
render() {
|
||||
function getEntityFromID(Entities, SelectedKey)
|
||||
{
|
||||
let tmp = [];
|
||||
Entities.map((val,index) => {
|
||||
if(val.id === SelectedKey)
|
||||
{
|
||||
tmp = val
|
||||
}
|
||||
|
||||
})
|
||||
return tmp;
|
||||
}
|
||||
|
||||
console.log(getEntityFromID(this.props.Entities,this.props.EntityOnFocus));
|
||||
return (
|
||||
<div className="controls">
|
||||
<Tracklist entities= {this.props.Entities} />
|
||||
{/* <button onClick={this.getMessage}> click me!</button> */}
|
||||
<br />
|
||||
<div>
|
||||
<button onClick={this.props.updateEntities}> click me!</button>
|
||||
<EntityControl Entity = { getEntityFromID(this.props.Entities,this.props.EntityOnFocus)} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user