Commit 0c587e36 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[Graph] graph doesn't flicker with createPortal

Well, it still does a bit because parent keeps rerendering but we can
manage that.
parent b9719ad8
...@@ -5,9 +5,10 @@ module Gargantext.Components.Graph ...@@ -5,9 +5,10 @@ module Gargantext.Components.Graph
-- ) -- )
where where
import Prelude (bind, discard, pure, ($), unit) import Prelude (bind, discard, pure, ($), unit)
import Data.Maybe (Maybe) import Data.Maybe (Maybe(..))
import Data.Nullable (null, Nullable) import Data.Nullable (notNull, null, Nullable)
import Data.Sequence as Seq import Data.Sequence as Seq
import DOM.Simple (createElement, setAttr)
import DOM.Simple.Console (log, log2) import DOM.Simple.Console (log, log2)
import DOM.Simple.Types (Element) import DOM.Simple.Types (Element)
import FFI.Simple (delay) import FFI.Simple (delay)
...@@ -36,6 +37,7 @@ type Props sigma forceatlas2 = ...@@ -36,6 +37,7 @@ type Props sigma forceatlas2 =
( elRef :: R.Ref (Nullable Element) ( elRef :: R.Ref (Nullable Element)
, forceAtlas2Settings :: forceatlas2 , forceAtlas2Settings :: forceatlas2
, graph :: Graph , graph :: Graph
, parentRef :: R.Ref (Nullable Element)
, sigmaSettings :: sigma , sigmaSettings :: sigma
, sigmaRef :: R.Ref Sigma , sigmaRef :: R.Ref Sigma
) )
...@@ -47,6 +49,22 @@ graphCpt :: forall s fa2. R.Component (Props s fa2) ...@@ -47,6 +49,22 @@ graphCpt :: forall s fa2. R.Component (Props s fa2)
graphCpt = R.hooksComponent "Graph" cpt graphCpt = R.hooksComponent "Graph" cpt
where where
cpt props _ = do cpt props _ = do
R.useEffect' $ do
el <- case R.readNullableRef props.elRef of
Just el -> do
pure el
Nothing -> do
let el = createElement "div"
setAttr el "style" "height: 95%"
setAttr el "id" "graph-cpt-root"
R.setRef props.elRef $ notNull $ el
pure el
case R.readNullableRef props.parentRef of
Nothing -> R2.addRootElement el
Just parentEl -> R2.appendChild parentEl el
pure unit
R.useEffectOnce $ do R.useEffectOnce $ do
log "[graphCpt] calling startSigmaEff" log "[graphCpt] calling startSigmaEff"
startSigmaEff props.elRef props.sigmaRef props.sigmaSettings props.forceAtlas2Settings props.graph startSigmaEff props.elRef props.sigmaRef props.sigmaSettings props.forceAtlas2Settings props.graph
...@@ -55,7 +73,12 @@ graphCpt = R.hooksComponent "Graph" cpt ...@@ -55,7 +73,12 @@ graphCpt = R.hooksComponent "Graph" cpt
log "[GraphCpt] cleaning up" log "[GraphCpt] cleaning up"
pure $ pure unit pure $ pure unit
pure $ RH.div { ref: props.elRef, style: {height: "95%"} } [] -- NOTE: This div is not empty after sigma initializes.
-- When we change state, we make it empty though.
--pure $ RH.div { ref: props.elRef, style: {height: "95%"} } []
pure $ case R.readNullableRef props.elRef of
Nothing -> RH.div {} []
Just el -> R.createPortal [] el
type SigmaSettings = type SigmaSettings =
( animationsTime :: Number ( animationsTime :: Number
......
...@@ -144,13 +144,16 @@ graphView elRef sigmaRef props = R.createElement el props [] ...@@ -144,13 +144,16 @@ graphView elRef sigmaRef props = R.createElement el props []
--memoCmp props1 props2 = props1.graphId == props2.graphId --memoCmp props1 props2 = props1.graphId == props2.graphId
el = R.hooksComponent "GraphView" cpt el = R.hooksComponent "GraphView" cpt
cpt {graphId, graph} _children = do cpt {graphId, graph} _children = do
parentRef <- R.useRef null
pure $ pure $
RH.div { id: "graph-view", className: "col-md-12" } RH.div { ref: parentRef, id: "graph-view", className: "col-md-12" }
[ [
Graph.graph { Graph.graph {
elRef elRef
, forceAtlas2Settings: Graph.forceAtlas2Settings , forceAtlas2Settings: Graph.forceAtlas2Settings
, graph , graph
, parentRef
, sigmaSettings: Graph.sigmaSettings , sigmaSettings: Graph.sigmaSettings
, sigmaRef: sigmaRef , sigmaRef: sigmaRef
} }
......
...@@ -13,6 +13,7 @@ import Data.Nullable (Nullable) ...@@ -13,6 +13,7 @@ import Data.Nullable (Nullable)
import Data.Sequence (Seq) import Data.Sequence (Seq)
import Data.Sequence as Seq import Data.Sequence as Seq
import Data.Traversable (traverse_) import Data.Traversable (traverse_)
import Data.Tuple (Tuple(..))
import Data.Tuple.Nested((/\)) import Data.Tuple.Nested((/\))
import Effect (Effect) import Effect (Effect)
import FFI.Simple (delay) import FFI.Simple (delay)
...@@ -230,13 +231,13 @@ startSigmaEff ref sigmaRef settings forceAtlas2Settings graph = do ...@@ -230,13 +231,13 @@ startSigmaEff ref sigmaRef settings forceAtlas2Settings graph = do
useForceAtlas2Eff sigma forceAtlas2Settings useForceAtlas2Eff sigma forceAtlas2Settings
Just sig -> do Just sig -> do
log "[startSigmaEff] sigma initialized already" log "[startSigmaEff] sigma initialized already"
isFARunning <- Sigma.isForceAtlas2Running sig --Sigma.swapRendererContainer ref sig
log2 "[startSigmaEff] isFARunning" isFARunning --dependOnContainer ref "[startSigmaEff] no container" $ Sigma.setRendererContainer sig
useCanvasRendererEff ref rSigma --useCanvasRendererEff ref rSigma
--useDataEff rSigma graph --useDataEff rSigma graph
--useForceAtlas2Eff rSigma forceAtlas2Settings --useForceAtlas2Eff rSigma forceAtlas2Settings
log "[startSigmaEff] refreshForceAtlas" log "[startSigmaEff] refreshForceAtlas"
Sigma.refreshForceAtlas sig --Sigma.refreshForceAtlas sig
--if isFARunning then --if isFARunning then
-- Sigma.restartForceAtlas2 sig -- Sigma.restartForceAtlas2 sig
--else --else
...@@ -314,9 +315,12 @@ handleForceAtlas2Pause sigmaRef (toggled /\ setToggled) = do ...@@ -314,9 +315,12 @@ handleForceAtlas2Pause sigmaRef (toggled /\ setToggled) = do
dependOnSigma sigma "[handleForceAtlas2Pause] sigma: Nothing" $ \s -> do dependOnSigma sigma "[handleForceAtlas2Pause] sigma: Nothing" $ \s -> do
log2 "[handleForceAtlas2Pause] mSigma: Just " s log2 "[handleForceAtlas2Pause] mSigma: Just " s
log2 "[handleForceAtlas2Pause] toggled: " toggled log2 "[handleForceAtlas2Pause] toggled: " toggled
case toggled of isFARunning <- Sigma.isForceAtlas2Running s
true -> Sigma.restartForceAtlas2 s log2 "[handleForceAtlas2Pause] isFARunning: " isFARunning
_ -> Sigma.stopForceAtlas2 s case Tuple toggled isFARunning of
Tuple true false -> Sigma.restartForceAtlas2 s
Tuple false true -> Sigma.stopForceAtlas2 s
_ -> pure unit
-- handle case when user pressed pause/start fa button before timeout fired -- handle case when user pressed pause/start fa button before timeout fired
--case R.readRef mFAPauseRef of --case R.readRef mFAPauseRef of
-- Nothing -> pure unit -- Nothing -> pure unit
......
...@@ -39,6 +39,12 @@ function killRenderer(left, right, sigma, renderer) { ...@@ -39,6 +39,12 @@ function killRenderer(left, right, sigma, renderer) {
return left(e); return left(e);
} }
} }
function getRendererContainer(sigma) {
return sigma.renderers[0].container;
}
function setRendererContainer(sigma, el) {
sigma.renderers[0].container = el;
}
function killSigma(left, right, sigma) { function killSigma(left, right, sigma) {
try { try {
sigma.kill() sigma.kill()
...@@ -69,6 +75,8 @@ exports._graphRead = graphRead; ...@@ -69,6 +75,8 @@ exports._graphRead = graphRead;
exports._refresh = refresh; exports._refresh = refresh;
exports._addRenderer = addRenderer; exports._addRenderer = addRenderer;
exports._killRenderer = killRenderer; exports._killRenderer = killRenderer;
exports._getRendererContainer = getRendererContainer;
exports._setRendererContainer = setRendererContainer;
exports._killSigma = killSigma exports._killSigma = killSigma
exports._clear = clear; exports._clear = clear;
exports._bind = bind; exports._bind = bind;
......
...@@ -2,11 +2,14 @@ module Gargantext.Hooks.Sigmax.Sigma where ...@@ -2,11 +2,14 @@ module Gargantext.Hooks.Sigmax.Sigma where
import Prelude import Prelude
import Data.Either (Either(..)) import Data.Either (Either(..))
import Data.Nullable (null) import Data.Nullable (notNull, null, Nullable)
import DOM.Simple.Console (log, log2)
import DOM.Simple.Types (Element)
import Effect (Effect, foreachE) import Effect (Effect, foreachE)
import Effect.Timer (setTimeout) import Effect.Timer (setTimeout)
import Effect.Uncurried (EffectFn1, mkEffectFn1, runEffectFn1, EffectFn2, runEffectFn2, EffectFn3, runEffectFn3, EffectFn4, runEffectFn4) import Effect.Uncurried (EffectFn1, mkEffectFn1, runEffectFn1, EffectFn2, runEffectFn2, EffectFn3, runEffectFn3, EffectFn4, runEffectFn4)
import Type.Row (class Union) import Type.Row (class Union)
import Reactix as R
foreign import data Sigma :: Type foreign import data Sigma :: Type
...@@ -75,6 +78,24 @@ foreign import _killRenderer ...@@ -75,6 +78,24 @@ foreign import _killRenderer
r r
(Either err Unit) (Either err Unit)
getRendererContainer :: Sigma -> Effect Element
getRendererContainer sigma = runEffectFn1 _getRendererContainer sigma
foreign import _getRendererContainer
:: EffectFn1 Sigma Element
swapRendererContainer :: R.Ref (Nullable Element) -> Sigma -> Effect Unit
swapRendererContainer ref sigma = do
el <- getRendererContainer sigma
log2 "[swapRendererContainer] el" el
R.setRef ref $ notNull el
setRendererContainer :: Sigma -> Element -> Effect Unit
setRendererContainer sigma el = runEffectFn2 _setRendererContainer sigma el
foreign import _setRendererContainer
:: EffectFn2 Sigma Element Unit
killSigma :: forall err. Sigma -> Effect (Either err Unit) killSigma :: forall err. Sigma -> Effect (Either err Unit)
killSigma = runEffectFn3 _killSigma Left Right killSigma = runEffectFn3 _killSigma Left Right
......
'use strict';
function addRootElement(rootElem) {
document.body.insertBefore(
rootElem,
document.body.lastElementChild.nextElementSibling
);
}
exports._addRootElement = addRootElement;
...@@ -9,11 +9,12 @@ import DOM.Simple as DOM ...@@ -9,11 +9,12 @@ import DOM.Simple as DOM
import DOM.Simple.Document (document) import DOM.Simple.Document (document)
import DOM.Simple.Event as DE import DOM.Simple.Event as DE
import DOM.Simple.Element as Element import DOM.Simple.Element as Element
import DOM.Simple.Types (class IsNode)
import Effect (Effect) import Effect (Effect)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect.Aff (Aff, launchAff, launchAff_, killFiber) import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Exception (error) import Effect.Exception (error)
import Effect.Uncurried (EffectFn1, mkEffectFn1, mkEffectFn2) import Effect.Uncurried (EffectFn1, runEffectFn1, mkEffectFn1, mkEffectFn2)
import FFI.Simple ((...), defineProperty, delay, args2, args3) import FFI.Simple ((...), defineProperty, delay, args2, args3)
import React (class ReactPropFields, Children, ReactClass, ReactElement) import React (class ReactPropFields, Children, ReactClass, ReactElement)
import React as React import React as React
...@@ -167,3 +168,12 @@ useReductor' r = useReductor r pure ...@@ -167,3 +168,12 @@ useReductor' r = useReductor r pure
render :: R.Element -> DOM.Element -> Effect Unit render :: R.Element -> DOM.Element -> Effect Unit
render e d = delay unit $ \_ -> pure $ R.reactDOM ... "render" $ args2 e d render e d = delay unit $ \_ -> pure $ R.reactDOM ... "render" $ args2 e d
addRootElement :: DOM.Element -> Effect Unit
addRootElement = runEffectFn1 _addRootElement
foreign import _addRootElement
:: EffectFn1 DOM.Element Unit
appendChild :: forall n m. IsNode n => IsNode m => n -> m -> Effect Unit
appendChild n c = delay unit $ \_ -> pure $ n ... "appendChild" $ [c]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment