Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
purescript-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Przemyslaw Kaminski
purescript-gargantext
Commits
64b242fc
Unverified
Commit
64b242fc
authored
6 years ago
by
Nicolas Pouillard
Browse files
Options
Browse Files
Download
Plain Diff
Finish multi-node selection
Merge remote-tracking branch 'origin/multinode-test' into dev-selector
parents
cf762e19
7a74bebd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
69 additions
and
31 deletions
+69
-31
FacetsTable.purs
src/Gargantext/Components/FacetsTable.purs
+13
-13
Graph.purs
src/Gargantext/Pages/Corpus/Graph.purs
+43
-13
Tabs.purs
src/Gargantext/Pages/Corpus/Graph/Tabs.purs
+5
-5
Utils.purs
src/Gargantext/Utils.purs
+8
-0
No files found.
src/Gargantext/Components/FacetsTable.purs
View file @
64b242fc
...
@@ -9,7 +9,7 @@ import Affjax.ResponseFormat (printResponseFormatError)
...
@@ -9,7 +9,7 @@ import Affjax.ResponseFormat (printResponseFormatError)
import Affjax.ResponseFormat as ResponseFormat
import Affjax.ResponseFormat as ResponseFormat
import Control.Monad.Cont.Trans (lift)
import Control.Monad.Cont.Trans (lift)
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson, jsonEmptyObject, (.?), (:=), (~>))
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson, jsonEmptyObject, (.?), (:=), (~>))
import Data.Array (drop, take, (:), filter)
import Data.Array (drop, take, (:), filter
, (!!)
)
import Data.Either (Either(..))
import Data.Either (Either(..))
import Data.Foldable (intercalate)
import Data.Foldable (intercalate)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep (class Generic)
...
@@ -30,6 +30,7 @@ import Gargantext.Config (End(..), NodeType(..), OrderBy(..), Path(..), TabType,
...
@@ -30,6 +30,7 @@ import Gargantext.Config (End(..), NodeType(..), OrderBy(..), Path(..), TabType,
import Gargantext.Config.REST (put, post, deleteWithBody)
import Gargantext.Config.REST (put, post, deleteWithBody)
import Gargantext.Components.Loader as Loader
import Gargantext.Components.Loader as Loader
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Utils (toggleSet)
import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Utils.DecodeMaybe ((.|))
import React.DOM (a, br', button, div, i, input, p, text, span)
import React.DOM (a, br', button, div, i, input, p, text, span)
import React.DOM.Props (_type, className, href, onClick, placeholder, style, checked, target)
import React.DOM.Props (_type, className, href, onClick, placeholder, style, checked, target)
...
@@ -43,14 +44,19 @@ import Thermite (PerformAction, Render, Spec, defaultPerformAction, modifyState_
...
@@ -43,14 +44,19 @@ import Thermite (PerformAction, Render, Spec, defaultPerformAction, modifyState_
type NodeID = Int
type NodeID = Int
type TotalRecords = Int
type TotalRecords = Int
-- Example:
-- [["machine","learning"],["artificial","intelligence"]]
-- This searches for documents with "machine learning" or "artificial intelligence"
type TextQuery = Array (Array String)
newtype SearchQuery = SearchQuery
newtype SearchQuery = SearchQuery
{ query ::
Array String
{ query ::
TextQuery
, id :: Int
, id :: Int
}
}
instance encodeJsonSearchQuery :: EncodeJson SearchQuery where
instance encodeJsonSearchQuery :: EncodeJson SearchQuery where
encodeJson (SearchQuery post)
encodeJson (SearchQuery post)
= "query" := post.query
= "query" := post.query
!! 0 -- TODO anoe
~> "corpus_id" := post.id
~> "corpus_id" := post.id
~> jsonEmptyObject
~> jsonEmptyObject
...
@@ -64,7 +70,7 @@ instance decodeSearchResults :: DecodeJson SearchResults where
...
@@ -64,7 +70,7 @@ instance decodeSearchResults :: DecodeJson SearchResults where
type Props =
type Props =
{ nodeId :: Int
{ nodeId :: Int
, query ::
Array String
, query ::
TextQuery
, totalRecords :: Int
, totalRecords :: Int
, chart :: ReactElement
, chart :: ReactElement
, container :: T.TableContainerProps -> Array ReactElement
, container :: T.TableContainerProps -> Array ReactElement
...
@@ -283,9 +289,9 @@ layoutDocviewGraph = simpleSpec performAction render
...
@@ -283,9 +289,9 @@ layoutDocviewGraph = simpleSpec performAction render
type PageParams = {nodeId :: Int, query ::
Array String
, params :: T.Params}
type PageParams = {nodeId :: Int, query ::
TextQuery
, params :: T.Params}
initialPageParams :: {nodeId :: Int, query ::
Array String
} -> PageParams
initialPageParams :: {nodeId :: Int, query ::
TextQuery
} -> PageParams
initialPageParams {nodeId, query} = {nodeId, query, params: T.initialParams}
initialPageParams {nodeId, query} = {nodeId, query, params: T.initialParams}
loadPage :: PageParams -> Aff (Array DocumentsView)
loadPage :: PageParams -> Aff (Array DocumentsView)
...
@@ -325,7 +331,7 @@ type PageLoaderProps row =
...
@@ -325,7 +331,7 @@ type PageLoaderProps row =
}
}
renderPage :: forall props path.
renderPage :: forall props path.
Render (Loader.State {nodeId :: Int, query ::
Array String
| path} (Array DocumentsView))
Render (Loader.State {nodeId :: Int, query ::
TextQuery
| path} (Array DocumentsView))
{ totalRecords :: Int
{ totalRecords :: Int
, dispatch :: Action -> Effect Unit
, dispatch :: Action -> Effect Unit
, deletionState :: State
, deletionState :: State
...
@@ -425,9 +431,3 @@ deleteFavorites nodeId = deleteWithBody (toUrl Back Node (Just nodeId) <> "/favo
...
@@ -425,9 +431,3 @@ deleteFavorites nodeId = deleteWithBody (toUrl Back Node (Just nodeId) <> "/favo
deleteDocuments :: Int -> DeleteDocumentQuery -> Aff (Array Int)
deleteDocuments :: Int -> DeleteDocumentQuery -> Aff (Array Int)
deleteDocuments nodeId = deleteWithBody (toUrl Back Node (Just nodeId) <> "/documents")
deleteDocuments nodeId = deleteWithBody (toUrl Back Node (Just nodeId) <> "/documents")
-- TODO: not optimal but Data.Set lacks some function (Set.alter)
toggleSet :: forall a. Ord a => a -> Set a -> Set a
toggleSet a s
| Set.member a s = Set.delete a s
| otherwise = Set.insert a s
This diff is collapsed.
Click to expand it.
src/Gargantext/Pages/Corpus/Graph.purs
View file @
64b242fc
...
@@ -9,17 +9,19 @@ import Affjax.ResponseFormat as ResponseFormat
...
@@ -9,17 +9,19 @@ import Affjax.ResponseFormat as ResponseFormat
import Control.Monad.Cont.Trans (lift)
import Control.Monad.Cont.Trans (lift)
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.?), (.??), (:=), (~>))
import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, jsonEmptyObject, (.?), (.??), (:=), (~>))
import Data.Argonaut (decodeJson)
import Data.Argonaut (decodeJson)
import Data.Array (fold, length, mapWithIndex, (!!))
import Data.Array (fold, length, mapWithIndex, (!!)
, null
)
import Data.Either (Either(..))
import Data.Either (Either(..))
import Data.HTTP.Method (Method(..))
import Data.HTTP.Method (Method(..))
import Data.Int (fromString, toNumber)
import Data.Int (fromString, toNumber)
import Data.Int as Int
import Data.Int as Int
import Data.Lens (Lens, Lens', over, (%~), (+~), (.~), (^.))
import Data.Lens (Lens, Lens', over, (%~), (+~), (.~), (^.)
, review
)
import Data.Lens.Record (prop)
import Data.Lens.Record (prop)
import Data.Maybe (Maybe(..), fromJust, fromMaybe, isNothing)
import Data.Maybe (Maybe(..), fromJust, fromMaybe, isNothing)
import Data.Newtype (class Newtype)
import Data.Newtype (class Newtype)
import Data.Number as Num
import Data.Number as Num
import Data.String (joinWith)
import Data.String (joinWith)
import Data.Set (Set)
import Data.Set as Set
import Data.Symbol (SProxy(..))
import Data.Symbol (SProxy(..))
import Data.Traversable (for_)
import Data.Traversable (for_)
import Effect (Effect)
import Effect (Effect)
...
@@ -38,7 +40,7 @@ import Gargantext.Config.REST (get, post)
...
@@ -38,7 +40,7 @@ import Gargantext.Config.REST (get, post)
import Gargantext.Pages.Corpus.Graph.Tabs as GT
import Gargantext.Pages.Corpus.Graph.Tabs as GT
import Gargantext.Prelude (flip)
import Gargantext.Prelude (flip)
import Gargantext.Types (class Optional)
import Gargantext.Types (class Optional)
import Gargantext.Utils (getter)
import Gargantext.Utils (getter
, toggleSet
)
import Math (cos, sin)
import Math (cos, sin)
import Partial.Unsafe (unsafePartial)
import Partial.Unsafe (unsafePartial)
import React (ReactElement)
import React (ReactElement)
...
@@ -51,7 +53,6 @@ import Web.HTML (window)
...
@@ -51,7 +53,6 @@ import Web.HTML (window)
import Web.HTML.Window (localStorage)
import Web.HTML.Window (localStorage)
import Web.Storage.Storage (getItem)
import Web.Storage.Storage (getItem)
data Action
data Action
= LoadGraph Int
= LoadGraph Int
| SelectNode SelectedNode
| SelectNode SelectedNode
...
@@ -61,12 +62,21 @@ data Action
...
@@ -61,12 +62,21 @@ data Action
| ChangeLabelSize Number
| ChangeLabelSize Number
| ChangeNodeSize Number
| ChangeNodeSize Number
| DisplayEdges
| DisplayEdges
| ToggleMultiNodeSelection
-- | Zoom Boolean
-- | Zoom Boolean
newtype SelectedNode = SelectedNode {id :: String, label :: String}
newtype SelectedNode = SelectedNode {id :: String, label :: String}
derive instance eqSelectedNode :: Eq SelectedNode
derive instance eqSelectedNode :: Eq SelectedNode
derive instance newtypeSelectedNode :: Newtype SelectedNode _
derive instance newtypeSelectedNode :: Newtype SelectedNode _
derive instance ordSelectedNode :: Ord SelectedNode
instance showSelectedNode :: Show SelectedNode where
show (SelectedNode node) = node.label
_multiNodeSelection :: forall s a. Lens' { multiNodeSelection :: a | s } a
_multiNodeSelection = prop (SProxy :: SProxy "multiNodeSelection")
-- _settings :: forall s t a b. Lens { settings :: a | s } { settings :: b | t } a b
-- _settings :: forall s t a b. Lens { settings :: a | s } { settings :: b | t } a b
_settings :: forall s a. Lens' { settings :: a | s } a
_settings :: forall s a. Lens' { settings :: a | s } a
...
@@ -106,7 +116,8 @@ newtype State = State
...
@@ -106,7 +116,8 @@ newtype State = State
, filePath :: String
, filePath :: String
, sigmaGraphData :: Maybe SigmaGraphData
, sigmaGraphData :: Maybe SigmaGraphData
, legendData :: Array Legend
, legendData :: Array Legend
, selectedNode :: Maybe SelectedNode
, selectedNodes :: Set SelectedNode
, multiNodeSelection :: Boolean
, showSidePanel :: Boolean
, showSidePanel :: Boolean
, showControls :: Boolean
, showControls :: Boolean
, showTree :: Boolean
, showTree :: Boolean
...
@@ -123,7 +134,8 @@ initialState = State
...
@@ -123,7 +134,8 @@ initialState = State
, filePath : ""
, filePath : ""
, sigmaGraphData : Nothing
, sigmaGraphData : Nothing
, legendData : []
, legendData : []
, selectedNode : Nothing
, selectedNodes : Set.empty
, multiNodeSelection : false
, showSidePanel : false
, showSidePanel : false
, showControls : false
, showControls : false
, showTree : false
, showTree : false
...
@@ -154,8 +166,11 @@ performAction (LoadGraph fp) _ _ = void do
...
@@ -154,8 +166,11 @@ performAction (LoadGraph fp) _ _ = void do
-- graph.
-- graph.
--modifyState \(State s) -> State s {graphData = resp, sigmaGraphData = Just $ convert resp, legendData = getLegendData resp}
--modifyState \(State s) -> State s {graphData = resp, sigmaGraphData = Just $ convert resp, legendData = getLegendData resp}
performAction (SelectNode (SelectedNode node)) _ (State state) =
performAction (SelectNode selectedNode@(SelectedNode node)) _ (State state) =
modifyState_ $ \(State s) -> State s {selectedNode = pure $ SelectedNode node}
modifyState_ $ \(State s) ->
State s {selectedNodes = toggleSet selectedNode
(if s.multiNodeSelection then s.selectedNodes
else Set.empty) }
performAction (ShowSidePanel b) _ (State state) = void do
performAction (ShowSidePanel b) _ (State state) = void do
modifyState $ \(State s) -> State s {showSidePanel = b }
modifyState $ \(State s) -> State s {showSidePanel = b }
...
@@ -181,6 +196,10 @@ performAction DisplayEdges _ _ =
...
@@ -181,6 +196,10 @@ performAction DisplayEdges _ _ =
modifyState_ $ \(State s) -> do
modifyState_ $ \(State s) -> do
State $ ((_settings <<< _drawEdges) %~ not) s
State $ ((_settings <<< _drawEdges) %~ not) s
performAction ToggleMultiNodeSelection _ _ =
modifyState_ $ \(State s) -> do
State $ s # _multiNodeSelection %~ not
--performAction (Zoom True) _ _ =
--performAction (Zoom True) _ _ =
-- modifyState_ $ \() -> do
-- modifyState_ $ \() -> do
-- State $
-- State $
...
@@ -535,6 +554,15 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
...
@@ -535,6 +554,15 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
modCamera0 (const {ratio})
modCamera0 (const {ratio})
]
]
]
]
, li [className "col-me-2"]
[ span [] [text "MultiNode"]
, input
[ _type "checkbox"
, className "checkbox"
-- , checked
, onChange $ const $ d ToggleMultiNodeSelection
]
]
, li'
, li'
[ button [ className "btn btn-primary"
[ button [ className "btn btn-primary"
, onClick \_ -> pauseForceAtlas2
, onClick \_ -> pauseForceAtlas2
...
@@ -569,7 +597,8 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
...
@@ -569,7 +597,8 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
, onClickNode : \e ->
, onClickNode : \e ->
unsafePerformEffect $ do
unsafePerformEffect $ do
_ <- d $ ShowSidePanel true
_ <- d $ ShowSidePanel true
_ <- d $ SelectNode $ SelectedNode {id : (unsafeCoerce e).data.node.id, label : (unsafeCoerce e).data.node.label}
let {id, label} = (unsafeCoerce e).data.node
_ <- d $ SelectNode $ SelectedNode {id, label}
pure unit
pure unit
}
}
[ sigmaEnableWebGL
[ sigmaEnableWebGL
...
@@ -664,10 +693,11 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
...
@@ -664,10 +693,11 @@ specOld = fold [treespec treeSpec, graphspec $ simpleSpec performAction render']
[ div []
[ div []
[ p [] []
[ p [] []
, div [className "col-md-12"]
, div [className "col-md-12"]
[ case st.selectedNode of
[ let query = (\(SelectedNode {label}) -> words label) <$> Set.toUnfoldable st.selectedNodes in
Just (SelectedNode {label}) ->
if null query then
GT.tabsElt {query: words label, sides}
p [] []
Nothing -> p [] []
else
GT.tabsElt {query, sides}
, p [] []
, p [] []
]
]
]
]
...
...
This diff is collapsed.
Click to expand it.
src/Gargantext/Pages/Corpus/Graph/Tabs.purs
View file @
64b242fc
...
@@ -6,7 +6,7 @@ import Data.List (fromFoldable)
...
@@ -6,7 +6,7 @@ import Data.List (fromFoldable)
import Data.Tuple (Tuple(..))
import Data.Tuple (Tuple(..))
import Gargantext.Config (TabType(..), TabSubType(..))
import Gargantext.Config (TabType(..), TabSubType(..))
import Gargantext.Components.GraphExplorer.Types (GraphSideCorpus(..))
import Gargantext.Components.GraphExplorer.Types (GraphSideCorpus(..))
import Gargantext.Components.FacetsTable
as FT
import Gargantext.Components.FacetsTable
(TextQuery, docViewSpec)
import Gargantext.Components.Table as T
import Gargantext.Components.Table as T
import Gargantext.Components.Tab as Tab
import Gargantext.Components.Tab as Tab
import React (ReactElement, ReactClass, Children, createElement)
import React (ReactElement, ReactClass, Children, createElement)
...
@@ -14,23 +14,23 @@ import Thermite ( Spec, PerformAction, Render, _performAction, _render
...
@@ -14,23 +14,23 @@ import Thermite ( Spec, PerformAction, Render, _performAction, _render
, hideState, noState, cmapProps, simpleSpec, createClass
, hideState, noState, cmapProps, simpleSpec, createClass
)
)
type Props = { query ::
Array String
, sides :: Array GraphSideCorpus }
type Props = { query ::
TextQuery
, sides :: Array GraphSideCorpus }
tabsElt :: Props -> ReactElement
tabsElt :: Props -> ReactElement
tabsElt props = createElement tabsClass props []
tabsElt props = createElement tabsClass props []
-- TODO no need for Children here
-- TODO no need for Children here
tabsClass :: ReactClass { query ::
Array String
, sides :: Array GraphSideCorpus, children :: Children }
tabsClass :: ReactClass { query ::
TextQuery
, sides :: Array GraphSideCorpus, children :: Children }
tabsClass = createClass "GraphTabs" pureTabs (const {})
tabsClass = createClass "GraphTabs" pureTabs (const {})
pureTabs :: Spec {} Props Void
pureTabs :: Spec {} Props Void
pureTabs = hideState (const {activeTab: 0}) statefulTabs
pureTabs = hideState (const {activeTab: 0}) statefulTabs
tab :: forall props state.
Array String
-> GraphSideCorpus -> Tuple String (Spec state props Tab.Action)
tab :: forall props state.
TextQuery
-> GraphSideCorpus -> Tuple String (Spec state props Tab.Action)
tab query (GraphSideCorpus {corpusId: nodeId, corpusLabel}) =
tab query (GraphSideCorpus {corpusId: nodeId, corpusLabel}) =
Tuple corpusLabel $
Tuple corpusLabel $
cmapProps (const {nodeId, query, chart, totalRecords: 4736, container}) $
cmapProps (const {nodeId, query, chart, totalRecords: 4736, container}) $
noState
FT.
docViewSpec
noState docViewSpec
where
where
-- TODO totalRecords: probably need to insert a corpusLoader.
-- TODO totalRecords: probably need to insert a corpusLoader.
chart = mempty
chart = mempty
...
...
This diff is collapsed.
Click to expand it.
src/Gargantext/Utils.purs
View file @
64b242fc
...
@@ -3,6 +3,8 @@ module Gargantext.Utils where
...
@@ -3,6 +3,8 @@ module Gargantext.Utils where
import Prelude
import Prelude
import Data.Newtype (class Newtype, unwrap, wrap)
import Data.Newtype (class Newtype, unwrap, wrap)
import Data.Set as Set
import Data.Set (Set)
setterv :: forall nt record field. Newtype nt record => (record -> field -> record) -> field -> nt -> nt
setterv :: forall nt record field. Newtype nt record => (record -> field -> record) -> field -> nt -> nt
setterv fn v t = (setter (flip fn v) t)
setterv fn v t = (setter (flip fn v) t)
...
@@ -12,3 +14,9 @@ setter fn = wrap <<< fn <<< unwrap
...
@@ -12,3 +14,9 @@ setter fn = wrap <<< fn <<< unwrap
getter :: forall record field nt. Newtype nt record => (record -> field) -> nt -> field
getter :: forall record field nt. Newtype nt record => (record -> field) -> nt -> field
getter fn = fn <<< unwrap
getter fn = fn <<< unwrap
-- TODO: not optimal but Data.Set lacks some function (Set.alter)
toggleSet :: forall a. Ord a => a -> Set a -> Set a
toggleSet a s
| Set.member a s = Set.delete a s
| otherwise = Set.insert a s
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment