Skip to content

Commit

Permalink
impact charts working
Browse files Browse the repository at this point in the history
  • Loading branch information
jcw780 committed May 16, 2020
1 parent b3e070b commit 3982fbc
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 24 deletions.
24 changes: 18 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import Button from 'react-bootstrap/Button';

import ShellFormsContainer from './ShellForms';
import TargetFormsContainer from './TargetForms';
import ChartGroup from './Charts';

import ShellWasm from './shellWasm.wasm';
import { string } from 'prop-types';


class App extends React.Component<{},{}> {
SFCref = React.createRef<ShellFormsContainer>();
TFCref = React.createRef<TargetFormsContainer>();
graphsRef : React.RefObject<ChartGroup> = React.createRef<ChartGroup>();
instance : any;
arrayIndices : Record<string, Record<string, number>> = {
impactDataIndex: {},
Expand All @@ -39,7 +38,7 @@ class App extends React.Component<{},{}> {
}
});
})
console.log(this.arrayIndices);
//console.log(this.arrayIndices);
});
}
generate = () => {
Expand Down Expand Up @@ -77,11 +76,19 @@ class App extends React.Component<{},{}> {
ra1D : Array.from({length: numShells}, _ => new Array<Record<string, number>>(impactSize)),
},
post: {
shipWidth : Array.from({length: numShells}, _ => new Array<Record<string, number>>(impactSize)),
shipWidth : Array.from({length: 1}, _ => new Array<Record<string, number>>(impactSize)),
notFused: Array.from({length: numShells * numAngles}, _ => new Array<Record<string, number>>()),
Fused: Array.from({length: numShells * numAngles}, _ => new Array<Record<string, number>>()),
}
},
numShells : numShells,
names : Array<string>(numShells),
colors : Array<Array<string>>(numShells),
}

shellData.forEach((value, i) => {
output.names[i] = value.name;
output.colors[i] = value.colors;
});
let maxDist = 0;
let maxShell = 0;
for(let j=0; j<numShells; j++){
Expand Down Expand Up @@ -123,18 +130,23 @@ class App extends React.Component<{},{}> {
maxShell = greater ? j : maxShell;
}
console.log(output);
if(this.graphsRef.current){
this.graphsRef.current.updateData(output);
}
}
render () {
return (
<div className="App">
<ShellFormsContainer ref={this.SFCref}/>
<TargetFormsContainer ref={this.TFCref}/>
<Button onClick={this.generate}>Generate</Button>
<ChartGroup ref={this.graphsRef}/>
</div>
);
}
componentDidMount(){
console.log("done rendering");
//console.log(this);
}
}

Expand Down
155 changes: 144 additions & 11 deletions src/Charts.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,175 @@
import React from 'react';
import {Scatter} from 'react-chartjs-2';
import {Scatter, defaults} from 'react-chartjs-2';
import Container from 'react-bootstrap/Container';

