SlideButton.purs 6.26 KB
Newer Older
arturo's avatar
arturo committed
1
module Gargantext.Components.GraphExplorer.Toolbar.SlideButton
2 3 4
  ( Props
  , sizeButton
  , labelSizeButton
5
  , labelRenderedSizeThresholdButton
6
  , mouseSelectorSizeSlider
7 8
  ) where

9 10
import Data.Array as A
import Data.Map as Map
11 12
import Data.Maybe (Maybe(..))
import Data.Number as DN
13
import Prelude
14
import Effect (Effect)
15 16
import Reactix as R
import Reactix.DOM.HTML as H
17
import Toestand as T
18

19
import Gargantext.Components.Bootstrap.Types (ComponentStatus(Disabled))
20 21
import Gargantext.Components.GraphExplorer.Types as GET
import Gargantext.Components.GraphExplorer.Utils as GEU
22
import Gargantext.Hooks.Sigmax as Sigmax
23
import Gargantext.Hooks.Sigmax.Graphology as Graphology
24
import Gargantext.Hooks.Sigmax.Sigma as Sigma
25
import Gargantext.Hooks.Sigmax.Types as SigmaxTypes
26 27
import Gargantext.Utils.Reactix as R2

28
here :: R2.Here
arturo's avatar
arturo committed
29
here = R2.here "Gargantext.Components.GraphExplorer.Toolbar.SlideButton"
30

31
type Props =
32 33 34 35 36 37
  ( caption         :: String
  , forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
  , min             :: Number
  , max             :: Number
  , onChange        :: forall e. e -> Effect Unit
  , state           :: T.Box Number
38
  )
39 40 41 42

sizeButton :: Record Props -> R.Element
sizeButton props = R.createElement sizeButtonCpt props []
sizeButtonCpt :: R.Component Props
43
sizeButtonCpt = here.component "sizeButton" cpt where
44
  cpt { state, caption, forceAtlasState, min, max, onChange } _ = do
45
    defaultValue <- T.useLive T.unequal state
46 47 48
    forceAtlasState' <- R2.useLive' forceAtlasState

    let status = SigmaxTypes.forceAtlasComponentStatus forceAtlasState'
arturo's avatar
arturo committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

    pure $

      H.span
      { className: "range-simple" }
      [
        H.label
        { className: "range-simple__label" }
        [ H.text caption ]
      ,
        H.span
        { className: "range-simple__field" }
        [
          H.input
          { type: "range"
          , min: show min
          , max: show max
          , defaultValue
          , on: { input: onChange }
          , className: "range-simple__input"
69
          , disabled: status == Disabled
arturo's avatar
arturo committed
70 71 72
          }
        ]
      ]
73

74 75
type LabelSizeButtonProps =
  ( forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
76
  , graph           :: T.Box SigmaxTypes.SGraph
77 78
  , sigmaRef        :: R.Ref Sigmax.Sigma
  , state           :: T.Box Number)
79 80 81 82 83 84

labelSizeButton :: R2.Leaf LabelSizeButtonProps
labelSizeButton = R2.leaf labelSizeButtonCpt
labelSizeButtonCpt :: R.Component LabelSizeButtonProps
labelSizeButtonCpt = here.component "labelSizeButton" cpt
  where
85 86 87 88 89 90 91
    cpt { forceAtlasState, graph, sigmaRef, state} _ = do
      graph' <- T.useLive T.unequal graph

      let minLabelSize = 1.0
      let maxLabelSize = 30.0
      let defaultLabelSize = 14.0

