Commit fa126ebf authored by James Laver's avatar James Laver

push for anoe

parent 41ea2a5c
...@@ -16,47 +16,36 @@ Institute of Paris Île-de-France (ISC-PIF) and its partners. ...@@ -16,47 +16,36 @@ Institute of Paris Île-de-France (ISC-PIF) and its partners.
## Development ## Development
### Installing dependencies ### System Dependencies
#### Debian * NodeJS (11+)
* Yarn (Recent)
* A webserver (anything that can serve a static directory will do)
#### NodeJS Installation
On debian testing, debian unstable or ubuntu:
##### Testing Distribution and above
```shell ```shell
sudo apt update && sudo apt install nodejs yarn sudo apt update && sudo apt install nodejs yarn
``` ```
##### Stable Distribution On debian stable:
```shell ```shell
curl -sL https://deb.nodesource.com/setup_11.x | sudo bash - curl -sL https://deb.nodesource.com/setup_11.x | sudo bash -
sudo apt update && sudo apt install nodejs sudo apt update && sudo apt install nodejs
``` ```
(For Ubuntu): On Mac OS (with Homebrew):
```shell
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
```
### OSX
```shell ```shell
brew install node yarn brew install node
``` ```
### Installing dependencies #### Yarn installation
#### Debian
##### Testing Distribution and above On ubuntu:
```shell
sudo apt update && sudo apt install nodejs yarn
```
##### Stable Distribution
```shell
curl -sL https://deb.nodesource.com/setup_11.x | sudo bash -
sudo apt update && sudo apt install nodejs
```
```shell ```shell
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
...@@ -64,35 +53,61 @@ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/source ...@@ -64,35 +53,61 @@ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/source
sudo apt update && sudo apt install yarn sudo apt update && sudo apt install yarn
``` ```
### OSX On Mac OS (with Homebrew):
```shell ```shell
brew install node yarn brew install yarn
``` ```
### Installing dependencies #### Webservers
Some options:
* The `python3` builtin webserver
* Caddy
Before building gargantext, you must install the dependencies. We use ### Purescript and Javascript dependencies
[yarn](https://yarnpkg.com/en/) for this. They have excellent
[installation instructions](https://yarnpkg.com/en/docs/install).
Once you have yarn installed, you may install everything else simply: Once you have node and yarn installed, you may install deps with:
```shell ```shell
yarn install && yarn install-ps yarn install && yarn install-ps
``` ```
You may now build: ### Development
You can compile the purescript code with:
```shell ```shell
yarn build yarn compile
``` ```
And run a repl: Or run a repl:
```shell ```shell
yarn repl yarn repl
``` ```
To test in the browser, you need to build a browser bundle:
```shell
yarn build
```
It is *not* necessary to `yarn compile` before running `yarn build`.
You can then serve the `dist` directory with your favourite webserver.
Examples:
* `python3 -m http.server dist`
<!-- To get a live-reloading development server -->
<!-- ```shell -->
<!-- yarn live -->
<!-- ``` -->
## Note to the contributors ## Note to the contributors
Please follow CONTRIBUTING.md Please follow CONTRIBUTING.md
...@@ -128,6 +143,8 @@ yarn rebuild-set ...@@ -128,6 +143,8 @@ yarn rebuild-set
yarn rebase-set && yarn rebuild-set yarn rebase-set && yarn rebuild-set
``` ```
This will occasionally result in swearing when you go on to build.
## Theory Introduction ## Theory Introduction
Making sense of out text isn't actually that hard, but it does require Making sense of out text isn't actually that hard, but it does require
......
module Gargantext.Components.Graph
-- ( graph, graphCpt
-- , sigmaSettings, SigmaSettings, SigmaOptionalSettings
-- , forceAtlas2Settings, ForceAtlas2Settings, ForceAtlas2OptionalSettings
-- )
where
import Prelude
import Control.Monad.Except.Trans
import Data.Array as A
import Data.Bitraversable (bitraverse)
import Data.Either (Either(..), either)
import Data.Maybe (Maybe(..), maybe)
import Data.Nullable (Nullable, null)
import Data.Sequence as Seq
import Data.Sequence (Seq)
import Data.Traversable (for, for_, traverse, traverse_)
import DOM.Simple.Types (Element)
import DOM.Simple.Console (log, log2)
import Effect (Effect)
import FFI.Simple (delay)
import Reactix as R
import Reactix.DOM.HTML as RH
import Gargantext.Utils.Reactix as R2
import Gargantext.Types (class Optional)
import Gargantext.Hooks.Sigmax
import Gargantext.Hooks.Sigmax.Types as Sigmax
import Gargantext.Hooks.Sigmax.Sigma (SigmaOpts)
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Sigmajs ()
type OnProps = ()
type Node =
( id :: String
, label :: String
, x :: Number
, y :: Number
, size :: Number
, color :: String )
type Edge = ( id :: String, source :: String, target :: String )
type Graph = Sigmax.Graph Node Edge
type Props sigma forceatlas2 =
( graph :: Graph
, sigmaSettings :: sigma
, forceAtlas2Settings :: forceatlas2 )
graph :: forall s fa2. Record (Props s fa2) -> R.Element
graph props = R.createElement graphCpt props []
graphCpt :: forall s fa2. R.Component (Props s fa2)
graphCpt = R.hooksComponent "Graph" cpt
where
cpt props _ = do
ref <- R.useRef null
sigma <- useSigma ref props.sigmaSettings
useCanvasRenderer ref sigma
useData sigma props.graph
useForceAtlas2 sigma props.forceAtlas2Settings
pure $ RH.div { ref, style: {height: "95%"} } []
type SigmaSettings =
( animationsTime :: Number
, autoRescale :: Boolean
, autoResize :: Boolean
, batchEdgesDrawing :: Boolean
, borderSize :: Number
-- , canvasEdgesBatchSize :: Number
-- , clone :: Boolean
-- , defaultEdgeColor :: String
-- , defaultEdgeHoverColor :: String
, defaultEdgeType :: String
, defaultHoverLabelBGColor :: String
, defaultHoverLabelColor :: String
, defaultLabelColor :: String
-- , defaultLabelHoverColor :: String
-- , defaultLabelSize :: String
, defaultNodeBorderColor :: String
, defaultNodeColor :: String
-- , defaultNodeHoverColor :: String
-- , defaultNodeType :: String
-- , doubleClickEnabled :: Boolean
-- , doubleClickTimeout :: Number
-- , doubleClickZoomDuration :: Number
-- , doubleClickZoomingRatio :: Number
-- , doubleTapTimeout :: Number
-- , dragTimeout :: Number
, drawEdgeLabels :: Boolean
, drawEdges :: Boolean
, drawLabels :: Boolean
, drawNodes :: Boolean
-- , edgeColor :: String
-- , edgeHoverColor :: String
-- , edgeHoverExtremities :: Boolean
-- , edgeHoverPrecision :: Number
-- , edgeHoverSizeRatio :: Number
-- , edgesPowRatio :: Number
-- , enableCamera :: Boolean
, enableEdgeHovering :: Boolean
, enableHovering :: Boolean
-- , eventsEnabled :: Boolean
, font :: String
, fontStyle :: String
, hideEdgesOnMove :: Boolean
-- , hoverFont :: String
-- , hoverFontStyle :: String
-- , immutable :: Boolean
-- , labelColor :: String
-- , labelHoverBGColor :: String
-- , labelHoverColor :: String
-- , labelHoverShadow :: String
-- , labelHoverShadowColor :: String
, labelMaxSize :: Number
, labelSize :: String
, labelSizeRatio :: Number
, labelThreshold :: Number
, maxEdgeSize :: Number
, maxNodeSize :: Number
-- , minArrowSize :: Number
, minEdgeSize :: Number
, minNodeSize :: Number
, mouseEnabled :: Boolean
-- , mouseInertiaDuration :: Number
-- , mouseInertiaRatio :: Number
-- , mouseWheelEnabled :: Boolean
, mouseZoomDuration :: Number
, nodeBorderColor :: String
-- , nodeHoverColor :: String
-- , nodesPowRatio :: Number
, rescaleIgnoreSize :: Boolean
-- , scalingMode :: String
-- , sideMargin :: Number
, singleHover :: Boolean
-- , skipErrors :: Boolean
, touchEnabled :: Boolean
-- , touchInertiaDuration :: Number
-- , touchInertiaRatio :: Number
, twBorderGreyColor :: String
, twEdgeDefaultOpacity :: Number
, twEdgeGreyColor :: String
, twNodeRendBorderColor :: String
, twNodeRendBorderSize :: Number
, twNodesGreyOpacity :: Number
, twSelectedColor :: String
, verbose :: Boolean
-- , webglEdgesBatchSize :: Number
-- , webglOversamplingRatio :: Number
, zoomMax :: Number
, zoomMin :: Number
, zoomingRatio :: Number
)
-- not selected <=> (1-greyness)
-- selected nodes <=> special label
sigmaSettings :: {|SigmaSettings}
sigmaSettings =
{ animationsTime: 5500.0
, autoRescale: true
, autoResize: true
, batchEdgesDrawing: false
, borderSize: 3.0 -- for ex, bigger border when hover
, defaultEdgeType: "curve" -- 'curve' or 'line' (curve iff ourRendering)
, defaultHoverLabelBGColor: "#fff"
, defaultHoverLabelColor: "#000"
, defaultLabelColor: "#000" -- labels text color
, defaultNodeBorderColor: "black" -- <- if nodeBorderColor = 'default'
, defaultNodeColor: "#ddd"
, drawEdgeLabels: true
, drawEdges: true
, drawLabels: true
, drawNodes: true
, enableEdgeHovering: false
, enableHovering: true
, font: "Droid Sans" -- font params
, fontStyle: "bold"
, hideEdgesOnMove: true
, labelMaxSize: 3.0 -- (old tina: showLabelsIfZoom)
, labelSize : "proportional"
, labelSizeRatio: 2.0 -- label size in ratio of node size
, labelThreshold: 2.0 -- min node cam size to start showing label
, maxEdgeSize: 0.0
, maxNodeSize: 30.0
, minEdgeSize: 0.0 -- in fact used in tina as edge size
, minNodeSize: 5.0
, mouseEnabled: true
, mouseZoomDuration: 150.0
, nodeBorderColor: "node" -- choices: 'default' color vs. node color
-- , nodesPowRatio: 0.3
, rescaleIgnoreSize: false
, singleHover: true
, touchEnabled: true
, twBorderGreyColor: "rgba(100, 100, 100, 0.5)"
, twEdgeDefaultOpacity: 0.4 -- initial opacity added to src/tgt colors
, twEdgeGreyColor: "rgba(100, 100, 100, 0.25)"
, twNodeRendBorderColor: "#222"
, twNodeRendBorderSize: 0.5 -- node borders (only iff ourRendering)
, twNodesGreyOpacity: 5.5 -- smaller value: more grey
, twSelectedColor: "default" -- "node" for a label bg like the node color, "default" for white background
, verbose : true
, zoomMax: 1.7
, zoomMin: 0.0
, zoomingRatio: 3.2
}
type ForceAtlas2Settings =
( adjustSizes :: Boolean
, barnesHutOptimize :: Boolean
-- , barnesHutTheta :: Number
, edgeWeightInfluence :: Number
-- , fixedY :: Boolean
, gravity :: Number
, iterationsPerRender :: Number
, linLogMode :: Boolean
, outboundAttractionDistribution :: Boolean
, scalingRatio :: Number
, skipHidden :: Boolean
, slowDown :: Number
, startingIterations :: Number
, strongGravityMode :: Boolean
-- , timeout :: Number
-- , worker :: Boolean
)
forceAtlas2Settings :: {|ForceAtlas2Settings}
forceAtlas2Settings =
{ adjustSizes : false
, barnesHutOptimize : true
, edgeWeightInfluence : 0.0
-- fixedY : false
, gravity : 1.0
, iterationsPerRender : 4.0
, linLogMode : true -- false
, outboundAttractionDistribution: false
, scalingRatio : 4.0
, skipHidden: false
, slowDown : 0.7
, startingIterations : 2.0
, strongGravityMode : false
}
...@@ -46,8 +46,8 @@ searchFieldComponent = R.memo (R.hooksComponent "SearchField" cpt) hasChanged ...@@ -46,8 +46,8 @@ searchFieldComponent = R.memo (R.hooksComponent "SearchField" cpt) hasChanged
where where
cpt props _ = do cpt props _ = do
let search = maybe defaultSearch identity (fst props.search) let search = maybe defaultSearch identity (fst props.search)
term <- R.useState $ \_ -> search.term term <- R.useState' search.term
db <- R.useState $ \_ -> Nothing db <- R.useState' Nothing
pure $ pure $
div { className: "search-field input-group" } div { className: "search-field input-group" }
[ databaseInput db props.databases [ databaseInput db props.databases
......
...@@ -31,7 +31,7 @@ endConfig = endConfig' V10 ...@@ -31,7 +31,7 @@ endConfig = endConfig' V10
endConfig' :: ApiVersion -> EndConfig endConfig' :: ApiVersion -> EndConfig
endConfig' v = { front : frontRelative endConfig' v = { front : frontRelative
, back : backLocal v , back : backDev v
, static : staticRelative , static : staticRelative
} }
-- , back : backDemo v } -- , back : backDemo v }
......
module Gargantext.Hooks.Sigmax
-- (
-- )
where
import Prelude
import Data.Array as A
import Data.Bitraversable (bitraverse)
import Data.Either (Either(..), either)
import Data.Foldable (sequence_)
import Data.Maybe (Maybe(..), maybe)
import Data.Nullable (Nullable, null)
import Data.Sequence as Seq
import Data.Sequence (Seq)
import Data.Traversable (for, for_, traverse, traverse_)
import DOM.Simple.Types (Element)
import DOM.Simple.Console (log, log2)
import Effect (Effect)
import FFI.Simple (delay)
import Reactix as R
import Reactix.DOM.HTML as RH
import Gargantext.Utils.Reactix as R2
import Gargantext.Types (class Optional)
import Gargantext.Hooks.Sigmax.Sigma (SigmaOpts)
import Gargantext.Hooks.Sigmax.Sigma as Sigma
import Gargantext.Hooks.Sigmax.Types
type Sigma =
{ sigma :: R.Ref (Maybe Sigma.Sigma)
, cleanup :: R.Ref (Seq (Effect Unit))
}
type Data n e = { graph :: R.Ref (Graph n e) }
readSigma :: Sigma -> Maybe Sigma.Sigma
readSigma sigma = R.readRef sigma.sigma
writeSigma :: Sigma -> Maybe Sigma.Sigma -> Effect Unit
writeSigma sigma = R.setRef sigma.sigma
-- | Pushes to the back of the cleanup sequence. Cleanup happens
-- | *before* sigma is destroyed
cleanupLast :: Sigma -> Effect Unit -> Effect Unit
cleanupLast sigma = R.setRef sigma.cleanup <<< Seq.snoc existing
where existing = R.readRef sigma.cleanup
-- | Pushes to the front of the cleanup sequence. Cleanup happens
-- | *before* sigma is destroyed
cleanupFirst :: Sigma -> Effect Unit -> Effect Unit
cleanupFirst sigma =
R.setRef sigma.cleanup <<< (flip Seq.cons) (R.readRef sigma.cleanup)
-- | Manages a sigma with the given settings
useSigma :: forall settings. R.Ref (Nullable Element) -> settings -> R.Hooks Sigma
useSigma container settings = do
sigma <- newSigma <$> R2.nothingRef <*> R.useRef Seq.empty
R.useEffect2 container sigma.sigma $
delay unit $ handleSigma sigma (readSigma sigma)
pure sigma
where
newSigma sigma cleanup = { sigma, cleanup }
handleSigma sigma (Just _) _ = pure R.nothing
handleSigma sigma Nothing _ = do
ret <- createSigma settings
traverse_ (writeSigma sigma <<< Just) ret
pure (cleanupSigma sigma "useSigma")
-- | Manages a renderer for the sigma
useCanvasRenderer :: R.Ref (Nullable Element) -> Sigma -> R.Hooks Unit
useCanvasRenderer container sigma =
R.useEffect2' container sigma.sigma $
delay unit $ \_ ->
dependOnContainer container containerNotFoundMsg withContainer
where
withContainer c = dependOnSigma sigma sigmaNotFoundMsg withSigma
where -- close over c
withSigma sig = addRenderer sig renderer >>= handle
where -- close over sig
renderer = { "type": "canvas", container: c }
handle (Right _) = cleanupFirst sigma (Sigma.killRenderer sig renderer >>= logCleanup)
handle (Left e) =
log2 errorAddingMsg e *> cleanupSigma sigma "useCanvasRenderer"
logCleanup (Left e) = log2 errorKillingMsg e
logCleanup _ = log killedMsg
containerNotFoundMsg = "[useCanvasRenderer] Container not found, not adding renderer"
sigmaNotFoundMsg = "[useCanvasRenderer] Sigma not found, not adding renderer"
errorAddingMsg = "[useCanvasRenderer] Error adding canvas renderer: "
errorKillingMsg = "[useCanvasRenderer] Error killing renderer:"
killedMsg = "[useCanvasRenderer] Killed renderer"
createSigma :: forall settings err. settings -> Effect (Either err Sigma.Sigma)
createSigma settings = do
ret <- Sigma.sigma {settings}
ret <$ logStatus ret
where
logStatus (Left err) = log2 "[useSigma] Error during sigma creation:" err
logStatus _ = log "[useSigma] Initialised sigma successfully"
cleanupSigma :: Sigma -> String -> Effect Unit
cleanupSigma sigma context = traverse_ kill (readSigma sigma)
where
kill sig = runCleanups *> killSigma *> emptyOut
where -- close over sig
killSigma = Sigma.killSigma sig >>= report
runCleanups = sequence_ (R.readRef sigma.cleanup)
emptyOut = writeSigma sigma Nothing *> R.setRef sigma.cleanup Seq.empty
report = either (log2 errorMsg) (\_ -> log successMsg)
prefix = "[" <> context <> "] "
errorMsg = prefix <> "Error killing sigma:"
successMsg = prefix <> "Killed sigma"
addRenderer :: forall err. Sigma.Sigma -> Renderer -> Effect (Either err Unit)
addRenderer sigma renderer = do
ret <- Sigma.addRenderer sigma renderer
(const unit <$> ret) <$ report ret
where
report = either (log2 errorMsg) (\_ -> log successMsg)
errorMsg = "[useRenderer] Error adding renderer:"
successMsg = "[useRenderer] Added renderer successfully"
useData :: forall n e. Sigma -> Graph n e -> R.Hooks Unit
useData sigma graph =
R.useEffect2' sigma.sigma graph $
delay unit $ \_ -> dependOnSigma sigma sigmaNotFoundMsg withSigma
where
withSigma sig = refreshData sig (sigmafy graph)
sigmaNotFoundMsg = "[useData] Sigma not found, not adding data"
refreshData :: forall n e. Sigma.Sigma -> Sigma.Graph n e -> Effect Unit
refreshData sigma graph
= log clearingMsg
*> Sigma.clear sigma
*> log readingMsg
*> Sigma.graphRead sigma graph
>>= either (log2 errorMsg) refresh
where
refresh _ = log refreshingMsg *> Sigma.refresh sigma
clearingMsg = "[useData] Clearing existing graph data"
readingMsg = "[useData] Reading graph data"
refreshingMsg = "[useData] Refreshing graph"
errorMsg = "[useData] Error reading graph data:"
sigmafy :: forall n e. Graph n e -> Sigma.Graph n e
sigmafy (Graph g) = {nodes,edges}
where
nodes = A.fromFoldable g.nodes
edges = A.fromFoldable g.edges
useForceAtlas2 :: forall settings. Sigma -> settings -> R.Hooks Unit
useForceAtlas2 sigma settings =
R.useEffect1' sigma.sigma (delay unit effect)
where
effect _ = dependOnSigma sigma sigmaNotFoundMsg withSigma
withSigma sig = do
log startingMsg
Sigma.startForceAtlas2 sig settings
cleanupFirst sigma (Sigma.killForceAtlas2 sig)
startingMsg = "[Graph] Starting ForceAtlas2"
sigmaNotFoundMsg = "[Graph] Sigma not found, not initialising"
dependOnSigma :: Sigma -> String -> (Sigma.Sigma -> Effect Unit) -> Effect Unit
dependOnSigma sigma notFoundMsg f = do
case readSigma sigma of
Nothing -> log notFoundMsg
Just sig -> f sig
dependOnContainer :: R.Ref (Nullable Element) -> String -> (Element -> Effect Unit) -> Effect Unit
dependOnContainer container notFoundMsg f = do
case R.readNullableRef container of
Nothing -> log notFoundMsg
Just c -> f c
'use strict';
const s = require('sigma').sigma;
if (typeof window === 'undefined') {
window.sigma = s;
}
function _sigma(left, right, opts) {
try {
return right(new sigma(opts));
} catch(e) {
return left(e);
}
}
function graphRead(left, right, sigma, data) {
try {
return right(sigma.graph.read(data));
} catch(e) {
return left(e);
}
}
function addRenderer(left, right, sigma, renderer) {
try {
return right(sigma.addRenderer(renderer));
} catch(e) {
return left(e);
}
}
function killRenderer(left, right, sigma, renderer) {
try {
sigma.killRenderer(renderer);
return right(sigma)
} catch(e) {
return left(e);
}
}
function killSigma(left, right, sigma) {
try {
sigma.kill()
return right(null)
} catch(e) {
return left(e);
}
}
exports._sigma = _sigma;
exports._graphRead = graphRead;
exports._refresh = function refresh(sigma) { sigma.refresh(); };
exports._addRenderer = addRenderer;
exports._killRenderer = killRenderer;
exports._killSigma = killSigma
exports._clear = function clear(sigma) { sigma.graph.clear(); };
exports._bind = function bind(sigma, event, handler) { sigma.bind(event, handler); };
exports._startForceAtlas2 = function startForceAtlas2(sigma, settings) {
sigma.startForceAtlas2(settings);
};
exports._stopForceAtlas2 = function stopForceAtlas2(sigma) { sigma.stopForceAtlas2(); };
exports._killForceAtlas2 = function killForceAtlas2(sigma) { sigma.killForceAtlas2(); };
module Gargantext.Hooks.Sigmax.Sigma where
import Prelude
import Type.Row (class Union)
import Data.Either (Either(..))
import Data.Unit (Unit)
import Effect (Effect)
import FFI.Simple.Objects (named)
import Effect.Uncurried (EffectFn1, mkEffectFn1, runEffectFn1, EffectFn2, runEffectFn2, EffectFn3, runEffectFn3, EffectFn4, runEffectFn4)
foreign import data Sigma :: Type
type NodeRequiredProps = ( id :: String )
type EdgeRequiredProps = ( id :: String, source :: String, target :: String )
class NodeProps (all :: #Type) (extra :: #Type) | all -> extra
class EdgeProps (all :: #Type) (extra :: #Type) | all -> extra
instance nodeProps
:: Union NodeRequiredProps extra all
=> NodeProps all extra
instance edgeProps
:: Union EdgeRequiredProps extra all
=> EdgeProps all extra
type Graph n e = { nodes :: Array {|n}, edges :: Array {|e} }
type SigmaOpts s = { settings :: s }
sigma :: forall opts err. SigmaOpts opts -> Effect (Either err Sigma)
sigma = runEffectFn3 _sigma Left Right
foreign import _sigma ::
forall a b opts err.
EffectFn3 (a -> Either a b)
(b -> Either a b)
(SigmaOpts opts)
(Either err Sigma)
graphRead :: forall node edge err. Sigma -> Graph node edge -> Effect (Either err Unit)
graphRead = runEffectFn4 _graphRead Left Right
foreign import _graphRead ::
forall a b data_ err.
EffectFn4 (a -> Either a b)
(b -> Either a b)
Sigma
data_
(Either err Unit)
refresh :: Sigma -> Effect Unit
refresh = runEffectFn1 _refresh
foreign import _refresh :: EffectFn1 Sigma Unit
addRenderer :: forall r err. Sigma -> r -> Effect (Either err Unit)
addRenderer = runEffectFn4 _addRenderer Left Right
foreign import _addRenderer
:: forall a b r err.
EffectFn4 (a -> Either a b)
(b -> Either a b)
Sigma
r
(Either err Unit)
killRenderer :: forall r err. Sigma -> r -> Effect (Either err Unit)
killRenderer = runEffectFn4 _killRenderer Left Right
foreign import _killRenderer
:: forall a b r err.
EffectFn4 (a -> Either a b)
(b -> Either a b)
Sigma
r
(Either err Unit)
killSigma :: forall err. Sigma -> Effect (Either err Unit)
killSigma = runEffectFn3 _killSigma Left Right
clear :: Sigma -> Effect Unit
clear = runEffectFn1 _clear
foreign import _clear :: EffectFn1 Sigma Unit
foreign import _killSigma
:: forall a b err.
EffectFn3 (a -> Either a b)
(b -> Either a b)
Sigma
(Either err Unit)
bind_ :: forall e. Sigma -> String -> (e -> Effect Unit) -> Effect Unit
bind_ s e h = runEffectFn3 _bind s e (mkEffectFn1 h)
foreign import _bind :: forall e. EffectFn3 Sigma String (EffectFn1 e Unit) Unit
startForceAtlas2 :: forall settings. Sigma -> settings -> Effect Unit
startForceAtlas2 = runEffectFn2 _startForceAtlas2
stopForceAtlas2 :: Sigma -> Effect Unit
stopForceAtlas2 = runEffectFn1 _stopForceAtlas2
killForceAtlas2 :: Sigma -> Effect Unit
killForceAtlas2 = runEffectFn1 _killForceAtlas2
foreign import _startForceAtlas2 :: forall s. EffectFn2 Sigma s Unit
foreign import _stopForceAtlas2 :: EffectFn1 Sigma Unit
foreign import _killForceAtlas2 :: EffectFn1 Sigma Unit
module Gargantext.Components.GraphExplorer.Sigmajs where module Gargantext.Hooks.Sigmax.Sigmajs where
import Prelude import Prelude
...@@ -10,7 +10,6 @@ import Effect.Uncurried (EffectFn1, EffectFn2, mkEffectFn1, runEffectFn1) ...@@ -10,7 +10,6 @@ import Effect.Uncurried (EffectFn1, EffectFn2, mkEffectFn1, runEffectFn1)
import React (Children, ReactClass, ReactElement, ReactRef, SyntheticEventHandler, createElement, unsafeCreateElement) import React (Children, ReactClass, ReactElement, ReactRef, SyntheticEventHandler, createElement, unsafeCreateElement)
import React.SyntheticEvent (SyntheticMouseEvent) import React.SyntheticEvent (SyntheticMouseEvent)
import Record.Unsafe (unsafeGet) import Record.Unsafe (unsafeGet)
import Thermite (EventHandler)
import Unsafe.Coerce (unsafeCoerce) import Unsafe.Coerce (unsafeCoerce)
import Gargantext.Types (class Optional) import Gargantext.Types (class Optional)
...@@ -51,22 +50,6 @@ randomizeNodePositions = createElement randomizeNodePositionsClass {} [] ...@@ -51,22 +50,6 @@ randomizeNodePositions = createElement randomizeNodePositionsClass {} []
relativeSize :: {initialSize :: Number } -> ReactElement relativeSize :: {initialSize :: Number } -> ReactElement
relativeSize props = unsafeCreateElement randomizeNodePositionsClass (unsafeCoerce props) [] relativeSize props = unsafeCreateElement randomizeNodePositionsClass (unsafeCoerce props) []
forceAtlas2 :: forall o. Optional o ForceAtlas2OptProps => { | o } -> ReactElement
forceAtlas2 props = unsafeCreateElement forceAtlas2Class props []
sigma :: forall props. Optional props SigmaProps => { | props} -> Array ReactElement -> ReactElement
sigma props children = unsafeCreateElement sigmaClass (unsafeCoerce props) children
sigmaEnableWebGL :: ReactElement
sigmaEnableWebGL = createElement sigmaEnableWebGLClass {} []
edgeShapes :: { "default" :: EdgeShape } -> ReactElement
edgeShapes props = unsafeCreateElement edgeShapesClass props []
nodeShapes :: { "default" :: NodeShape } -> ReactElement
nodeShapes props = unsafeCreateElement nodeShapesClass (unsafeCoerce props) []
foreign import data SigmaNode :: Type foreign import data SigmaNode :: Type
foreign import data SigmaEdge :: Type foreign import data SigmaEdge :: Type
foreign import data SigmaSettings :: Type foreign import data SigmaSettings :: Type
...@@ -110,10 +93,12 @@ type ForceLinkOptProps = ...@@ -110,10 +93,12 @@ type ForceLinkOptProps =
newtype Randomize = Randomize String newtype Randomize = Randomize String
randomize :: { globally :: Randomize randomize ::
, locally :: Randomize { globally :: Randomize
, no :: Randomize , locally :: Randomize
} , no :: Randomize
}
randomize = randomize =
{ globally : Randomize "globally" { globally : Randomize "globally"
, locally : Randomize "locally" , locally : Randomize "locally"
...@@ -140,26 +125,6 @@ sigmaEasing = ...@@ -140,26 +125,6 @@ sigmaEasing =
, cubicInOut : SigmaEasing "cubicInOut" , cubicInOut : SigmaEasing "cubicInOut"
} }
type ForceAtlas2OptProps =
( worker :: Boolean
, barnesHutOptimize :: Boolean
, barnesHutTheta :: Number
, adjustSizes :: Boolean
, iterationsPerRender :: Number
, linLogMode :: Boolean
, outboundAttractionDistribution :: Boolean
, edgeWeightInfluence :: Number
, scalingRatio :: Number
, strongGravityMode :: Boolean
, slowDown :: Number
, gravity :: Number
, timeout :: Number
, fixedY :: Boolean
, startingIterations :: Number
, skipHidden :: Boolean
)
type NOverlapOptProps = type NOverlapOptProps =
( nodes :: Array SigmaNode ( nodes :: Array SigmaNode
, nodeMargin :: Number , nodeMargin :: Number
...@@ -200,8 +165,6 @@ webgl = Renderer "webgl" ...@@ -200,8 +165,6 @@ webgl = Renderer "webgl"
canvas :: Renderer canvas :: Renderer
canvas = Renderer "canvas" canvas = Renderer "canvas"
newtype Color = Color String
newtype SigmaGraphData = SigmaGraphData newtype SigmaGraphData = SigmaGraphData
{ nodes :: Array SigmaNode { nodes :: Array SigmaNode
, edges :: Array SigmaEdge , edges :: Array SigmaEdge
...@@ -211,7 +174,7 @@ type SigmaNodeOptProps = ...@@ -211,7 +174,7 @@ type SigmaNodeOptProps =
( x :: Number ( x :: Number
, y :: Number , y :: Number
, size :: Number , size :: Number
, color :: Color , color :: String
, label :: String , label :: String
) )
...@@ -221,7 +184,7 @@ type SigmaNodeReqProps o = ...@@ -221,7 +184,7 @@ type SigmaNodeReqProps o =
} }
type SigmaEdgeOptProps = type SigmaEdgeOptProps =
( color :: Color ( color :: String
, label :: String , label :: String
, "type" :: String , "type" :: String
) )
...@@ -245,9 +208,6 @@ sigmaEdge = unsafeCoerce ...@@ -245,9 +208,6 @@ sigmaEdge = unsafeCoerce
-- sn_ex01 :: SigmaNode -- sn_ex01 :: SigmaNode
-- sn_ex01 = sigmaNode { id : "", label : ""} -- sn_ex01 = sigmaNode { id : "", label : ""}
sigmaSettings :: forall o. Optional o SigmaSettingProps => { | o } -> SigmaSettings
sigmaSettings = unsafeCoerce
foreign import data SigmaStyle :: Type foreign import data SigmaStyle :: Type
type CameraProps = type CameraProps =
...@@ -338,104 +298,3 @@ nodeShape = ...@@ -338,104 +298,3 @@ nodeShape =
, square : NodeShape "square" , square : NodeShape "square"
} }
newtype ScalingMode = ScalingMode String
scalingMode :: { inside :: ScalingMode
, outside :: ScalingMode
}
scalingMode =
{ inside : ScalingMode "inside"
, outside : ScalingMode "outside"
}
type SigmaSettingProps =
( clone :: Boolean
, immutable :: Boolean
, verbose :: Boolean
, defaultNodeType :: String
, defaultEdgeType :: String
, defaultLabelColor :: String
, defaultEdgeCOlor :: String
, defaultNodeColor :: String
, defaultLabelSize :: String
, edgeColor :: String
, minArrowSize :: Number
, font :: String
, fontStyle :: String
, labelColor :: String
, labelSize :: String
, labelSizeRatio :: Number
, labelThreshold :: Number
, labelMaxSize :: Number
, webglOversamplingRatio :: Number
, borderSize :: Number
, nodeBorderColor :: String
, defaultNodeBorderColor :: String
, hoverFont :: String
, hoverFontStyle :: String
, labelHoverShadow :: String
, labelHoverShadowColor :: String
, nodeHoverColor :: String
, defaultNodeHoverColor :: String
, labelHoverBGColor :: String
, defaultHoverLabelBGColor :: String
, defaultHoverLabelColor :: String
, labelHoverColor :: String
, defaultLabelHoverColor :: String
, singleHover :: Boolean
, edgeHoverColor :: String
, defaultEdgeHoverColor :: String
, edgeHoverSizeRatio :: Number
, edgeHoverExtremities :: Boolean
, drawLabels :: Boolean
, drawEdgeLabels :: Boolean
, drawEdges :: Boolean
, drawNodes :: Boolean
, batchEdgesDrawing :: Boolean
, canvasEdgesBatchSize :: Number
, webglEdgesBatchSize :: Number
, hideEdgesOnMove :: Boolean
, scalingMode :: ScalingMode
, sideMargin :: Number
, minEdgeSize :: Number
, maxEdgeSize :: Number
, minNodeSize :: Number
, maxNodeSize :: Number
, touchEnabled :: Boolean
, mouseEnabled :: Boolean
, mouseWheelEnabled :: Boolean
, doubleClickEnabled :: Boolean
, eventsEnabled :: Boolean
, zoomingRatio :: Number
, doubleClickZoomingRatio :: Number
, zoomMin :: Number
, zoomMax :: Number
, mouseZoomDuration :: Number
, doubleClickZoomDuration :: Number
, mouseInertiaDuration :: Number
, mouseInertiaRatio :: Number
, touchInertiaDuration :: Number
, touchInertiaRatio :: Number
, doubleClickTimeout :: Number
, doubleTapTimeout :: Number
, dragTimeout :: Number
, autoResize :: Boolean
, autoRescale :: Boolean
, enableCamera :: Boolean
, enableHovering :: Boolean
, enableEdgeHovering :: Boolean
, edgeHoverPrecision :: Number
, rescaleIgnoreSize :: Boolean
, skipErrors :: Boolean
, nodesPowRatio :: Number
, edgesPowRatio :: Number
, animationsTime :: Number
, twNodeRendBorderSize :: Number
, twNodeRendBorderColor :: String
, twEdgeDefaultOpacity :: Number
, twSelectedColor :: String
, twNodesGreyOpacity :: Number
, twBorderGreyColor :: String
, twEdgeGreyColor :: String
)
module Gargantext.Hooks.Sigmax.Types where
import Data.Maybe (Maybe)
import Data.Sequence as Seq
import Data.Sequence (Seq)
import Reactix as R
import DOM.Simple.Types (Element)
newtype Graph n e = Graph { nodes :: Seq {|n}, edges :: Seq {|e} }
type Renderer = { "type" :: String, container :: Element }
...@@ -4,7 +4,9 @@ import Effect.Unsafe (unsafePerformEffect) ...@@ -4,7 +4,9 @@ import Effect.Unsafe (unsafePerformEffect)
import Gargantext.Prelude hiding (max,min) import Gargantext.Prelude hiding (max,min)
import Control.Monad.Cont.Trans (lift) import Control.Monad.Cont.Trans (lift)
import Data.Array (fold, length, mapWithIndex, (!!), null) import Data.Array (fold, length, (!!), null)
import Data.FoldableWithIndex (foldMapWithIndex)
import Data.Foldable (foldMap)
import Data.Int (toNumber) import Data.Int (toNumber)
import Data.Int as Int import Data.Int as Int
import Data.Lens (Lens', over, (%~), (.~), (^.)) import Data.Lens (Lens', over, (%~), (.~), (^.))
...@@ -12,6 +14,7 @@ import Data.Lens.Record (prop) ...@@ -12,6 +14,7 @@ import Data.Lens.Record (prop)
import Data.Maybe (Maybe(..), fromJust) import Data.Maybe (Maybe(..), fromJust)
import Data.Newtype (class Newtype) import Data.Newtype (class Newtype)
import Data.Number as Num import Data.Number as Num
import Data.Sequence as Seq
import Data.Set (Set) import Data.Set (Set)
import Data.Set as Set import Data.Set as Set
import Data.Symbol (SProxy(..)) import Data.Symbol (SProxy(..))
...@@ -19,16 +22,19 @@ import Data.Traversable (for_) ...@@ -19,16 +22,19 @@ import Data.Traversable (for_)
import Effect (Effect) import Effect (Effect)
import Effect.Aff (Aff) import Effect.Aff (Aff)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.Components.GraphExplorer.Sigmajs (Color(Color), SigmaEasing, SigmaGraphData(SigmaGraphData), SigmaNode, SigmaSettings, canvas, edgeShape, edgeShapes, forceAtlas2, setSigmaRef, getSigmaRef, cameras, CameraProps, getCameraProps, goTo, pauseForceAtlas2, sStyle, sigmaOnMouseMove, sigma, sigmaEasing, sigmaEdge, sigmaEnableWebGL, sigmaNode, sigmaSettings) import Gargantext.Hooks.Sigmax.Types as Sigmax
import Gargantext.Hooks.Sigmax.Sigmajs (CameraProps, SigmaEasing, SigmaNode, cameras, getCameraProps, getSigmaRef, goTo, pauseForceAtlas2, sigmaEasing, sigmaOnMouseMove)
import Gargantext.Components.GraphExplorer.Types (Cluster(..), MetaData(..), Edge(..), GraphData(..), Legend(..), Node(..), getLegendData) import Gargantext.Components.GraphExplorer.Types (Cluster(..), MetaData(..), Edge(..), GraphData(..), Legend(..), Node(..), getLegendData)
import Gargantext.Components.Login.Types (AuthData(..), TreeId) import Gargantext.Components.Login.Types (AuthData(..), TreeId)
import Gargantext.Components.RandomText (words) import Gargantext.Components.RandomText (words)
import Gargantext.Components.Graph as Graph
import Gargantext.Components.Tree as Tree import Gargantext.Components.Tree as Tree
import Gargantext.Config as Config import Gargantext.Config as Config
import Gargantext.Config.REST (get) import Gargantext.Config.REST (get)
import Gargantext.Pages.Corpus.Graph.Tabs as GT import Gargantext.Pages.Corpus.Graph.Tabs as GT
import Gargantext.Types (class Optional) import Gargantext.Types (class Optional)
import Gargantext.Utils (toggleSet) import Gargantext.Utils (toggleSet)
import Gargantext.Utils.Reactix (scuff)
import Partial.Unsafe (unsafePartial) import Partial.Unsafe (unsafePartial)
import React (ReactElement) import React (ReactElement)
import React.DOM (button, div, input, li, li', menu, p, span, text, ul') import React.DOM (button, div, input, li, li', menu, p, span, text, ul')
...@@ -68,32 +74,32 @@ _cursorSize = prop (SProxy :: SProxy "cursorSize") ...@@ -68,32 +74,32 @@ _cursorSize = prop (SProxy :: SProxy "cursorSize")
_multiNodeSelection :: forall s a. Lens' { multiNodeSelection :: a | s } a _multiNodeSelection :: forall s a. Lens' { multiNodeSelection :: a | s } a
_multiNodeSelection = prop (SProxy :: SProxy "multiNodeSelection") _multiNodeSelection = prop (SProxy :: SProxy "multiNodeSelection")
-- _settings :: forall s t a b. Lens { settings :: a | s } { settings :: b | t } a b -- _sigmaSettings :: forall s t a b. Lens { settings :: a | s } { settings :: b | t } a b
_settings :: forall s a. Lens' { settings :: a | s } a _sigmaSettings :: forall s a. Lens' { sigmaSettings :: a | s } a
_settings = prop (SProxy :: SProxy "settings") _sigmaSettings = prop (SProxy :: SProxy "sigmaSettings")
_labelSizeRatio' :: forall s a. Lens' { labelSizeRatio :: a | s } a _labelSizeRatio' :: forall s a. Lens' { labelSizeRatio :: a | s } a
_labelSizeRatio' = prop (SProxy :: SProxy "labelSizeRatio") _labelSizeRatio' = prop (SProxy :: SProxy "labelSizeRatio")
_labelSizeRatio :: Lens' SigmaSettings Number _labelSizeRatio :: Lens' {|Graph.SigmaSettings} Number
_labelSizeRatio f = unsafeCoerce $ _labelSizeRatio' f _labelSizeRatio f = unsafeCoerce $ _labelSizeRatio' f
_maxNodeSize' :: forall s a. Lens' { maxNodeSize :: a | s} a _maxNodeSize' :: forall s a. Lens' { maxNodeSize :: a | s} a
_maxNodeSize' = prop (SProxy :: SProxy "maxNodeSize") _maxNodeSize' = prop (SProxy :: SProxy "maxNodeSize")
_maxNodeSize :: Lens' SigmaSettings Number _maxNodeSize :: Lens' {|Graph.SigmaSettings} Number
_maxNodeSize f = unsafeCoerce $ _maxNodeSize' f _maxNodeSize f = unsafeCoerce $ _maxNodeSize' f
_minNodeSize' :: forall s a. Lens' { minNodeSize :: a | s} a _minNodeSize' :: forall s a. Lens' { minNodeSize :: a | s} a
_minNodeSize' = prop (SProxy :: SProxy "minNodeSize") _minNodeSize' = prop (SProxy :: SProxy "minNodeSize")
_minNodeSize :: Lens' SigmaSettings Number _minNodeSize :: Lens' {|Graph.SigmaSettings} Number
_minNodeSize f = unsafeCoerce $ _minNodeSize' f _minNodeSize f = unsafeCoerce $ _minNodeSize' f
_drawEdges' :: forall s a. Lens' { drawEdges :: a | s} a _drawEdges' :: forall s a. Lens' { drawEdges :: a | s} a
_drawEdges' = prop (SProxy :: SProxy "drawEdges") _drawEdges' = prop (SProxy :: SProxy "drawEdges")
_drawEdges :: Lens' SigmaSettings Boolean _drawEdges :: Lens' {|Graph.SigmaSettings} Boolean
_drawEdges f = unsafeCoerce $ _drawEdges' f _drawEdges f = unsafeCoerce $ _drawEdges' f
numberTargetValue :: SyntheticUIEvent -> Number numberTargetValue :: SyntheticUIEvent -> Number
...@@ -104,7 +110,7 @@ numberTargetValue e = ...@@ -104,7 +110,7 @@ numberTargetValue e =
newtype State = State newtype State = State
{ graphData :: GraphData { graphData :: GraphData
, filePath :: String , filePath :: String
, sigmaGraphData :: Maybe SigmaGraphData , sigmaGraphData :: Maybe Graph.Graph
, legendData :: Array Legend , legendData :: Array Legend
, selectedNodes :: Set SelectedNode , selectedNodes :: Set SelectedNode
, cursorSize :: Number , cursorSize :: Number
...@@ -114,7 +120,7 @@ newtype State = State ...@@ -114,7 +120,7 @@ newtype State = State
, showTree :: Boolean , showTree :: Boolean
, corpusId :: Int , corpusId :: Int
, treeId :: Maybe TreeId , treeId :: Maybe TreeId
, settings :: SigmaSettings , sigmaSettings :: {|Graph.SigmaSettings}
} }
derive instance newtypeState :: Newtype State _ derive instance newtypeState :: Newtype State _
...@@ -133,7 +139,7 @@ initialState = State ...@@ -133,7 +139,7 @@ initialState = State
, showTree : false , showTree : false
, corpusId : 0 , corpusId : 0
, treeId : Nothing , treeId : Nothing
, settings : mySettings , sigmaSettings : Graph.sigmaSettings
} }
-- This one is not used: specOld is the one being used. -- This one is not used: specOld is the one being used.
...@@ -176,17 +182,17 @@ performAction (ToggleTree) _ (State state) = void do ...@@ -176,17 +182,17 @@ performAction (ToggleTree) _ (State state) = void do
performAction (ChangeLabelSize size) _ _ = performAction (ChangeLabelSize size) _ _ =
modifyState_ $ \(State s) -> modifyState_ $ \(State s) ->
State $ ((_settings <<< _labelSizeRatio) .~ size) s State $ ((_sigmaSettings <<< _labelSizeRatio) .~ size) s
performAction (ChangeNodeSize size) _ _ = performAction (ChangeNodeSize size) _ _ =
modifyState_ $ \(State s) -> modifyState_ $ \(State s) ->
s # _settings <<< _maxNodeSize .~ (size * 10.0) s # _sigmaSettings <<< _maxNodeSize .~ (size * 10.0)
# _settings <<< _minNodeSize .~ size # _sigmaSettings <<< _minNodeSize .~ size
# State # State
performAction DisplayEdges _ _ = performAction DisplayEdges _ _ =
modifyState_ $ \(State s) -> do modifyState_ $ \(State s) -> do
State $ ((_settings <<< _drawEdges) %~ not) s State $ ((_sigmaSettings <<< _drawEdges) %~ not) s
performAction ToggleMultiNodeSelection _ _ = performAction ToggleMultiNodeSelection _ _ =
modifyState_ $ \(State s) -> do modifyState_ $ \(State s) -> do
...@@ -201,23 +207,24 @@ performAction (ChangeCursorSize size) _ _ = ...@@ -201,23 +207,24 @@ performAction (ChangeCursorSize size) _ _ =
-- modifyState_ $ \() -> do -- modifyState_ $ \() -> do
-- State $ -- State $
convert :: GraphData -> SigmaGraphData
convert (GraphData r) = SigmaGraphData {nodes, edges} convert :: GraphData -> Graph.Graph
convert (GraphData r) = Sigmax.Graph {nodes, edges}
where where
nodes = mapWithIndex nodeFn r.nodes nodes = foldMapWithIndex nodeFn r.nodes
nodeFn i (Node n) = nodeFn i (Node n) =
sigmaNode Seq.singleton
{ id : n.id_ { id : n.id_
, size : toNumber n.size , size : toNumber n.size
, label : n.label , label : n.label
, x : n.x -- cos (toNumber i) , x : n.x -- cos (toNumber i)
, y : n.y -- sin (toNumber i) , y : n.y -- sin (toNumber i)
, color : intColor $ cDef n.attributes , color : intColor (cDef n.attributes)
} }
where where
cDef (Cluster {clustDefault}) = clustDefault cDef (Cluster {clustDefault}) = clustDefault
edges = map edgeFn r.edges edges = foldMap edgeFn r.edges
edgeFn (Edge e) = sigmaEdge {id : e.id_, source : e.source, target : e.target} edgeFn (Edge e) = Seq.singleton {id : e.id_, source : e.source, target : e.target}
{-- {--
render :: Render State {} Action render :: Render State {} Action
render d p (State {sigmaGraphData, settings, legendData}) c = render d p (State {sigmaGraphData, settings, legendData}) c =
...@@ -246,110 +253,17 @@ render d p (State {sigmaGraphData, settings, legendData}) c = ...@@ -246,110 +253,17 @@ render d p (State {sigmaGraphData, settings, legendData}) c =
-- [dispLegend legendData] -- [dispLegend legendData]
--} --}
forceAtlas2Config :: { slowDown :: Number
, startingIterations :: Number
, iterationsPerRender :: Number
, barnesHutOptimize :: Boolean defaultPalette :: Array String
, linLogMode :: Boolean defaultPalette = ["#5fa571","#ab9ba2","#da876d","#bdd3ff","#b399df","#ffdfed","#33c8f3","#739e9a","#caeca3","#f6f7e5","#f9bcca","#ccb069","#c9ffde","#c58683","#6c9eb0","#ffd3cf","#ccffc7","#52a1b0","#d2ecff","#99fffe","#9295ae","#5ea38b","#fff0b3","#d99e68"]
, edgeWeightInfluence :: Number
, gravity :: Number
, strongGravityMode :: Boolean
, scalingRatio :: Number
, skipHidden :: Boolean
, adjustSizes :: Boolean
, outboundAttractionDistribution :: Boolean
}
forceAtlas2Config = { -- fixedY : false
slowDown : 0.7
, startingIterations : 2.0
, iterationsPerRender : 4.0
, barnesHutOptimize : true
, linLogMode : true -- false
, edgeWeightInfluence : 0.0
, gravity : 1.0
, strongGravityMode : false
, scalingRatio : 4.0
, skipHidden: false
, adjustSizes : false
, outboundAttractionDistribution: false
}
mySettings :: SigmaSettings
mySettings = sigmaSettings { verbose : true
, drawLabels: true
, drawEdgeLabels: true
, drawEdges: true
, drawNodes: true
, labelSize : "proportional"
--, nodesPowRatio: 0.3
, batchEdgesDrawing: false
, hideEdgesOnMove: true
, enableHovering: true
, singleHover: true
, enableEdgeHovering: false
, autoResize: true
, autoRescale: true
, rescaleIgnoreSize: false
, mouseEnabled: true
, touchEnabled: true
, animationsTime: (5500.0)
, defaultNodeColor: "#ddd"
, twNodeRendBorderSize: 0.5 -- node borders (only iff ourRendering)
, twNodeRendBorderColor: "#222"
-- edges
, minEdgeSize: 0.0 -- in fact used in tina as edge size
, maxEdgeSize: 0.0
--, defaultEdgeType: "curve" -- 'curve' or 'line' (curve only iff ourRendering)
, twEdgeDefaultOpacity: 0.4 -- initial opacity added to src/tgt colors
, minNodeSize: 5.0
, maxNodeSize: 30.0
--
-- -- labels
, font: "Droid Sans" -- font params
, fontStyle: "bold"
, defaultLabelColor: "#000" -- labels text color
, labelSizeRatio: 2.0 -- label size in ratio of node size
, labelThreshold: 2.0 -- min node cam size to start showing label
, labelMaxSize: 3.0 -- (old tina: showLabelsIfZoom)
-- hovered nodes
, defaultHoverLabelBGColor: "#fff"
, defaultHoverLabelColor: "#000"
, borderSize: 3.0 -- for ex, bigger border when hover
, nodeBorderColor: "node" -- choices: 'default' color vs. node color
, defaultNodeBorderColor: "black" -- <- if nodeBorderColor = 'default'
-- selected nodes <=> special label
, twSelectedColor: "default" -- "node" for a label bg like the node color, "default" for white background
-- not selected <=> (1-greyness)
, twNodesGreyOpacity: 5.5 -- smaller value: more grey
, twBorderGreyColor: "rgba(100, 100, 100, 0.5)"
, twEdgeGreyColor: "rgba(100, 100, 100, 0.25)"
, zoomMin: 0.0
, zoomMax: 1.7
, zoomingRatio: 3.2
, mouseZoomDuration: 150.0
}
defaultPalette :: Array Color
defaultPalette = map Color defaultPalette'
defaultPalette' :: Array String
defaultPalette' = ["#5fa571","#ab9ba2","#da876d","#bdd3ff","#b399df","#ffdfed","#33c8f3","#739e9a","#caeca3","#f6f7e5","#f9bcca","#ccb069","#c9ffde","#c58683","#6c9eb0","#ffd3cf","#ccffc7","#52a1b0","#d2ecff","#99fffe","#9295ae","#5ea38b","#fff0b3","#d99e68"]
-- clusterColor :: Cluster -> Color -- clusterColor :: Cluster -> Color
-- clusterColor (Cluster {clustDefault}) = unsafePartial $ fromJust $ defaultPalette !! (clustDefault `mod` length defaultPalette) -- clusterColor (Cluster {clustDefault}) = unsafePartial $ fromJust $ defaultPalette !! (clustDefault `mod` length defaultPalette)
intColor :: Int -> Color intColor :: Int -> String
intColor i = unsafePartial $ fromJust $ defaultPalette !! (i `mod` length defaultPalette) intColor i = unsafePartial $ fromJust $ defaultPalette !! (i `mod` length defaultPalette)
modCamera0 :: forall o. Optional o CameraProps => modCamera0 :: forall o. Optional o CameraProps =>
...@@ -423,7 +337,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -423,7 +337,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
render' :: Render State {} Action render' :: Render State {} Action
render' d _ (State st@{settings, graphData: GraphData {sides,metaData }}) _ = render' d _ (State st@{sigmaSettings, graphData: GraphData {sides,metaData }}) _ =
[ div [className "container-fluid", style {"padding-top" : "90px" }] [ div [className "container-fluid", style {"padding-top" : "90px" }]
[ {-div [ className "row"] [ {-div [ className "row"]
[ h2 [ style {textAlign : "center", position : "relative", top: "-1px"}] [ h2 [ style {textAlign : "center", position : "relative", top: "-1px"}]
...@@ -524,7 +438,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -524,7 +438,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
[ span [] [text "Labels"],input [_type "range" [ span [] [text "Labels"],input [_type "range"
, _id "labelSizeRange" , _id "labelSizeRange"
, max "4" , max "4"
, defaultValue <<< show $ settings ^. _labelSizeRatio , defaultValue <<< show $ sigmaSettings ^. _labelSizeRatio
, min "1" , min "1"
, onChange \e -> d $ ChangeLabelSize (numberTargetValue e) , onChange \e -> d $ ChangeLabelSize (numberTargetValue e)
] ]
...@@ -534,7 +448,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -534,7 +448,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
[ span [] [text "Nodes"],input [_type "range" [ span [] [text "Nodes"],input [_type "range"
, _id "nodeSizeRange" , _id "nodeSizeRange"
, max "15" , max "15"
, defaultValue <<< show $ settings ^. _minNodeSize , defaultValue <<< show $ sigmaSettings ^. _minNodeSize
, min "5" , min "5"
, onChange \e -> d $ ChangeNodeSize (numberTargetValue e) , onChange \e -> d $ ChangeNodeSize (numberTargetValue e)
] ]
...@@ -596,22 +510,19 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -596,22 +510,19 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
case st.sigmaGraphData of case st.sigmaGraphData of
Nothing -> [] Nothing -> []
Just graph -> Just graph ->
[ sigma { graph, settings let forceAtlas2Settings = Graph.forceAtlas2Settings in
, renderer : canvas let opts = { graph, sigmaSettings, forceAtlas2Settings } in
, style : sStyle { height : "95%"} [ scuff $ Graph.graph opts ]
, ref: setSigmaRef
, onClickNode : \e -> -- [ sigma { graph, settings
unsafePerformEffect $ do -- , style : sStyle { height : "95%"}
_ <- d $ ShowSidePanel true -- , onClickNode : \e ->
let {id, label} = (unsafeCoerce e).data.node -- unsafePerformEffect $ do
_ <- d $ SelectNode $ SelectedNode {id, label} -- _ <- d $ ShowSidePanel true
pure unit -- let {id, label} = (unsafeCoerce e).data.node
} -- _ <- d $ SelectNode $ SelectedNode {id, label}
[ sigmaEnableWebGL -- pure unit
, forceAtlas2 forceAtlas2Config -- ]
, edgeShapes {"default" : edgeShape.curve}
]
]
<> <>
if length st.legendData > 0 then [div [style {position : "absolute", bottom : "10px", border: "1px solid black", boxShadow : "rgb(0, 0, 0) 0px 2px 6px", marginLeft : "10px", padding: "16px"}] [dispLegend st.legendData]] else [] if length st.legendData > 0 then [div [style {position : "absolute", bottom : "10px", border: "1px solid black", boxShadow : "rgb(0, 0, 0) 0px 2px 6px", marginLeft : "10px", padding: "16px"}] [dispLegend st.legendData]] else []
] ]
...@@ -620,7 +531,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -620,7 +531,7 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
div [_id "sp-container", className "col-md-2", style {border : "1px white solid", backgroundColor : "white"}] div [_id "sp-container", className "col-md-2", style {border : "1px white solid", backgroundColor : "white"}]
[ div [className "row"] $ [ div [className "row"] $
-- , div [className "col-md-12"] -- , div [className "col-md-12"]
-- [ -- [a
-- ul [className "nav nav-tabs" -- ul [className "nav nav-tabs"
-- , _id "myTab" -- , _id "myTab"
-- , role "tablist" -- , role "tablist"
...@@ -715,7 +626,6 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render'] ...@@ -715,7 +626,6 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
] ]
] ]
getNodes :: Int -> Aff GraphData getNodes :: Int -> Aff GraphData
getNodes graphId = get $ Config.toUrl Config.Back Config.Graph $ Just graphId getNodes graphId = get $ Config.toUrl Config.Back Config.Graph $ Just graphId
......
...@@ -46,3 +46,9 @@ select = createDOMElement "select" ...@@ -46,3 +46,9 @@ select = createDOMElement "select"
effToggler :: forall e. R.State Boolean -> EffectFn1 e Unit effToggler :: forall e. R.State Boolean -> EffectFn1 e Unit
effToggler (_value /\ setValue) = mkEffectFn1 $ \e -> setValue not effToggler (_value /\ setValue) = mkEffectFn1 $ \e -> setValue not
nullRef :: forall t. R.Hooks (R.Ref (Nullable t))
nullRef = R.useRef null
nothingRef :: forall t. R.Hooks (R.Ref (Maybe t))
nothingRef = R.useRef Nothing
...@@ -3,7 +3,7 @@ module Gargantext.Components.NgramsTable.Spec where ...@@ -3,7 +3,7 @@ module Gargantext.Components.NgramsTable.Spec where
import Prelude import Prelude
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
import Gargantext.Components.NgramsTable (highlightNgrams, NgramsElement(..), NgramsTable(..)) import Gargantext.Components.NgramsTable.Core (highlightNgrams, NgramsElement(..), NgramsTable(..))
import Gargantext.Types (TermList(..)) import Gargantext.Types (TermList(..))
import Test.Spec (Spec, describe, it) import Test.Spec (Spec, describe, it)
import Test.Spec.Assertions (shouldEqual) import Test.Spec.Assertions (shouldEqual)
......
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