class SingleChart extends React.Component
<{data?: Record<string, any>, options?: Record<string, any>, title?: string,
<{config: Record<string, any>, title?: string,
dimensions: Record<string, number>}> {
chartRef : React.RefObject<Scatter>
public static defaultProps = {
config : {data: {datasets : [],}, options: {}}
}
state = {
updateTrigger : true,
}
chartRef : React.RefObject<Scatter> = React.createRef<Scatter>();
update = () => {
console.log(this.chartRef);
//this.chartRef.update();
//console.log(this.props.config);
//console.log(this.chartRef.current);
this.setState((current) => {
return {updateTrigger : !current['updateTrigger']};
});
}
render(){
return(
<>
<Scatter data={this.props.data} options={this.props.options}
<Scatter data={this.props.config.data} options={this.props.config.options}
width={this.props.dimensions.width} height={this.props.dimensions.height}
ref={this.chartRef}/>
</>
);
}
componentDidMount(){
//console.log(this.chartRef.current);
}
}

class ChartGroup extends React.Component
<{}>{
commonStyle = {};
dimensions = {height: 1200, width: 300};
chartRefs = {
impact: [React.createRef<SingleChart>(), ],
};
dimensions = {height: 300, width: 1200};
chartConfigs : Record<string, Array<[Record<string, any>, React.RefObject<SingleChart>]>> = {
impact: [
[{data: {datasets : Array<any>(),}, options: {}}, React.createRef<SingleChart>()],
[{data: {datasets : Array<any>(),}, options: {}}, React.createRef<SingleChart>()],
[{data: {datasets : Array<any>(),}, options: {}}, React.createRef<SingleChart>()],
],
}
updateData = (graphData) => {
console.log(graphData, this.chartConfigs);
//Common Utility Functions / Values
const addCommas = (value, index, values) => {return value.toLocaleString();}
const commonPointRadius = 0;
const yAxesPenetration = {
id: "Penetration", postition: "left",
scaleLabel: {display: true,},
ticks: {stepSize: 100,
callback: addCommas,
}
}
const xAxesDistance = [{
scaleLabel: {display: true,
labelString: "Distance from Launch (m)",
},
ticks:{callback: addCommas,}
}];

defaults.scatter.scales.xAxes[0] = xAxesDistance;

const yAxesRightAngle = {
id: "Angle", position: "right",
scaleLabel: {display: true,},
}

//Impact Charts
//0
const EPL = "Effective Penetration ";
const IAL = "Impact Angle ";
var hRAL0 = yAxesRightAngle; hRAL0.scaleLabel['labelString'] = "Belt Impact Angle (°)";
var hRPL0 = yAxesPenetration; hRPL0.scaleLabel['labelString'] = "Belt Penetration (mm)";
this.chartConfigs.impact[0][0].options = {
title: {display: true,
text: 'Horizontal Penetration and Impact Angle'
},
scales: {yAxes: [hRPL0 , hRAL0]},
};
//1
var vRAL1 = yAxesRightAngle; vRAL1.scaleLabel['labelString'] = "Deck Impact Angle (°)";
var vRPL1 = yAxesPenetration; vRPL1.scaleLabel['labelString'] = "Deck Penetration (mm)";
const EDP = "Effective Deck Penetration ";
const DIA = "Deck Impact Angle ";
this.chartConfigs.impact[1][0].options = {
title: {display: true,
text: 'Deck Penetration and Impact Angle'
},
scales: {yAxes: [vRPL1, vRAL1]},
}
//2
const IVL = "Impact Velocity "; const FTL = "Flight Time ";
this.chartConfigs.impact[2][0].options = {
title: {display: true,
text: 'Shell Flight Time and Impact Velocity'
},
scales: {
yAxes: [{
id: "Impact Velocity", postition: "left",
scaleLabel: {display: true,
labelString: "Impact Velocity (m/s)",
},
ticks: {stepSize: 100}
},{
id: "Time", position: "right",
scaleLabel: {display: true,
labelString: "Flight Time (s)",
},
}],
}
};

this.chartConfigs.impact[0][0].data.datasets = [];
this.chartConfigs.impact[1][0].data.datasets = [];
this.chartConfigs.impact[2][0].data.datasets = [];
const impactLine = (data : Array<Record<string, number>>,
label: string, yAxisID : string,
color : string = "") : Record<string, any> => {
return {
data: data, showLine: true, label: label, yAxisID: yAxisID,
fill: false, pointRadius: commonPointRadius, pointHitRadius: 5,
borderColor: color
};

}

for(let i=0; i<graphData.numShells; i++){
const name = graphData.names[i]; const colors = graphData.colors[i];
const impactData = graphData.impact;
console.log(graphData.colors, colors);
this.chartConfigs.impact[0][0].data.datasets.push(
impactLine(impactData.ePenHN[i], EPL + name, "Penetration", colors[0]),
impactLine(impactData.impactAHD[i], IAL + name, "Angle", colors[1]));
this.chartConfigs.impact[1][0].data.datasets.push(
impactLine(impactData.ePenDN[i], EDP + name, "Penetration", colors[0]),
impactLine(impactData.impactAHD[i], DIA + name, "Angle", colors[1]));
this.chartConfigs.impact[2][0].data.datasets.push(
impactLine(impactData.impactV[i], IVL + name, "Impact Velocity", colors[0]),
impactLine(impactData.tToTargetA[i], FTL + name, "Time", colors[1]));
}
this.updateCharts();
}
updateCharts = () => {
const updateImpact = (chart : number) => {
const ref = this.chartConfigs.impact[chart][1];
if(ref.current !== undefined){
ref.current!.update();
}
}
this.chartConfigs.impact.forEach((value, i) => {
updateImpact(i);
});

}
render(){
return(
<>
<SingleChart dimensions={this.dimensions} ref={this.chartRefs.impact[0]}/>
<h3 style={{textAlign: "center"}}>Impact Charts</h3>
{this.chartConfigs.impact.map((value, i) => {
return (<SingleChart config={value[0]} dimensions={this.dimensions} ref={this.chartConfigs.impact[i][1]} key={i}/>);
})}
</>
);
}
componentDidMount(){
//console.log(this, defaults);
}
}

export default ChartGroup;
58 changes: 53 additions & 5 deletions src/ShellForms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ShellParameters extends React.Component<shellParametersProps>{
}

interface shellFormsProps{
index: number, keyProp: number, deleteShip : Function
index: number, colors: Array<string>, keyProp: number, deleteShip : Function
}
class ShellForms extends React.Component<shellFormsProps> {
parameters = React.createRef<ShellParameters>()
Expand All @@ -111,6 +111,7 @@ class ShellForms extends React.Component<shellFormsProps> {
const value = kv[1];
condensed[key] = value[1];
})
condensed['colors'] = this.props.colors;
return condensed;
}
nameForm = React.createRef<ParameterForm>()
Expand Down Expand Up @@ -151,13 +152,13 @@ class ShellForms extends React.Component<shellFormsProps> {
render() {
return(
<Modal.Dialog style={{margin: 0}}>
<Modal.Header closeButton onHide={this.deleteShip}>
<Modal.Title>Shell {this.props.index + 1}</Modal.Title>
<Modal.Header closeButton onHide={this.deleteShip} style={{padding: "0.5rem"}}>
<Modal.Title style={{marginLeft: "40%", marginRight: "auto", }}>Shell {this.props.index + 1}</Modal.Title>
</Modal.Header>
<Modal.Body style={{padding: 0}}>
<Container>
<Col sm='12'>
<ParameterForm label="Ship Label" controlId='shipName'
<ParameterForm label="Shell Label" controlId='shipName'
handleValueChange={this.handleNameChange}
type="text" newValue=""
ref={this.nameForm}/>
Expand Down Expand Up @@ -233,6 +234,53 @@ class ShellFormsContainer extends React.Component{
return data;
}

selectColor = (number, colors) => {
const hue = number * 137.507764 % 360; // use golden angle approximation
console.log(hue);
//return this.hslToRgb(hue, .8, .5);
return `hsl(${hue},50%,60%)`;
}

hslToRgb = (h: number, s: number, l: number) => {
var r, g, b;

if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}

var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return 'rgb(' + Math.round(r * 255) + ',' + Math.round(g * 255) + ',' + Math.round(b * 255) + ')'
//return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
/*
selectColor = (colorNum, colors) => {
if (colors < 1) colors = 1; // defaults to one color - avoid divide by zero
return "hsl(" + (colorNum * (360 / colors) % 360) + ",100%,50%)";
}*/

generateColors = (index : number, total : number) => {
const colors = Array<string>(3);
for(let i=0; i<3; i++){
console.log(index * 3 + i, total * 3);
colors[i] = this.selectColor(index * 3 + i, total * 3);
}
console.log(colors, index, total);
return colors;
}

render(){
return(
<>
Expand All @@ -241,7 +289,7 @@ class ShellFormsContainer extends React.Component{
<Row sm={3}>
{Array.from(this.state.keys).map((value, i) => {
return <Col key={value} style={{margin: 0, padding: 0}}>
<ShellForms index={i} deleteShip={this.deleteShip}
<ShellForms colors={this.generateColors(i, this.state.keys.size)} index={i} deleteShip={this.deleteShip}
keyProp={value} ref={this.shellRefs[i]}/>
</Col>;
})}
Expand Down
4 changes: 2 additions & 2 deletions src/TargetForms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class TargetFormsContainer extends React.Component
handleValueChange={this.handleChange} type="number"
label="Target Width" labelWidth={4} />
</div>
<Container>
<Container style={{marginBottom: "1rem"}}>
<Row>
{angleElements.map((values, i) => {
return (
Expand All @@ -125,7 +125,7 @@ class TargetFormsContainer extends React.Component
</Row>
</Container>

<Row>
<Row style={{marginBottom: "1rem"}}>
<Col/>
<Col sm="6"><Button className="form-control" onClick={this.addAngle}>Add Angle</Button></Col>
<Col/>
Expand Down

0 comments on commit 3982fbc

Please sign in to comment.