diff --git a/src/DataFragment.js b/src/DataFragment.js index d4f86567..1493eb52 100644 --- a/src/DataFragment.js +++ b/src/DataFragment.js @@ -6,6 +6,7 @@ import { Button } from 'react-native-material-ui'; import LatestDataFragment from "./LatestDataFragment.js"; import HistoricalDataFragment from "./HistoricalDataFragment.js" +import LastFlashDataFragment from "./LastFlashDataFragment.js" const initialLayout = { height: 0, @@ -19,7 +20,7 @@ const styles = StyleSheet.create({ flex: 1, }, tab: { - width: Dimensions.get('window').width / 2, + width: Dimensions.get('window').width / 3, }, tabbar: { backgroundColor: '#19222a', @@ -44,19 +45,19 @@ export default class DataFragment extends React.Component { routes: [ { key: 'first', title: 'Latest' }, { key: 'second', title: 'Historical' }, + { key: 'third', title: 'Last Flash' }, ], refreshList: false, } - constructor(props) { + /* constructor(props) { super(props); this.tableUpdate = this.tableUpdate.bind(this); } tableUpdate(e) { this.setState({ refreshList: !this.state.refreshList }); - this.tableDialog.show(); - } + this.tableDialog.show();*/ LatestView = () => ( @@ -65,12 +66,16 @@ export default class DataFragment extends React.Component { HistoricalView = () => ( {this.historicalDataFragment = historicalDataFragment}}/> ); + LastFlashView = () => ( + + ); _handleIndexChange = index => this.setState({ index, }); _renderScene = SceneMap({ first: this.LatestView, second: this.HistoricalView, + third: this.LastFlashView, }); _renderTabBar = props => ( diff --git a/src/LastFlashDataFragment.js b/src/LastFlashDataFragment.js new file mode 100644 index 00000000..43bea277 --- /dev/null +++ b/src/LastFlashDataFragment.js @@ -0,0 +1,368 @@ +import React, {Component} from 'react'; +import { Alert, Dimensions, StyleSheet, View, ScrollView, Text, TouchableOpacity } from 'react-native'; +import { VictoryBar, VictoryChart, VictoryTheme, VictoryLine, VictoryScatter, VictoryStack, VictoryArea, VictoryAxis } from "victory-native"; +import { Button } from 'react-native-material-ui'; +import SectionedMultiSelect from 'react-native-sectioned-multi-select'; +import Icon from '@expo/vector-icons/MaterialCommunityIcons'; +import * as math from 'mathjs'; + +import {getFlashBurstData} from '../api-library-js/EQUiSatAPI.js'; +import {signalToName} from '../api-library-js/HumanReadables.js'; + +const styles = StyleSheet.create({ + dataContainer: { + flex: 1, + justifyContent: 'center', + backgroundColor: '#131a20', + }, + rowContainer: { + flexDirection: 'row', + justifyContent: 'space-evenly', + }, + inlineContainer: { + flexDirection: 'row', + justifyContent: 'flex-start', + }, + multiSelectContainer: { + backgroundColor: '#19222a', + }, + multiSelectSearchIcon: { + backgroundColor: '#FFFFFF', + }, +}); + +const timeStamps = [-20, 0, 20, 40, 60, 80, 100]; + +const unitMappings = { + "LF1REF": "mV", + "LF2REF": "mV", + "LF3REF": "mV", + "LF4REF": "mV", + "LFREF_AVG": "mV", + "LFB1SNS": "mA", + "LFB1OSNS": "mA", + "LFB2SNS": "mA", + "LFB2OSNS": "mA", + "LFBSNS_AVG": "mA", + "LED1SNS": "mA", + "LED2SNS": "mA", + "LED3SNS": "mA", + "LED4SNS": "mA", + "LEDSNS_AVG": "mA", + "LED1TEMP": "C", + "LED2TEMP": "C", + "LED3TEMP": "C", + "LED4TEMP": "C", + "LEDTEMP_AVG": "C", + "LF1_TEMP": "C", + "LF3_TEMP": "C", + "LTEMP_AVG": "C", +} + +const tickValues = [ + [0.25, 0.5, 0.75, 1], + [0.25, 0.5, 0.75, 1], + [0.125, 0.375, 0.625, 0.875], + [0.125, 0.375, 0.625, 0.875] +] + +const avcSignals = ["LF1REF","LF2REF","LF3REF","LF4REF","LFREF_AVG","LFB1SNS","LFB1OSNS","LFB2SNS","LFB2OSNS","LFBSNS_AVG","LED1SNS","LED2SNS","LED3SNS","LED4SNS","LEDSNS_AVG"]; +const tempSignals = ["LED1TEMP","LED2TEMP","LED3TEMP","LED4TEMP","LEDTEMP_AVG","LF1_TEMP","LF3_TEMP","LTEMP_AVG"]; + +const xOffsets = [50, 350, 0, 400]; +const tickPadding = [-5, -15, -15, -5]; +const anchors = ["end", "start", "start", "end"]; +const colors = ["rgb(255, 99, 132)", "rgb(54, 162, 235)", "rgb(255, 206, 86)", "rgb(75, 192, 192)"]; + +const maxItems = 4; + +class LastFlashDataFragment extends Component { + + state = { + signalItems: [], + selectedItems: [], + confirmText: "", + graphData1: [], + graphData2: [], + graphData3: [], + graphData4: [], + haveFlashData: false, + } + + makeSignalChildrenArr(signalList) { + var childrenArr = []; + for (var i = 0; i < signalList.length; i++) { + childrenArr.push({name: signalToName(signalList[i]), id: signalList[i]}); + } + return childrenArr; + } + + componentDidMount() { + this.makeSignalItems(); + var _this = this; + getFlashBurstData(["LED1TEMP"], 1) + .then(function(result) { + if (result.data.length > 0) { + _this.setState({ haveFlashData: true }); + } + }) + .catch(function (error) { + console.log(error); + }); + + } + + makeSignalItems() { + var items = []; + var avc = {name: "Analog Voltage/Current", id: "0", children: this.makeSignalChildrenArr(avcSignals)}; + var temps = {name: "Temperatures", id: "1", children: this.makeSignalChildrenArr(tempSignals)}; + items.push(avc, temps); + this.setState({ signalItems: items }); + } + + displayLabel(shouldDisplay, labelNum) { + if (shouldDisplay) { + switch(labelNum) { + case 1: + return ( + + {this.state.selectedItems.length > 0 ? this.state.selectedItems[0] : "" } + ); + break; + case 2: + return ( + + {this.state.selectedItems.length > 0 ? this.state.selectedItems[1] : "" } + ); + break; + case 3: + return ( + + {this.state.selectedItems.length > 0 ? this.state.selectedItems[2] : "" } + ); + break; + case 4: + return( + + {this.state.selectedItems.length > 0 ? this.state.selectedItems[3] : "" } + ); + break; + } + } else { + return + } + } + + onSelectedItemsChange = (selectedItems) => { + if ( selectedItems.length > maxItems ) { + Alert.alert( + 'Too Many Signals', + 'Please select no more than 4 signals.', + [ + {text: 'OK'}, + ], + { cancelable: false } + ) + return; + } + this.setState({confirmText:` - ${selectedItems.length}/${maxItems}`}); + this.setState({ selectedItems }); + } + + _getSignalCodes = (code) => { + switch (code) { + case "LFREF_AVG": return ["LF1REF", "LF2REF", "LF3REF", "LF4REF"]; + case "LFBSNS_AVG": return ["LFB1SNS", "LFB2SNS", "LFB1OSNS", "LFB2OSNS"]; + case "LEDSNS_AVG": return ["LED1SNS", "LED2SNS", "LED3SNS", "LED4SNS"]; + case "LEDTEMP_AVG": return ["LED1TEMP", "LED2TEMP", "LED3TEMP", "LED4TEMP"]; + case "LTEMP_AVG": return ["LF1_TEMP", "LF3_TEMP"]; + default: return [code]; + } + } + + _formatTick = (t, i) => { + if (i < this.state.selectedItems.length) { + tick_unit = math.unit(t, unitMappings[this.state.selectedItems[i]]); + tick_formatted = tick_unit.format({notation: 'fixed', precision: 1}); + return tick_formatted; + } else { + return ""; + } + } + + getFullData = () => { + var data = []; + const full_data = [ + this.state.graphData1, + this.state.graphData2, + this.state.graphData3, + this.state.graphData4 + ] + for (let x = 0; x<4; x++) { + if (full_data[x].length > 0) { + data.push(full_data[x]) + } + } + return data; + } + + setGraphData(signals, _this) { + if (signals.length == 0) { + _this.setState( + { + graphData1: [], + graphData2: [], + graphData3: [], + graphData4: [] + } + ) + } else if (signals.length == 1) { + _this.setState( { + graphData2: [], + graphData3: [], + graphData4: [] + }) + } else if (signals.length == 2) { + _this.setState({ + graphData3: [], + graphData4: [] + }) + } else if (signals.length == 3) { + _this.setState({ graphData4: []}) + } + for (let k=0; k + Awaiting First Flash + + ); + } else { + return ( + + + Sorry, no results} + searchIconComponent={} + selectToggleIconComponent={} + dropDownToggleIconUpComponent={} + dropDownToggleIconDownComponent={} + styles={{container: styles.multiSelectContainer, listContainer: styles.multiSelectContainer, item: styles.multiSelectContainer, subItem: styles.multiSelectContainer, searchBar: styles.multiSelectContainer, searchTextInput: {color: "#e5e5e5"}, selectedItem: {backgroundColor: "#6aa2c8"}}} + colors={{primary: "#6aa2c8", text: "#e5e5e5", subText: "#e5e5e5", chipColor: "#6aa2c8", selectToggleTextColor: "#e5e5e5", itemBackground: "#19222a", success: "#e5e5e5"}} + onConfirm={ () => this.setGraphData(this.state.selectedItems, this) } + /> + + + {this.displayLabel(this.state.selectedItems.length > 0, 1)} + {this.displayLabel(this.state.selectedItems.length > 1, 2)} + {this.displayLabel(this.state.selectedItems.length > 2, 3)} + {this.displayLabel(this.state.selectedItems.length > 3, 4)} + + + + + + {this.getFullData().map((d, i) => ( + { + const graphMax = this.getFullData().map( + (dataset) => Math.max(...dataset.map((d) => d.y)) + ); + const graphMin = this.getFullData().map( + (dataset) => Math.min(...dataset.map((d) => d.y)) + ); + return this._formatTick((t * (graphMax[i] - graphMin[i])) + graphMin[i], i).replace('degC', 'C'); + }} + /> + ))} + {this.getFullData().map((d, i) => ( + {//datum.y / this.state.graphMaxima[i] } + const graphMax = this.getFullData().map( + (dataset) => Math.max(...dataset.map((d) => d.y)) + ); + const graphMin = this.getFullData().map( + (dataset) => Math.min(...dataset.map((d) => d.y)) + ); + return graphMax[i] - graphMin[i] == 0 + ? datum.y + : (datum.y - graphMin[i]) / (graphMax[i] - graphMin[i])} + } + /> + ))} + + + + + ); + } + } +} + +module.exports= LastFlashDataFragment