ADD: added small details view on click on an entity

This commit is contained in:
hwinkel
2023-09-25 09:26:46 +02:00
parent df41e5d9ea
commit 8587d1d664
11 changed files with 2829 additions and 2761 deletions

5317
webapp/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,12 +7,14 @@
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-container-dimensions": "^1.4.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-leaflet": "^4.2.1", "react-leaflet": "^4.2.1",
"react-scripts": "5.0.1", "react-scripts": "^5.0.1",
"react-use-websocket": "^4.3.1", "react-use-websocket": "^4.3.1",
"sass": "^1.66.1", "sass": "^1.66.1",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4",
"websocket": "^1.0.34"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

View File

@@ -1,66 +1,74 @@
// App.js // App.js
import React, { Component } from "react"; import React, { Component } from "react";
import "./App.css"; import "./App.css";
import { connect, sendMsg } from "./components/api/index"; // import { connect, sendMsg } from "./components/api/index";
import Header from './components/Header'; import Header from './components/Header';
import Controls from "./components/control/controls"; import Controls from "./components/control/controls";
// import ChatHistory from "./components/ChatHistory/ChatHistory.jsx"; // import ChatHistory from "./components/ChatHistory/ChatHistory.jsx";
import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap"; import OpenSeaMap from "./components/OpenSeaMap/OpenSeaMap";
import {w3cwebsocket as W3CWebSocket} from "websocket"
const client = new W3CWebSocket("ws://localhost:8008/");
class App extends Component { class App extends Component {
constructor(props) { state = {
super(props); Entities: [],
this.state = { EntityOnFocus: []
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"}
],
}
} }
componentDidMount() { componentDidMount() {
connect((msg) => { client.onopen = () => {
console.log("New Message") console.log("Websocket Client for Map Connected");
};
var jsonMSG; client.onmessage = (message) => {
try { const dataFromServer = JSON.parse(message.data);
jsonMSG = JSON.parse(msg.data); console.log('reply: ', dataFromServer);
} catch (error) {
console.log(error);
}
if(jsonMSG["Type"] == "COP"){ if(dataFromServer.Type === "COP")
console.log(msg.data) {
var Entities = Array.from(jsonMSG["Entities"]) this.setState((state) => ({
if(Array.isArray(Entities)) Entities: dataFromServer.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); // 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 = var msg =
{ {
@@ -68,13 +76,19 @@ class App extends Component {
Data: "COP" Data: "COP"
} }
sendMsg(JSON.stringify(msg)); client.send(JSON.stringify(msg));
} }
MapIntervalCallback = () => { setEntityOnFocus(Entity)
this.updateMap() {
// console.log(Entity);
this.setState({
EntityOnFocus: Entity
});
} }
render() { render() {
const {name} = this.state; const {name} = this.state;
return ( return (
@@ -82,13 +96,13 @@ class App extends Component {
<Header /> <Header />
<div className="Content"> <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} /> */} {/* <ChatHistory History={this.state.History} /> */}
{/* <div> {/* <div>
{name} {name}
</div> */} </div> */}
<OpenSeaMap Entities= {this.state.Entities} parentCallback = {this.MapIntervalCallback}/> <OpenSeaMap Entities= {this.state.Entities} updateEntities = {this.updateEntities} setEntityOnFocus = {this.setEntityOnFocus.bind(this)}/>
</div> </div>
{/* <button onClick={this.send}>Hit</button> */} {/* <button onClick={this.send}>Hit</button> */}

View File

@@ -3,7 +3,7 @@ import "./header.scss";
const Header = () => ( const Header = () => (
<div className="header"> <div className="header">
<h2>Cloud Simulator</h2> <font className="caption">Cloud Simulator</font>
</div> </div>
); );

View File

@@ -6,5 +6,10 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: white; color: white;
height: 70px;
} }
.caption{
font-size: 40px;
}

View File

@@ -3,19 +3,31 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { MapContainer, TileLayer,Marker, Popup } from 'react-leaflet' import { MapContainer, TileLayer,Marker, Popup } from 'react-leaflet'
import { friend,Hostile, iconShip,createIcon } from "./icon"; import { friend,Hostile, iconShip,createIcon } from "./icon";
import "./OpenSeaMap.scss" import "./OpenSeaMap.scss";
import { sendMsg } from '../api'; 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'; // import icon from 'leaflet/dist/images/marker-icon.png';
class OpenSeaMap extends Component { class OpenSeaMap extends Component {
updateDimensions() {
const height = window.innerWidth >= 992 ? window.innerHeight : 400
this.setState({ height: height })
}
componentWillMount() {
this.updateDimensions()
}
componentDidMount() { componentDidMount() {
// setInterval(() => this.setState({ time: Date.now()}), 1000) window.addEventListener("resize", this.updateDimensions.bind(this))
setInterval(() => this.props.parentCallback(), 3000) }
componentWillUnmount() {
} window.removeEventListener("resize", this.updateDimensions.bind(this))
}
handleClick(e) handleClick(e)
@@ -29,11 +41,12 @@ class OpenSeaMap extends Component {
var icon; var icon;
icon = createIcon(entity.Type,entity.Side) icon = createIcon(entity.Type,entity.Side)
return ( 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={{ eventHandlers={{
click: (e) => { 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 ( return (
<div className='map' > <div className='map' style={{ height: this.state.height }} >
<MapContainer MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true}> <MapContainer MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={true}>
<TileLayer <TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" />
@@ -65,7 +78,7 @@ class OpenSeaMap extends Component {
this.makeIcon(index,pos) this.makeIcon(index,pos)
))} ))}
</MapContainer> </MapContainer>
</div> </div>
); );
} }
} }

View File

@@ -3,16 +3,18 @@
// @import url('https://unpkg.com/leaflet@1.5.1/dist/leaflet.css'); // @import url('https://unpkg.com/leaflet@1.5.1/dist/leaflet.css');
.leaflet-container { .leaflet-container {
width: 100%; width: 100%;
height: 100%; height: 90%;
} }
.map { .map {
padding-top: 1%; // display: flex;
height: 800px; padding-top: 10px;
width: 76%; // height: 750px;
width: 79%;
// padding-left: 20%; // padding-left: 20%;
float: left; float: left;
// height: 80%;
} }
// .leaflet-marker-icon{ // .leaflet-marker-icon{

View File

@@ -16,7 +16,7 @@ const AirLetter = "A";
const SurfaceLetter = "S"; const SurfaceLetter = "S";
const SubsurfaceLetter = "U"; const SubsurfaceLetter = "U";
const Size = 25; // const Size = 25;
function createIcon(Type , Side ) function createIcon(Type , Side )
{ {

View 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;

View File

@@ -1,5 +1,18 @@
.controls{ .controls{
display: flex; /* display: flex; */
width: 20%; width: 20%;
float: left; float: left;
} }
.ControlsComponent{
display: grid;
}
.ControlHeader{
float: left;
width: 30%;
}
.ControlValues{
float: left;
}

View File

@@ -1,32 +1,55 @@
import React from 'react'; import React from 'react';
import './controls.css' import './controls.css'
import { sendMsg } from '../api'; // import { sendMsg } from '../api';
import Tracklist from './Tracklist' 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 class Controls extends React.Component
{ {
constructor(props) {
super(props);
this.ws = props.ws;
// This binding is necessary to make `this` work in the callback state = {
} EntityOnFocus: this.props.EntityOnFocus
getMessage() }
componentDidMount()
{ {
var msg = client.onopen = () => {
{ console.log("Websocket Client Connected");
Type: "Request", };
Data: "COP"
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 ( return (
<div className="controls"> <div className="controls">
<Tracklist entities= {this.props.Entities} /> <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> </div>
); );
} }