diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/components/graph/graph.tsx | 9 | ||||
-rw-r--r-- | app/components/tweaks/tweaks.tsx | 470 | ||||
-rw-r--r-- | app/screens/graph/graph-screen.tsx | 127 |
3 files changed, 323 insertions, 283 deletions
diff --git a/app/components/graph/graph.tsx b/app/components/graph/graph.tsx index 14e3b60..72b9eea 100644 --- a/app/components/graph/graph.tsx +++ b/app/components/graph/graph.tsx @@ -192,6 +192,10 @@ export const Graph = observer(function Graph(props: GraphProps): JSX.Element { nodeLabel={(node) => "label"} // nodeVal ={(node)=> node.childLinks.length * 0.5 + 1} //d3VelocityDecay={visco} + linkWidth={physics.linkWidth} + linkOpacity={physics.linkOpacity} + nodeRelSize={physics.nodeRel} + linkDirectionalParticleWidth={physics.particleWidth} /> ) : ( <ForceGraph3D @@ -207,8 +211,11 @@ export const Graph = observer(function Graph(props: GraphProps): JSX.Element { } onNodeClick={!physics.collapse ? null : handleNodeClick} nodeVal={(node) => node.childLinks.length + 1} - linkOpacity={0.8} //d3VelocityDecay={visco} + linkWidth={physics.linkWidth} + linkOpacity={physics.linkOpacity} + nodeRelSize={physics.nodeRel} + linkDirectionalParticleWidth={physics.particleWidth} /> )} </View> diff --git a/app/components/tweaks/tweaks.tsx b/app/components/tweaks/tweaks.tsx index d275a5b..6c207e9 100644 --- a/app/components/tweaks/tweaks.tsx +++ b/app/components/tweaks/tweaks.tsx @@ -34,260 +34,290 @@ export interface TweaksProps { */ export const Tweaks = observer(function Tweaks(props: TweaksProps): JSX.Element { const { style, physics, setPhysics } = props -// const styles = flatten([CONTAINER, style]) + // const styles = flatten([CONTAINER, style]) const content = [ { title: "Physics", content: - <View> - <Text preset="fieldLabel" text={"Repulsive force: " + physics.charge}/> - <Slider style={{height: 40 , width: "90%"}} - minimumValue={-400} - maximumValue={100} - onValueChange={(value) => { setPhysics({...physics, charge: value}) }} - value={physics.charge} - step={1}/> - <Text preset="fieldLabel" text={"Link Force: " + physics.linkStrength}/> - <Slider style={{height: 40 , width: "90%"}} - minimumValue={0} - maximumValue={2} - onValueChange={(value) => { setPhysics({...physics, linkStrength: value}) }} - value={physics.linkStrength} - step={0.1} - /> - <Text preset="fieldLabel" text={"'Link Iterations': " + physics.linkIts}/> - <Slider style={{ height: 40 , width: "90%"}} - minimumValue={1} - maximumValue={10} - onValueChange={(value) => { setPhysics({...physics, linkIts: value}) }} - value={physics.linkIts} - step={1}/> - <Text preset="fieldLabel" text="Collision"/> - <Switch style={{width: "5", height: 20, marginVertical: 10 }} - value={physics.collision} - onValueChange={()=>{setPhysics({...physics, collision: !physics.collision})}} - /> - </View>, + <View> + <Text preset="fieldLabel" text={"Repulsive force: " + physics.charge} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={-400} + maximumValue={100} + onValueChange={(value) => { setPhysics({ ...physics, charge: value }) }} + value={physics.charge} + step={1} /> + <Text preset="fieldLabel" text={"Link Force: " + physics.linkStrength} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={0} + maximumValue={2} + onValueChange={(value) => { setPhysics({ ...physics, linkStrength: value }) }} + value={physics.linkStrength} + step={0.1} + /> + <Text preset="fieldLabel" text={"'Link Iterations': " + physics.linkIts} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={1} + maximumValue={10} + onValueChange={(value) => { setPhysics({ ...physics, linkIts: value }) }} + value={physics.linkIts} + step={1} /> + <Text preset="fieldLabel" text="Collision" /> + <Switch style={{ width: "5", height: 20, marginVertical: 10 }} + value={physics.collision} + onValueChange={() => { setPhysics({ ...physics, collision: !physics.collision }) }} + /> + </View>, }, { title: 'Visual', content: - <View> - <Text preset="fieldLabel" text={"Particles: " + physics.particles}/> - <Slider style={{ height: 40 , width: "90%"}} - minimumValue={0} - maximumValue={5} - onValueChange={(value) => { setPhysics({...physics, particles: value}) }} - value={physics.particles} - step={1}/> - </View>, + <View> + <Text preset="fieldLabel" text={"Line Opacity: " + physics.linkOpacity} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={0} + maximumValue={1} + onValueChange={(value) => { setPhysics({ ...physics, linkOpacity: value }) }} + value={physics.linkOpacity} + step={.01} /> + <Text preset="fieldLabel" text={"Line width: " + physics.linkWidth} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={.1} + maximumValue={10} + onValueChange={(value) => { setPhysics({ ...physics, linkWidth: value }) }} + value={physics.linkWidth} + step={0.1} /> + <Text preset="fieldLabel" text={"Node size: " + physics.nodeRel} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={1} + maximumValue={10} + onValueChange={(value) => { setPhysics({ ...physics, nodeRel: value }) }} + value={physics.nodeRel} + step={.01} /> + <Text preset="fieldLabel" text={"Particles: " + physics.particles} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={0} + maximumValue={10} + onValueChange={(value) => { setPhysics({ ...physics, particles: value }) }} + value={physics.particles} + step={1} /> + <Text preset="fieldLabel" text={"Particle Size: " + physics.particleWidth} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={1} + maximumValue={10} + onValueChange={(value) => { setPhysics({ ...physics, particleWidth: value }) }} + value={physics.particleWidth} + step={.1} /> + </View>, }, { title: 'Modes', content: - <View> - <Text preset="fieldLabel" text="Expandable Graph"/> - <Switch style={{width: "5", height: 20, marginVertical: 10 }} - value={physics.collapse} - onValueChange={()=>{setPhysics({...physics, collapse: !physics.collapse})}} - /> - <Text preset="fieldLabel" text="3D"/> - <Switch style={{width: "5", height: 20, marginVertical: 10 }} - value={physics.threedim} - onValueChange={()=>{setPhysics({...physics, threedim: !physics.threedim})}} - /> - </View> + <View> + <Text preset="fieldLabel" text="Expandable Graph" /> + <Switch style={{ width: "5", height: 20, marginVertical: 10 }} + value={physics.collapse} + onValueChange={() => { setPhysics({ ...physics, collapse: !physics.collapse }) }} + /> + <Text preset="fieldLabel" text="3D" /> + <Switch style={{ width: "5", height: 20, marginVertical: 10 }} + value={physics.threedim} + onValueChange={() => { setPhysics({ ...physics, threedim: !physics.threedim }) }} + /> + </View> }, ]; const [activeSections, setActiveSections] = useState([]); const setSections = (sections) => { - setActiveSections( - sections.includes(undefined) ? [] : sections - ); - }; + setActiveSections( + sections.includes(undefined) ? [] : sections + ); + }; - const renderHeader = (section, _, isActive) => { - return ( - <Animatable.View - duration={400} - style={[styles.header, isActive ? styles.active : styles.inactive]} - transition="backgroundColor" - > - <Text style={styles.headerText}>{section.title}</Text> - </Animatable.View> - ); - }; + const renderHeader = (section, _, isActive) => { + return ( + <Animatable.View + duration={400} + style={[styles.header, isActive ? styles.active : styles.inactive]} + transition="backgroundColor" + > + <Text style={styles.headerText}>{section.title}</Text> + </Animatable.View> + ); + }; - const renderContent = (section, _, isActive) => { - return ( - <Animatable.View - duration={400} - style={[styles.content, isActive ? styles.active : styles.inactive]} - transition="backgroundColor" - > - {section.content} - </Animatable.View> - ); - } + const renderContent = (section, _, isActive) => { + return ( + <Animatable.View + duration={400} + style={[styles.content, isActive ? styles.active : styles.inactive]} + transition="backgroundColor" + > + {section.content} + </Animatable.View> + ); + } const [tweaks, setTweaks] = useState(true); if (true) { - if(tweaks){ - return( - <View style={styles.container}> - <View style={{height: 30, width: "100%", backgroundColor: "rgb(20,20,20)"}}> - <TouchableOpacity style={{width: 30, color: "#ffffff", textAlign: "center", marginLeft: "auto", padding: 5}} - onPress={()=>{setTweaks(false)}}> - <Icon name="close-circle" color="#ffffff" size={20}/> - </TouchableOpacity> - </View> - <ScrollView> - <Accordion - activeSections={activeSections} - sections={content} - touchAbleComponent={TouchableOpacity} - expandMultiple={true} - renderHeader = {renderHeader} - renderContent = {renderContent} - duration={200} - onChange={setSections} - renderAsFlatList={false} + if (tweaks) { + return ( + <View style={styles.container}> + <View style={{ height: 30, width: "100%", backgroundColor: "rgb(20,20,20)" }}> + <TouchableOpacity style={{ width: 30, color: "#ffffff", textAlign: "center", marginLeft: "auto", padding: 5 }} + onPress={() => { setTweaks(false) }}> + <Icon name="close-circle" color="#ffffff" size={20} /> + </TouchableOpacity> + </View> + <ScrollView> + <Accordion + activeSections={activeSections} + sections={content} + touchAbleComponent={TouchableOpacity} + expandMultiple={true} + renderHeader={renderHeader} + renderContent={renderContent} + duration={200} + onChange={setSections} + renderAsFlatList={false} - /> - </ScrollView> - </View> - ); + /> + </ScrollView> + </View> + ); } else { - return( + return ( <TouchableOpacity - onPress={()=>{setTweaks(true)}} - style={{position: "absolute", top: 50, left: 50, width: 30, color: "#ffffff", zIndex: 100}}> - <Icon name="cog" color="#ffffff" size={30}/> + onPress={() => { setTweaks(true) }} + style={{ position: "absolute", top: 50, left: 50, width: 30, color: "#ffffff", zIndex: 100 }}> + <Icon name="cog" color="#ffffff" size={30} /> </TouchableOpacity> ) } } else { - return ( - <View style={{position: "absolute", top: "5%", left: "5%", zIndex: 100, width: 300, backgroundColor: "#000000", padding: 20}}> - <Text preset="bold" text="Physics"/> - <Text preset="fieldLabel" text={"Repulsive force: " + physics.charge}/> - <Slider style={{height: 40 , width: "90%"}} - minimumValue={-400} - maximumValue={100} - onValueChange={(value) => { setPhysics({...physics, charge: value}) }} - value={physics.charge} - step={1}/> - <Text preset="fieldLabel" text={"Link Force: " + physics.linkStrength}/> - <Slider style={{height: 40 , width: "90%"}} - minimumValue={0} - maximumValue={2} - onValueChange={(value) => { setPhysics({...physics, linkStrength: value}) }} - value={physics.linkStrength} - step={0.1} + return ( + <View style={{ position: "absolute", top: "5%", left: "5%", zIndex: 100, width: 300, backgroundColor: "#000000", padding: 20 }}> + <Text preset="bold" text="Physics" /> + <Text preset="fieldLabel" text={"Repulsive force: " + physics.charge} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={-400} + maximumValue={100} + onValueChange={(value) => { setPhysics({ ...physics, charge: value }) }} + value={physics.charge} + step={1} /> + <Text preset="fieldLabel" text={"Link Force: " + physics.linkStrength} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={0} + maximumValue={2} + onValueChange={(value) => { setPhysics({ ...physics, linkStrength: value }) }} + value={physics.linkStrength} + step={0.1} /> - <Text preset="fieldLabel" text={"'Link Iterations': " + physics.linkIts}/> - <Slider style={{ height: 40 , width: "90%"}} - minimumValue={1} - maximumValue={10} - onValueChange={(value) => { setPhysics({...physics, linkIts: value}) }} - value={physics.linkIts} - step={1}/> - <Text preset="fieldLabel" text="Collision"/> - <Switch style={{width: "5", height: 20, marginVertical: 10 }} - value={physics.collision} - onValueChange={()=>{setPhysics({...physics, collision: !physics.collision})}} + <Text preset="fieldLabel" text={"'Link Iterations': " + physics.linkIts} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={1} + maximumValue={10} + onValueChange={(value) => { setPhysics({ ...physics, linkIts: value }) }} + value={physics.linkIts} + step={1} /> + <Text preset="fieldLabel" text="Collision" /> + <Switch style={{ width: "5", height: 20, marginVertical: 10 }} + value={physics.collision} + onValueChange={() => { setPhysics({ ...physics, collision: !physics.collision }) }} /> - <Text preset="bold" text="Visual"/> - <Text preset="fieldLabel" text={"Particles: " + physics.particles}/> - <Slider style={{ height: 40 , width: "90%"}} - minimumValue={0} - maximumValue={5} - onValueChange={(value) => { setPhysics({...physics, particles: value}) }} - value={physics.particles} - step={1}/> - <Text preset="bold" text="Modes"/> - <Text preset="fieldLabel" text="Expandable Graph"/> - <Switch style={{width: "5", height: 20, marginVertical: 10 }} - value={physics.collapse} - onValueChange={()=>{setPhysics({...physics, collapse: !physics.collapse})}} + <Text preset="bold" text="Visual" /> + <Text preset="fieldLabel" text={"Particles: " + physics.particles} /> + <Slider style={{ height: 40, width: "90%" }} + minimumValue={0} + maximumValue={5} + onValueChange={(value) => { setPhysics({ ...physics, particles: value }) }} + value={physics.particles} + step={1} /> + <Text preset="bold" text="Modes" /> + <Text preset="fieldLabel" text="Expandable Graph" /> + <Switch style={{ width: "5", height: 20, marginVertical: 10 }} + value={physics.collapse} + onValueChange={() => { setPhysics({ ...physics, collapse: !physics.collapse }) }} /> - <Text preset="fieldLabel" text="3D"/> - <Switch style={{width: "5", height: 20, marginVertical: 10 }} - value={physics.threedim} - onValueChange={()=>{setPhysics({...physics, threedim: !physics.threedim})}} + <Text preset="fieldLabel" text="3D" /> + <Switch style={{ width: "5", height: 20, marginVertical: 10 }} + value={physics.threedim} + onValueChange={() => { setPhysics({ ...physics, threedim: !physics.threedim }) }} /> - </View> - );} + </View> + ); + } }) -const styles = StyleSheet.create ({ - container: { - flex: 1, - backgroundColor: '#111111', - position: "absolute", - zIndex: 100, - left: 50, - top: 50, - width: 300, - borderRadius: 5, - borderStyle: "solid", - }, - title: { - textAlign: 'left', - fontSize: 22, - fontWeight: '300', - marginBottom: 20, - paddingLeft: 20, - }, - header: { - backgroundColor: '#111111', - padding: 10, - paddingBottom: 20, - textAlign: "left", - }, - headerText: { - textAlign: 'left', - paddingLeft: 30, - fontSize: 16, - fontWeight: '500', - }, - content: { - padding: 20, - backgroundColor: '#000000', - }, - active: { - backgroundColor: 'rgba(0,0,0,1)', - }, - inactive: { - backgroundColor: 'rgba(20,20,20,1)', - }, - selectors: { - marginBottom: 10, - flexDirection: 'row', - justifyContent: 'center', - }, - selector: { - backgroundColor: '#111111', - padding: 10, - }, - activeSelector: { - fontWeight: 'bold', - }, - selectTitle: { - fontSize: 14, - fontWeight: '500', - padding: 10, - }, - multipleToggle: { - flexDirection: 'row', - justifyContent: 'center', - marginVertical: 30, - alignItems: 'center', - }, - multipleToggle__title: { - fontSize: 16, - marginRight: 8, - }, +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#111111', + position: "absolute", + zIndex: 100, + left: 50, + top: 50, + width: 250, + borderRadius: 5, + borderStyle: "solid", + maxHeight: "70%", + }, + title: { + textAlign: 'left', + fontSize: 22, + fontWeight: '300', + marginBottom: 20, + paddingLeft: 20, + }, + header: { + backgroundColor: '#111111', + padding: 10, + paddingBottom: 20, + textAlign: "left", + }, + headerText: { + textAlign: 'left', + paddingLeft: 30, + fontSize: 16, + fontWeight: '500', + }, + content: { + padding: 20, + backgroundColor: '#000000', + }, + active: { + backgroundColor: 'rgba(0,0,0,1)', + }, + inactive: { + backgroundColor: 'rgba(20,20,20,1)', + }, + selectors: { + marginBottom: 10, + flexDirection: 'row', + justifyContent: 'center', + }, + selector: { + backgroundColor: '#111111', + padding: 10, + }, + activeSelector: { + fontWeight: 'bold', + }, + selectTitle: { + fontSize: 14, + fontWeight: '500', + padding: 10, + }, + multipleToggle: { + flexDirection: 'row', + justifyContent: 'center', + marginVertical: 30, + alignItems: 'center', + }, + multipleToggle__title: { + fontSize: 16, + marginRight: 8, + }, }); diff --git a/app/screens/graph/graph-screen.tsx b/app/screens/graph/graph-screen.tsx index e6fbc19..da3734a 100644 --- a/app/screens/graph/graph-screen.tsx +++ b/app/screens/graph/graph-screen.tsx @@ -9,7 +9,7 @@ import { color } from "../../theme" import { Graph } from "../../components" import { Tweaks } from "../../components" -import genRandomTree from "../../data/randomdata"; +import genRandomTree from "../../data/randomdata" import AsyncStorage from "@react-native-async-storage/async-storage" @@ -24,79 +24,82 @@ export const GraphScreen = observer(function GraphScreen() { // Pull in navigation via hook // const navigation = useNavigation() - const [charge, setCharge] = useState(-30); - const [collision, setCollision] = useState(false); - const [linkStrength, setLinkStrength] = useState(1); - const [linkIts, setLinkIts] = useState(1); - - const [physics, setPhysics] = useState({}); + const [charge, setCharge] = useState(-30) + const [collision, setCollision] = useState(false) + const [linkStrength, setLinkStrength] = useState(1) + const [linkIts, setLinkIts] = useState(1) + const [physics, setPhysics] = useState({}) + const physicsInit = { + charge: -30, + collision: false, + linkStrength: 1, + linkIts: 1, + collapse: false, + threedim: false, + particles: 2, + linkOpacity: 1, + linkWidth: 1, + particleWidth: 1, + nodeRel: 1, + } const getData = async () => { try { - const value = await AsyncStorage.getItem('@physics') - if (value !== null) { - return JSON.parse(value); + const value = await AsyncStorage.getItem("@physics") + if (value !== null || keys(value) === keys(physicsInit)) { + return JSON.parse(value) } else { - return ( - { - charge: -30, - collision: false, - linkStrength: 1, - linkIts: 1, - collapse: false, - threedim: false, - particles: 2, - }); + console.log(physicsInit) + return physicsInit } } catch (e) { - console.log(e); + console.log(e) } - }; + } - useEffect(() => { - getData() - .then(data => setPhysics(data)); - }, []); + useEffect(() => { + getData().then((data) => setPhysics(data)) + }, []) - const storeData = async (value) => { - try { - const jsonValue = JSON.stringify(value); - await AsyncStorage.setItem('@physics', jsonValue); - console.log("Writing " + jsonValue); - } catch(e) { - console.log(e); - } - } + const storeData = async (value) => { + try { + const jsonValue = JSON.stringify(value) + await AsyncStorage.setItem("@physics", jsonValue) + console.log("Writing " + jsonValue) + } catch (e) { + console.log(e) + } + } /* const [physics, setPhysics] = useState( -* { -* charge: -30, -* collision: false, -* linkStrength: 1, -* linkIts: 1, -* collapse: false, -* threedim: false, -* particles: 2, -* }); */ - useEffect(() => { - console.log("Physics changed"); - storeData(physics); - const test = getData(); - console.log(test); - }, [physics]); + * { + * charge: -30, + * collision: false, + * linkStrength: 1, + * linkIts: 1, + * collapse: false, + * threedim: false, + * particles: 2, + * }); */ + useEffect(() => { + if (timer) { + clearTimeout(timer) + console.log("clear timer") + } + const timer = setTimeout(() => { + console.log("Physics changed") + storeData(physics) + const test = getData() + console.log(test) + }, 1000) + return () => clearTimeout(timer) + }, [physics]) - const gData = genRandomTree(); + const gData = genRandomTree() return ( <Screen style={ROOT} preset="scroll"> - <Text preset="header" text="Graph" /> - <Tweaks - physics={physics} - setPhysics={setPhysics} - /> - <Graph - physics={physics} - gData={gData} - /> + <Tweaks physics={physics} setPhysics={setPhysics} /> + <Graph physics={physics} gData={gData} /> </Screen> - ); -}); + ) +}) |