From 3982fbc09545b652b0d96705e12557bf0c1deef7 Mon Sep 17 00:00:00 2001 From: jcw780 <30562395+jcw780@users.noreply.github.com> Date: Sat, 16 May 2020 01:49:28 -0400 Subject: [PATCH] impact charts working --- src/App.tsx | 24 +++++-- src/Charts.tsx | 155 ++++++++++++++++++++++++++++++++++++++++---- src/ShellForms.tsx | 58 +++++++++++++++-- src/TargetForms.tsx | 4 +- 4 files changed, 217 insertions(+), 24 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c3cd6f4..ba540c7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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(); TFCref = React.createRef(); + graphsRef : React.RefObject = React.createRef(); instance : any; arrayIndices : Record> = { impactDataIndex: {}, @@ -39,7 +38,7 @@ class App extends React.Component<{},{}> { } }); }) - console.log(this.arrayIndices); + //console.log(this.arrayIndices); }); } generate = () => { @@ -77,11 +76,19 @@ class App extends React.Component<{},{}> { ra1D : Array.from({length: numShells}, _ => new Array>(impactSize)), }, post: { - shipWidth : Array.from({length: numShells}, _ => new Array>(impactSize)), + shipWidth : Array.from({length: 1}, _ => new Array>(impactSize)), notFused: Array.from({length: numShells * numAngles}, _ => new Array>()), Fused: Array.from({length: numShells * numAngles}, _ => new Array>()), - } + }, + numShells : numShells, + names : Array(numShells), + colors : Array>(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 { maxShell = greater ? j : maxShell; } console.log(output); + if(this.graphsRef.current){ + this.graphsRef.current.updateData(output); + } } render () { return ( @@ -130,11 +140,13 @@ class App extends React.Component<{},{}> { + ); } componentDidMount(){ console.log("done rendering"); + //console.log(this); } } diff --git a/src/Charts.tsx b/src/Charts.tsx index 64accb3..05a88a6 100644 --- a/src/Charts.tsx +++ b/src/Charts.tsx @@ -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, options?: Record, title?: string, +<{config: Record, title?: string, dimensions: Record}> { - chartRef : React.RefObject + public static defaultProps = { + config : {data: {datasets : [],}, options: {}} + } + state = { + updateTrigger : true, + } + chartRef : React.RefObject = React.createRef(); 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( <> - ); } + componentDidMount(){ + //console.log(this.chartRef.current); + } } class ChartGroup extends React.Component <{}>{ commonStyle = {}; - dimensions = {height: 1200, width: 300}; - chartRefs = { - impact: [React.createRef(), ], - }; + dimensions = {height: 300, width: 1200}; + chartConfigs : Record, React.RefObject]>> = { + impact: [ + [{data: {datasets : Array(),}, options: {}}, React.createRef()], + [{data: {datasets : Array(),}, options: {}}, React.createRef()], + [{data: {datasets : Array(),}, options: {}}, React.createRef()], + ], + } + 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>, + label: string, yAxisID : string, + color : string = "") : Record => { + return { + data: data, showLine: true, label: label, yAxisID: yAxisID, + fill: false, pointRadius: commonPointRadius, pointHitRadius: 5, + borderColor: color + }; + + } + + for(let i=0; i { + 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( <> - +

Impact Charts

+ {this.chartConfigs.impact.map((value, i) => { + return (); + })} ); } + componentDidMount(){ + //console.log(this, defaults); + } } export default ChartGroup; \ No newline at end of file diff --git a/src/ShellForms.tsx b/src/ShellForms.tsx index 91d7aca..ef9e965 100644 --- a/src/ShellForms.tsx +++ b/src/ShellForms.tsx @@ -85,7 +85,7 @@ class ShellParameters extends React.Component{ } interface shellFormsProps{ - index: number, keyProp: number, deleteShip : Function + index: number, colors: Array, keyProp: number, deleteShip : Function } class ShellForms extends React.Component { parameters = React.createRef() @@ -111,6 +111,7 @@ class ShellForms extends React.Component { const value = kv[1]; condensed[key] = value[1]; }) + condensed['colors'] = this.props.colors; return condensed; } nameForm = React.createRef() @@ -151,13 +152,13 @@ class ShellForms extends React.Component { render() { return( - - Shell {this.props.index + 1} + + Shell {this.props.index + 1} - @@ -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(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( <> @@ -241,7 +289,7 @@ class ShellFormsContainer extends React.Component{ {Array.from(this.state.keys).map((value, i) => { return - ; })} diff --git a/src/TargetForms.tsx b/src/TargetForms.tsx index e779f4e..7228710 100644 --- a/src/TargetForms.tsx +++ b/src/TargetForms.tsx @@ -111,7 +111,7 @@ class TargetFormsContainer extends React.Component handleValueChange={this.handleChange} type="number" label="Target Width" labelWidth={4} /> - + {angleElements.map((values, i) => { return ( @@ -125,7 +125,7 @@ class TargetFormsContainer extends React.Component - +