92 93 94 95
      pure $ sizeButton {
          state
        , caption: "Label size"
        , forceAtlasState
96 97
        , min: minLabelSize
        , max: maxLabelSize
98 99 100 101 102 103 104
        , onChange: \e -> do
          let sigma = R.readRef sigmaRef
          let newValue' = DN.fromString $ R.unsafeEventValue e
          case newValue' of
            Nothing -> pure unit
            Just newValue ->
              Sigmax.dependOnSigma sigma "[labelSizeButton] sigma: Nothing" $ \s -> do
105 106 107 108 109 110 111 112 113
                let ratio = (newValue - minLabelSize) / (defaultLabelSize - minLabelSize)
                let nodes = SigmaxTypes.graphNodes graph'
                let nodesResized = (\n@{ size } -> n { size = size * ratio }) <$> nodes
                let nodesMap = SigmaxTypes.idMap nodesResized
                Graphology.forEachNode (Sigma.graph s) $ \{ id } -> do
                  case Map.lookup id nodesMap of
                    Nothing -> pure unit
                    Just { size } -> Graphology.mergeNodeAttributes (Sigma.graph s) id { size }

114 115 116 117
                Sigma.setSettings s {
                    defaultLabelSize: newValue
                  , drawLabels: true
                  , labelSize: newValue
118
                  -- , maxNodeSize: newValue / 2.5
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
                    --, labelSizeRatio: newValue / 2.5
                  }
                T.write_ newValue state
        }

type LabelRenderedSizeThresholdButtonProps =
  ( forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
  , sigmaRef :: R.Ref Sigmax.Sigma
  , state    :: T.Box Number)

labelRenderedSizeThresholdButton :: R2.Leaf LabelRenderedSizeThresholdButtonProps
labelRenderedSizeThresholdButton = R2.leaf labelRenderedSizeThresholdButtonCpt
labelRenderedSizeThresholdButtonCpt :: R.Component LabelRenderedSizeThresholdButtonProps
labelRenderedSizeThresholdButtonCpt = here.component "labelRenderedSizeThresholdButton" cpt
  where
    cpt { forceAtlasState, sigmaRef, state} _ = do
      pure $ sizeButton {
        state
        , caption: "Label rendered size threshold"
        , forceAtlasState
        , min: 0.0
        , max: 10.0
        , onChange: \e -> do
          let sigma = R.readRef sigmaRef
          let newValue' = DN.fromString $ R.unsafeEventValue e
          case newValue' of
            Nothing -> pure unit
            Just newValue ->
              Sigmax.dependOnSigma sigma "[labelRenderdSizeThresholdButton] sigma: Nothing" $ \s -> do
                Sigma.setSettings s {
                  labelRenderedSizeThreshold: newValue
                  }
                T.write_ newValue state
        }
153

154 155 156 157
type MouseSelectorSizeSliderProps =
  ( forceAtlasState :: T.Box SigmaxTypes.ForceAtlasState
  , sigmaRef :: R.Ref Sigmax.Sigma
  , state    :: T.Box Number)
158

159 160 161 162 163 164 165 166 167 168
mouseSelectorSizeSlider :: R2.Leaf MouseSelectorSizeSliderProps
mouseSelectorSizeSlider = R2.leaf mouseSelectorSizeSliderCpt
mouseSelectorSizeSliderCpt :: R.Component MouseSelectorSizeSliderProps
mouseSelectorSizeSliderCpt = here.component "mouseSelectorSizeSlider" cpt
  where
    cpt { forceAtlasState, sigmaRef, state } _ = do
      pure $ sizeButton {
          caption: "Selector size (Shift + wheel)"
        , forceAtlasState
        , min: 1.0
169
        , max: 100.0
170 171 172 173 174 175 176 177 178 179 180 181 182
        , onChange: \e -> do
          let sigma = R.readRef sigmaRef
          let newValue' = DN.fromString $ R.unsafeEventValue e
          case newValue' of
            Nothing -> pure unit
            Just newValue ->
              Sigmax.dependOnSigma sigma "[mouseSelectorSizeButton] sigma: Nothing" $ \s -> do
                Sigma.setSettings s {
                  mouseSelectorSize: newValue
                  }
                T.write_ newValue state
        , state
        }