From 3b64c4170af8256d6601581dcac74f2a3bd6f0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Mon, 31 Jul 2023 22:54:29 +0200 Subject: [PATCH 1/2] Start working on graoh models docs --- docs/index.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/index.html b/docs/index.html index 2a0929d2..ab9d6855 100644 --- a/docs/index.html +++ b/docs/index.html @@ -262,11 +262,6 @@ depth: 6, hideOtherSidebarContent: false // whether or not to hide other sidebar content }, - timeUpdater: { - text: 'Last updated: {docsify-updated}', - formatUpdated: '{YYYY}-{MM}-{DD}', - whereToPlace: 'top' - }, copyCode: { buttonText: '' }, @@ -382,7 +377,6 @@ - From 15d22d63b392e427652eb9fba07eb217c516e5d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Tue, 1 Aug 2023 16:08:04 +0200 Subject: [PATCH 2/2] Start creating graph models pages --- docs/_sidebar.md | 10 + docs/pages/components/index.md | 2 + docs/pages/models/directed-graph.md | 11 + docs/pages/models/index.md | 15 ++ docs/pages/models/undirected-graph.md | 11 + src/examples/Graph.tsx | 209 +++++++++++------- .../StateMachine.ts | 13 +- .../MultiStepVertexFocusProvider/index.tsx | 5 +- 8 files changed, 187 insertions(+), 89 deletions(-) create mode 100644 docs/pages/models/directed-graph.md create mode 100644 docs/pages/models/undirected-graph.md diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 862e0da5..a2da9974 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -25,6 +25,16 @@ - [Example](pages/components/overlay/controls?id=example) - [Custom components](pages/components/overlay/custom) - [Graph models](pages/models/index) + - [DirectedGraph](pages/models/directed-graph) + - [Description](pages/models/directed-graph?id=description) + - [Usage](pages/models/directed-graph?id=usage) + - [Properties](pages/models/directed-graph?id=properties) + - [Example](pages/models/directed-graph?id=example) + - [UndirectedGraph](pages/models/undirected-graph) + - [Description](pages/models/undirected-graph?id=description) + - [Usage](pages/models/undirected-graph?id=usage) + - [Properties](pages/models/undirected-graph?id=properties) + - [Example](pages/models/undirected-graph?id=example) - [Settings](pages/settings/index) - [Graph components settings](pages/settings/components/index) - [Vertex](pages/settings/components/vertex) diff --git a/docs/pages/components/index.md b/docs/pages/components/index.md index 8b51bccd..8598d609 100644 --- a/docs/pages/components/index.md +++ b/docs/pages/components/index.md @@ -1,5 +1,7 @@ # Components +## Description + Graph components provide the core functionality of the library. Their main functionalities involve rendering the graph structure representation on the canvas, responding to user gestures and other interactions, as well as dynamically visualizing graph modifications. ## Available components diff --git a/docs/pages/models/directed-graph.md b/docs/pages/models/directed-graph.md new file mode 100644 index 00000000..b4e60442 --- /dev/null +++ b/docs/pages/models/directed-graph.md @@ -0,0 +1,11 @@ +# DirectedGraph + +## Description + +This model is used to create the **object** representing the **directed graph**. More details about [features](pages/models/index?id=features) can be found in [this](pages/models/index) page. + +## Usage + +## Properties + +## Example diff --git a/docs/pages/models/index.md b/docs/pages/models/index.md index b7b142c0..5a801d38 100644 --- a/docs/pages/models/index.md +++ b/docs/pages/models/index.md @@ -1 +1,16 @@ # Graph models + +## Description + +Graph models are **classes** used to **create objects modelling graphs**. They information about graph **vertices** and **edges** which connect them. + +Models also store graph-related **data**. Each graph **vertex** and **edge** can **hold data** which can be then used by the [custom renderer](pages/renderers/index) to **render** graph component with **desired appearance**. + +Graph models make it possible to **modify graph** (add/remove vertices/edges) **without** the necessity to **re-render** the whole graph structure. + +## Features + +## Available graph models + +- [DirectedGraph](pages/models/directed-graph) +- [UndirectedGraph](pages/models/undirected-graph) diff --git a/docs/pages/models/undirected-graph.md b/docs/pages/models/undirected-graph.md new file mode 100644 index 00000000..931f9594 --- /dev/null +++ b/docs/pages/models/undirected-graph.md @@ -0,0 +1,11 @@ +# UndirectedGraph + +## Description + +This model is used to create the **object** representing the **undirected graph**. More details about [features](pages/models/index?id=features) can be found in [this](pages/models/index) page. + +## Usage + +## Properties + +## Example diff --git a/src/examples/Graph.tsx b/src/examples/Graph.tsx index 7b3f593e..a1e9169d 100644 --- a/src/examples/Graph.tsx +++ b/src/examples/Graph.tsx @@ -1,105 +1,142 @@ -import { useMemo, useState } from 'react'; -import { StyleSheet, Text, View } from 'react-native'; -import { TouchableOpacity } from 'react-native-gesture-handler'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { StyleSheet } from 'react-native'; import { - DirectedGraphData, - DirectedGraph, - GraphView, + Easing, + useSharedValue, + withRepeat, + withSequence, + withTiming +} from 'react-native-reanimated'; + +import GraphViewControls from '@/components/controls/GraphViewControls'; +import GraphView from '@/components/views/GraphView'; +import { DirectedGraph } from '@/models/graphs'; + +import { + DefaultEdgeLabelRenderer, + DirectedEdgeData, DirectedGraphComponent, - DefaultEdgeLabelRenderer -} from 'react-native-smart-graph'; + FocusPoints, + FocusSettings, + ObjectFit, + VertexData, + VertexPressHandler +} from '..'; -const GRAPH: DirectedGraphData = { - vertices: [{ key: 'V1' }, { key: 'V2' }, { key: 'V3' }], +const FOCUS_SETTINGS: FocusSettings = { + alignment: { + horizontalAlignment: 'left', + horizontalOffset: 25 + }, + animation: { + duration: 250, + easing: Easing.inOut(Easing.ease) + }, + disableGestures: false, + vertexScale: 4 +}; + +const GRAPH: { + edges: DirectedEdgeData[]; + vertices: VertexData[]; +} = { edges: [ { key: 'E1', from: 'V1', to: 'V2' }, { key: 'E2', from: 'V1', to: 'V3' }, - { key: 'E3', from: 'V2', to: 'V3' }, - { key: 'E4', from: 'V3', to: 'V1' }, - { key: 'E5', from: 'V3', to: 'V2' }, - { key: 'E6', from: 'V3', to: 'V1' } - ] + { key: 'E3', from: 'V1', to: 'V4' } + ], + vertices: [{ key: 'V1' }, { key: 'V2' }, { key: 'V3' }, { key: 'V4' }] }; export default function Graph() { - const [scale, setScale] = useState(1); + const [objectFit, setObjectFit] = useState('contain'); + + const graph = useMemo(() => new DirectedGraph(), []); + const focusPoints = useMemo( + // TODO - add information in docs about useMemo + () => ({ + 0.25: { key: 'V1', vertexScale: 10 }, + 0.5: { + key: 'V2', + vertexScale: 2, + alignment: { horizontalAlignment: 'left', horizontalOffset: 25 } + }, + 0.8: { + key: 'V3', + alignment: { + verticalAlignment: 'top', + verticalOffset: 0, + horizontalAlignment: 'left', + horizontalOffset: 0 + } + } + }), + [] + ); - const graph = useMemo(() => new DirectedGraph(GRAPH), []); + const multiStepFocusProgress = useSharedValue(0); - const increaseScale = () => - setScale(prev => Math.min(Math.round(10 * prev + 2) / 10, 2)); - const decreaseScale = () => - setScale(prev => Math.max(Math.round(10 * prev - 2) / 10, 0.2)); + useEffect(() => { + graph.insertBatch(GRAPH); + }, [graph]); + + useEffect(() => { + multiStepFocusProgress.value = withRepeat( + withSequence( + withTiming(1, { duration: 5000, easing: Easing.linear }), + withTiming(0, { duration: 5000, easing: Easing.linear }) + ), + -1 + ); + }, []); + + const handleVertexLongPress = useCallback>( + ({ vertex: { key } }) => { + console.log('long press', key); + }, + [] + ); + + const handleVertexPress = useCallback>( + ({ vertex: { key } }) => { + graph.focus(key, FOCUS_SETTINGS); + }, + [graph] + ); return ( - <> - - - - {/* Helper overlay to change dimensions */} - - - - - - - {scale} - - + - - - - + + + + ); } const styles = StyleSheet.create({ - overlay: { - ...StyleSheet.absoluteFillObject, - justifyContent: 'flex-end', - pointerEvents: 'box-none' - }, - buttonsContainer: { - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center', - marginBottom: 50 - }, - button: { - backgroundColor: '#edcf46', - width: 40, - height: 40, - justifyContent: 'center', - borderRadius: 5 - }, - buttonText: { - fontSize: 30, - lineHeight: 30, - fontWeight: 'bold', - textAlign: 'center' - }, - radiusText: { - fontSize: 30, - color: '#fff', - fontWeight: 'bold', - width: 75, - textAlign: 'center' + controls: { + position: 'absolute', + top: 40, + right: 10 } }); diff --git a/src/providers/graph/transform/MultiStepVertexFocusProvider/StateMachine.ts b/src/providers/graph/transform/MultiStepVertexFocusProvider/StateMachine.ts index b2297179..b54c9596 100644 --- a/src/providers/graph/transform/MultiStepVertexFocusProvider/StateMachine.ts +++ b/src/providers/graph/transform/MultiStepVertexFocusProvider/StateMachine.ts @@ -14,8 +14,6 @@ import { updateTransitionPoints } from './utils'; -// TODO - add handling of cases when the transition was interrupted from outside - const focusStartState: StateHandler = props => { 'worklet'; const { @@ -218,6 +216,7 @@ const STATE_HANDLERS: Record = { }; type MachineContext = { + reset(): void; update( currentProgress: number, previousProgress: number, @@ -259,7 +258,16 @@ export const useStateMachine = ( return useMemo( () => ({ + // Resets the machine state + reset() { + 'worklet'; + // Trun off the focus without any transition + // focusContext.endFocus(null); + state.value = MachineState.BLUR; + targetKey.value = null; + }, state, + // Updates the state of the machine update( currentProgress, previousProgress, @@ -283,6 +291,7 @@ export const useStateMachine = ( targetKey, vertexRadius }); + console.log(result); } while (result !== state.value); state.value = result; } diff --git a/src/providers/graph/transform/MultiStepVertexFocusProvider/index.tsx b/src/providers/graph/transform/MultiStepVertexFocusProvider/index.tsx index f8f62f50..8a0b8c65 100644 --- a/src/providers/graph/transform/MultiStepVertexFocusProvider/index.tsx +++ b/src/providers/graph/transform/MultiStepVertexFocusProvider/index.tsx @@ -55,9 +55,11 @@ function MultiStepVertexFocusProvider({ const initialStep = useSharedValue(-1); const previousStep = useSharedValue(-1); - // State machine + // Used to ensure that the transition between the current graph + // position and the focus point is smooth const syncProgress = useSharedValue(0); + // State machine const stateMachine = useStateMachine( focusContext, canvasDataContext, @@ -73,6 +75,7 @@ function MultiStepVertexFocusProvider({ const updateInitialStep = useWorkletCallback( (progress: null | number, data: Array) => { + stateMachine.reset(); if (progress === null) { initialStep.value = -1; return;