Added old site
This commit is contained in:
parent
0b0c3f8e36
commit
655d8b0dc8
135
App_old.js
135
App_old.js
|
@ -1,135 +0,0 @@
|
|||
import React, {useState} from 'react';
|
||||
import {StyleSheet, Text, View, Button, TextInput, Dimensions, StatusBar} from 'react-native';
|
||||
import { LineChart} from 'react-native-chart-kit';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import PropValueCard from './components/PropValueCard'
|
||||
|
||||
|
||||
export default function App() {
|
||||
const [outputText, setOutputText] = useState('This is the first text');
|
||||
|
||||
const [flag, setFlag] = useState(false);
|
||||
|
||||
const initialState = [];
|
||||
for(let i=0; i < 100; ++i) {
|
||||
initialState.push( Math.random() * 100);
|
||||
}
|
||||
|
||||
const [graphData, setGraphData] = useState(initialState);
|
||||
|
||||
const makeNewGraphData = () => {
|
||||
setGraphData( oldGraphData => {
|
||||
console.log("Before", oldGraphData)
|
||||
oldGraphData.pop();
|
||||
oldGraphData.unshift(Math.random() * 100);
|
||||
console.log("After", oldGraphData);
|
||||
return oldGraphData.slice();
|
||||
})
|
||||
};
|
||||
const makeNewGraphData2 = () => {
|
||||
graphData.pop();
|
||||
graphData.unshift(Math.random() * 100);
|
||||
setGraphData(graphData);
|
||||
};
|
||||
|
||||
let tutorial = (
|
||||
<View style={{padding: 50}}>
|
||||
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center'}}>
|
||||
<TextInput
|
||||
style={{width: '70%', borderColor: 'black', borderWidth: 1, padding: 5}}
|
||||
placeholder="Course goal"
|
||||
/>
|
||||
<Button title="ADD"/>
|
||||
</View>
|
||||
|
||||
<Text style={{fontSize: 50}}>Text1
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
let mine = (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.view1}><Text>View1</Text></View>
|
||||
<View style={styles.view2}><Text>View2</Text></View>
|
||||
<View style={styles.view3}><Text>View3 </Text><TextInput/></View>
|
||||
|
||||
<View>
|
||||
<Text>{flag ? "Text1" : "Text2"}</Text>
|
||||
<Button title="Subba app is dat" onPress={() => setFlag(!flag)}/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
let graph = (
|
||||
<View>
|
||||
<StatusBar hidden={true} />
|
||||
|
||||
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
|
||||
<PropValueCard label="Züge" value="1234"/>
|
||||
<PropValueCard label="Bahnen" value="30"/>
|
||||
</View>
|
||||
|
||||
<View style={{justifyContent: 'center', alignItems: 'center', flexDirection:'row'}}>
|
||||
<LineChart
|
||||
data={{
|
||||
datasets: [{
|
||||
data: graphData
|
||||
}]
|
||||
}}
|
||||
width={Dimensions.get('window').width - 30} // from react-native
|
||||
height={180}
|
||||
chartConfig={{
|
||||
backgroundColor: '#e26a00',
|
||||
backgroundGradientFrom: '#fb8c00',
|
||||
backgroundGradientTo: '#ffa726',
|
||||
decimalPlaces: 0, // optional, defaults to 2dp
|
||||
color: (opacity = 1) => `rgba(255, 255, 255, 0.8)`,
|
||||
style: {
|
||||
borderRadius: 16
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
borderRadius: 16,
|
||||
}}
|
||||
bezier
|
||||
withDots={false}
|
||||
withInnerLines={false}
|
||||
withOuterLines={false}
|
||||
withVerticalLabel={false}
|
||||
withHorizontalLabels={true}
|
||||
fromZero={true}
|
||||
/>
|
||||
</View>
|
||||
<View>
|
||||
<Button title="UUUND nochmal" onPress={makeNewGraphData}/>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
);
|
||||
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
padding: 50,
|
||||
backgroundColor: '#7573ee',
|
||||
//alignItems: 'center',
|
||||
//justifyContent: 'center',
|
||||
justifyContent: 'space-between'
|
||||
},
|
||||
view1: {
|
||||
backgroundColor: 'green',
|
||||
height: 300
|
||||
},
|
||||
view2: {
|
||||
backgroundColor: 'blue',
|
||||
height: 100,
|
||||
},
|
||||
view3: {
|
||||
backgroundColor: 'white',
|
||||
height: 25
|
||||
}
|
||||
});
|
|
@ -0,0 +1,252 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>SwimTrainer</title>
|
||||
|
||||
<!-- plot.ly -->
|
||||
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
|
||||
|
||||
<!-- chart.js -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
|
||||
|
||||
<!-- Materialize -->
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
<!-- MsgPack -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/msgpack5/4.2.0/msgpack5.js"></script>
|
||||
|
||||
<link rel="manifest" href="swimtrainer.webmanifest">
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
|
||||
<nav class="blue " role="navigation">
|
||||
<div class="nav-wrapper container"><a id="logo-container" href="#" class="brand-logo">SwimTrainer</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="row">
|
||||
<div class="col s4 center-align">
|
||||
<h5>Bahnen</h5>
|
||||
<h1><span id="lanes"></span></h1>
|
||||
</div>
|
||||
<div class="col s4 center-align">
|
||||
<h5>Züge</h5>
|
||||
<h1><span id="peaks"></span></h1>
|
||||
</div>
|
||||
<div class="col s4 center-align">
|
||||
<a class="waves-effect waves-light btn-large" onclick="reload()">Neu laden</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<canvas id="plotCanvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col s3">
|
||||
</div>
|
||||
<div class="col s6">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s6"><label>Seconds</label></div>
|
||||
<div class="col s6"> <input type="number" id="seconds" min="30" max="3600" value="120"> </div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s6"><label>Threshold</label></div>
|
||||
<div class="col s6"> <input type="number" id="threshold" min="100" max="60000" value="2000"> </div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s6"><label>y max</label></div>
|
||||
<div class="col s6"> <input type="number" id="ymax" min="1000" max="60000" value="4000"> </div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="btn red white-text waves-effect waves-light" id="clickMe" type="button" onclick="save();">
|
||||
<i class="material-icons left">save</i>
|
||||
Speichern
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const url = 'http://smartswim/api/session/data';
|
||||
|
||||
// ------------------ MsgPack --------------------------------------------------------------
|
||||
var msgpack = msgpack5();
|
||||
msgpack.registerDecoder(0xd1, function (byteArr) {
|
||||
function typedArrayToBuffer(array) {
|
||||
return array.buffer.slice(array.byteOffset, array.byteLength + array.byteOffset)
|
||||
}
|
||||
|
||||
return new Int16Array(typedArrayToBuffer(byteArr));
|
||||
});
|
||||
|
||||
function countPeaks(array, threshold=500)
|
||||
{
|
||||
var result = 0;
|
||||
var lastMin = 0;
|
||||
for(var i = 1; i < array.length - 2; i++)
|
||||
{
|
||||
var current = array[i].y;
|
||||
var last = array[i-1].y;
|
||||
var next = array[i+1].y;
|
||||
|
||||
if(current > next && current > last && (current - lastMin) > threshold) {
|
||||
result += 1;
|
||||
lastMin = array[i].y;
|
||||
}
|
||||
lastMin = Math.min(lastMin, array[i].y);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------ Plot data -------------------------------------------------------------
|
||||
|
||||
|
||||
var ctx = document.getElementById('plotCanvas').getContext('2d');
|
||||
var chart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [],
|
||||
backgroundColor: '#2196f388',
|
||||
color: 'blue'
|
||||
}]
|
||||
},
|
||||
options: {color: ['red']}
|
||||
});
|
||||
|
||||
|
||||
var appendToPlotArray = function (typedTimeArr, typedValueArr, currentTime) {
|
||||
var plotArray = chart.data.datasets[0].data;
|
||||
// remove last element, pop on empty is ok
|
||||
plotArray.pop();
|
||||
|
||||
for (var i = 0; i < typedValueArr.length; ++i) {
|
||||
plotArray.push({x: typedTimeArr[i], y: typedValueArr[i]});
|
||||
}
|
||||
plotArray.push({x: currentTime, y: plotArray[plotArray.length - 1].y});
|
||||
|
||||
var secondsToShow = parseInt( document.getElementById("seconds").value );
|
||||
var yMax = parseInt( document.getElementById("ymax").value );
|
||||
|
||||
chart.options = {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
elements: {
|
||||
point: {
|
||||
radius: 2
|
||||
},
|
||||
line: {
|
||||
tension: 0 // disables bezier curves
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{
|
||||
ticks: {
|
||||
min: plotArray[plotArray.length - 1].x - secondsToShow * 10,
|
||||
max: plotArray[plotArray.length - 1].x
|
||||
},
|
||||
type: 'linear',
|
||||
display: false
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
min: 0,
|
||||
max: yMax
|
||||
},
|
||||
type: 'linear'
|
||||
}],
|
||||
}
|
||||
};
|
||||
chart.data.datasets[0].data = plotArray;
|
||||
chart.update();
|
||||
};
|
||||
|
||||
var reload = function() {
|
||||
chart.data.datasets[0].data = [];
|
||||
};
|
||||
/*
|
||||
var appendToPlot = function (typedTimeArr, typedValueArr, currentTime)
|
||||
{
|
||||
return;
|
||||
// remove last element, pop on empty is ok
|
||||
plotData.x.pop();
|
||||
plotData.y.pop();
|
||||
|
||||
var timeArr = Array.prototype.slice.call(typedTimeArr);
|
||||
var valueArr = Array.prototype.slice.call(typedValueArr);
|
||||
plotData.x = plotData.x.concat(timeArr);
|
||||
plotData.y = plotData.y.concat(valueArr);
|
||||
|
||||
// add last element
|
||||
plotData.x.push(currentTime);
|
||||
plotData.y.push(plotData.y[plotData.y.length - 1]);
|
||||
|
||||
var plotObj = document.getElementById('plot');
|
||||
Plotly.purge(plotObj);
|
||||
Plotly.plot(plotObj, [plotData]);
|
||||
};*/
|
||||
|
||||
var updateRunning = false;
|
||||
var update = function ()
|
||||
{
|
||||
if( updateRunning === true ) {
|
||||
//console.log("Skipping update, because update is running");
|
||||
return;
|
||||
}
|
||||
var oReq = new XMLHttpRequest();
|
||||
var startIndex = chart.data.datasets[0].data.length;
|
||||
if (startIndex > 0) {
|
||||
startIndex -= 1;
|
||||
}
|
||||
|
||||
oReq.open("GET", url + "?startIndex=" + startIndex, true);
|
||||
oReq.responseType = "arraybuffer";
|
||||
//console.log("-> Query, startIndex=", startIndex);
|
||||
oReq.onload = function (oEvent) {
|
||||
var arrayBuffer = oReq.response; // Note: not oReq.responseText
|
||||
if (arrayBuffer) {
|
||||
var decoded = msgpack.decode(arrayBuffer);
|
||||
//console.log("-> Finished query", startIndex, "#old:", chart.data.datasets[0].data.length,
|
||||
// "#new:", decoded['values'].length);
|
||||
appendToPlotArray(decoded['timestamps'], decoded['values'], decoded['currentTime']);
|
||||
//console.log("-> After unpack", chart.data.datasets[0].data.length);
|
||||
var peakThreshold = parseInt( document.getElementById("threshold").value );
|
||||
var peaks = countPeaks(chart.data.datasets[0].data, peakThreshold);
|
||||
document.getElementById("peaks").textContent = peaks;
|
||||
document.getElementById("lanes").textContent = (peaks / 30).toFixed(1);
|
||||
|
||||
}
|
||||
updateRunning = false;
|
||||
};
|
||||
oReq.send(null);
|
||||
updateRunning = true;
|
||||
};
|
||||
update();
|
||||
|
||||
setInterval(update, 1000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,59 @@
|
|||
import SimpleHTTPServer
|
||||
class CORSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||
def send_head(self):
|
||||
"""Common code for GET and HEAD commands.
|
||||
This sends the response code and MIME headers.
|
||||
Return value is either a file object (which has to be copied
|
||||
to the outputfile by the caller unless the command was HEAD,
|
||||
and must be closed by the caller under all circumstances), or
|
||||
None, in which case the caller has nothing further to do.
|
||||
"""
|
||||
path = self.translate_path(self.path)
|
||||
f = None
|
||||
if os.path.isdir(path):
|
||||
if not self.path.endswith('/'):
|
||||
# redirect browser - doing basically what apache does
|
||||
self.send_response(301)
|
||||
self.send_header("Location", self.path + "/")
|
||||
self.end_headers()
|
||||
return None
|
||||
for index in "index.html", "index.htm":
|
||||
index = os.path.join(path, index)
|
||||
if os.path.exists(index):
|
||||
path = index
|
||||
break
|
||||
else:
|
||||
return self.list_directory(path)
|
||||
ctype = self.guess_type(path)
|
||||
try:
|
||||
# Always read in binary mode. Opening files in text mode may cause
|
||||
# newline translations, making the actual size of the content
|
||||
# transmitted *less* than the content-length!
|
||||
f = open(path, 'rb')
|
||||
except IOError:
|
||||
self.send_error(404, "File not found")
|
||||
return None
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", ctype)
|
||||
fs = os.fstat(f.fileno())
|
||||
self.send_header("Content-Length", str(fs[6]))
|
||||
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
|
||||
self.send_header("Access-Control-Allow-Origin", "*")
|
||||
self.end_headers()
|
||||
return f
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
import SocketServer
|
||||
|
||||
PORT = 31339
|
||||
|
||||
Handler = CORSHTTPRequestHandler
|
||||
#Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
|
||||
|
||||
httpd = SocketServer.TCPServer(("", PORT), Handler)
|
||||
|
||||
print "serving at port", PORT
|
||||
httpd.serve_forever()
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#!/usr/bin/env python3
|
||||
# encoding: utf-8
|
||||
"""Use instead of `python3 -m http.server` when you need CORS"""
|
||||
|
||||
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||
|
||||
|
||||
class CORSRequestHandler(SimpleHTTPRequestHandler):
|
||||
def end_headers(self):
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET')
|
||||
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate')
|
||||
return super(CORSRequestHandler, self).end_headers()
|
||||
|
||||
|
||||
httpd = HTTPServer(('0.0.0.0', 8003), CORSRequestHandler)
|
||||
print("serving on http://localhost:8003/")
|
||||
httpd.serve_forever()
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"background_color": "blue",
|
||||
"description": "Measures force on pool trainer",
|
||||
"display": "fullscreen",
|
||||
"name": "SwimTrainer",
|
||||
"short_name": "SwimTrainer",
|
||||
"start_url": "/"
|
||||
}
|
Loading…
Reference in New Issue