Commit 488d75f3 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[Dashboard] work on selection of charts

parent 15801a80
......@@ -240,9 +240,10 @@ codeTypeSelectorCpt = R.hooksComponent "G.C.CE.CodeTypeSelector" cpt
where
cpt {codeType, onChange} _ = do
pure $ R2.select { className: "form-control"
, defaultValue: show $ fst codeType
, on: { change: onSelectChange codeType onChange }
, style: { width: "150px" }
, value: show $ fst codeType }
}
(option <$> [Haskell, JSON, Markdown])
option :: CodeType -> R.Element
......
......@@ -33,7 +33,7 @@ import Gargantext.Utils.Reactix as R2
import Gargantext.Routes as Routes
import Gargantext.Routes (SessionRoute(NodeAPI))
import Gargantext.Sessions (Session, sessionId, post, delete, put)
import Gargantext.Types (NodeType(..), OrderBy(..), TabType, TabPostQuery(..), AffTableResult)
import Gargantext.Types (NodeType(..), OrderBy(..), TabType, TabPostQuery(..), AffTableResult, NodeID)
------------------------------------------------------------------------
data Category = Trash | UnRead | Checked | Topic | Favorite
......@@ -143,7 +143,6 @@ categoryRoute nodeId = NodeAPI Node (Just nodeId) "category"
putCategories :: Session -> Int -> CategoryQuery -> Aff (Array Int)
putCategories session nodeId = put session $ categoryRoute nodeId
type NodeID = Int
type TotalRecords = Int
type LayoutProps =
......
......@@ -25,13 +25,12 @@ import Gargantext.Components.Table as T
import Gargantext.Routes (SessionRoute(Search, NodeAPI))
import Gargantext.Routes as Routes
import Gargantext.Sessions (Session, sessionId, post, deleteWithBody)
import Gargantext.Types (NodeType(..), OrderBy(..), NodePath(..))
import Gargantext.Types (NodeType(..), OrderBy(..), NodePath(..), NodeID)
import Gargantext.Utils (toggleSet, zeroPad)
import Gargantext.Utils.DecodeMaybe ((.|))
import Gargantext.Utils.Reactix as R2
------------------------------------------------------------------------
type NodeID = Int
type TotalRecords = Int
-- Example:
......
......@@ -5,7 +5,7 @@ import Data.Argonaut.Parser (jsonParser)
import Data.Array as A
import Data.Either (Either(..))
import Data.List as List
import Data.Maybe (Maybe(..))
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (Tuple(..), fst, snd)
import Data.Tuple.Nested ((/\))
import DOM.Simple.Console (log2)
......@@ -84,7 +84,7 @@ corpusLayoutViewCpt = R.hooksComponent "G.C.N.C.corpusLayoutView" cpt
H.div { className: "btn btn-default " <> (saveEnabled fieldsWithIndex fieldsS)
, on: { click: onClickSave {fields: fieldsS, nodeId, reload, session} }
} [
H.span { className: "glyphicon glyphicon-floppy-disk" } [ ]
H.span { className: "fa fa-floppy-o" } [ ]
]
]
, H.div {} [ fieldsCodeEditor { fields: fieldsS
......@@ -94,7 +94,7 @@ corpusLayoutViewCpt = R.hooksComponent "G.C.N.C.corpusLayoutView" cpt
H.div { className: "btn btn-default"
, on: { click: onClickAdd fieldsS }
} [
H.span { className: "glyphicon glyphicon-plus" } [ ]
H.span { className: "fa fa-plus" } [ ]
]
]
]
......@@ -151,9 +151,8 @@ fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt
onChange :: R.State FTFieldsWithIndex -> Index -> FieldType -> Effect Unit
onChange (_ /\ setFields) idx typ = do
setFields $ \fields ->
case List.modifyAt idx (\(Tuple _ (Field f)) -> Tuple idx (Field $ f { typ = typ })) fields of
Nothing -> fields
Just newFields -> newFields
fromMaybe fields $
List.modifyAt idx (\(Tuple _ (Field f)) -> Tuple idx (Field $ f { typ = typ })) fields
onMoveDown :: R.State Int -> R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onMoveDown (_ /\ setMasterKey) (fs /\ setFields) idx _ = do
......@@ -168,16 +167,12 @@ fieldsCodeEditorCpt = R.hooksComponent "G.C.N.C.fieldsCodeEditorCpt" cpt
onRemove :: R.State FTFieldsWithIndex -> Index -> Unit -> Effect Unit
onRemove (_ /\ setFields) idx _ = do
setFields $ \fields ->
case List.deleteAt idx fields of
Nothing -> fields
Just newFields -> recomputeIndices newFields
fromMaybe fields $ List.deleteAt idx fields
onRename :: R.State FTFieldsWithIndex -> Index -> String -> Effect Unit
onRename (_ /\ setFields) idx newName = do
setFields $ \fields ->
case List.modifyAt idx (\(Tuple _ (Field f)) -> Tuple idx (Field $ f { name = newName })) fields of
Nothing -> fields
Just newFields -> newFields
fromMaybe fields $ List.modifyAt idx (\(Tuple _ (Field f)) -> Tuple idx (Field $ f { name = newName })) fields
recomputeIndices :: FTFieldsWithIndex -> FTFieldsWithIndex
recomputeIndices = List.mapWithIndex $ \idx -> \(Tuple _ t) -> Tuple idx t
......@@ -213,7 +208,7 @@ fieldCodeEditorWrapperCpt = R.hooksComponent "G.C.N.C.fieldCodeEditorWrapperCpt"
H.div { className: "btn btn-danger"
, on: { click: \_ -> onRemove unit }
} [
H.span { className: "glyphicon glyphicon-trash" } [ ]
H.span { className: "fa fa-trash" } [ ]
]
]
, moveDownButton canMoveDown
......@@ -230,14 +225,14 @@ fieldCodeEditorWrapperCpt = R.hooksComponent "G.C.N.C.fieldCodeEditorWrapperCpt"
H.div { className: "btn btn-default"
, on: { click: \_ -> onMoveDown unit }
} [
H.span { className: "glyphicon glyphicon-arrow-down" } [ ]
H.span { className: "fa fa-arrow-down" } [ ]
]
moveUpButton false = H.div {} []
moveUpButton true =
H.div { className: "btn btn-default"
, on: { click: \_ -> onMoveUp unit }
} [
H.span { className: "glyphicon glyphicon-arrow-up" } [ ]
H.span { className: "fa fa-arrow-up" } [ ]
]
type RenameableProps =
......@@ -287,7 +282,7 @@ renameableTextCpt = R.hooksComponent "G.C.N.C.renameableTextCpt" cpt
H.span { className: "text" } [ H.text text ]
, H.span { className: "btn btn-default"
, on: { click: \_ -> setIsEditing $ const true } } [
H.span { className: "glyphicon glyphicon-pencil" } []
H.span { className: "fa fa-pencil" } []
]
]
cpt {isEditing: (true /\ setIsEditing), onRename, state: (text /\ setText)} _ = do
......@@ -300,7 +295,7 @@ renameableTextCpt = R.hooksComponent "G.C.N.C.renameableTextCpt" cpt
setIsEditing $ const false
onRename text
} } [
H.span { className: "glyphicon glyphicon-floppy-disk" } []
H.span { className: "fa fa-floppy-o" } []
]
]
......
module Gargantext.Components.Nodes.Corpus.Dashboard where
import Data.Array (zipWith)
import Data.Int (toNumber)
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Data.Array as A
import Data.String.Common as DSC
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Effect (Effect)
import Reactix as R
import Reactix.DOM.HTML as H
import Gargantext.Prelude
import Gargantext.Components.Charts.Options.ECharts (Options(..), chart, xAxis', yAxis', tooltipTriggerAxis)
import Gargantext.Components.Charts.Options.Data
import Gargantext.Components.Charts.Options.Series
( TreeNode, Trees(..), mkTree, seriesBarD1, seriesFunnelD1, seriesPieD1
, seriesSankey, seriesScatterD2, treeLeaf, treeNode )
import Gargantext.Components.Node (NodePoly(..))
import Gargantext.Components.Nodes.Corpus (loadCorpusWithChild)
import Gargantext.Components.Nodes.Corpus.Chart.Histo (histo)
import Gargantext.Components.Nodes.Corpus.Chart.Metrics (metrics)
import Gargantext.Components.Nodes.Corpus.Chart.Pie (pie)
import Gargantext.Components.Nodes.Corpus.Chart.Tree (tree)
import Gargantext.Components.Nodes.Corpus.Chart.Predefined as P
import Gargantext.Components.Nodes.Corpus.Types (getCorpusInfo, CorpusInfo(..), Hyperdata(..))
import Gargantext.Hooks.Loader (useLoader)
import Gargantext.Utils.Reactix as R2
import Gargantext.Sessions (Session)
import Gargantext.Types (Mode(..), TabSubType(..), TabType(..), modeTabType)
import Gargantext.Types (NodeID)
type Props =
(
nodeId :: Int
nodeId :: NodeID
, session :: Session
)
......@@ -38,17 +33,23 @@ dashboardLayoutCpt :: R.Component Props
dashboardLayoutCpt = R.hooksComponent "G.P.C.D.dashboardLayout" cpt
where
cpt params@{nodeId, session} _ = do
predefinedCharts <- R.useState' [
-- P.CDocsHistogram
-- , P.CAuthorsPie
-- , P.CTermsMetrics
-- , P.CInstitutesTree
]
useLoader params loadCorpusWithChild $
\corpusData@{corpusId, defaultListId, corpusNode: NodePoly poly} ->
\corpusData@{corpusId, defaultListId, corpusNode: NodePoly poly} -> do
let { name, date, hyperdata : Hyperdata h} = poly
CorpusInfo {desc,query,authors} = getCorpusInfo h.fields
in
dashboardLayoutLoaded {corpusId, defaultListId, nodeId, session}
let CorpusInfo {desc,query,authors} = getCorpusInfo h.fields
dashboardLayoutLoaded {corpusId, defaultListId, nodeId, predefinedCharts, session}
type LoadedProps =
(
corpusId :: Int
corpusId :: NodeID
, defaultListId :: Int
, predefinedCharts :: R.State (Array P.PredefinedChart)
| Props
)
......@@ -56,65 +57,88 @@ dashboardLayoutLoaded :: Record LoadedProps -> R.Element
dashboardLayoutLoaded props = R.createElement dashboardLayoutLoadedCpt props []
dashboardLayoutLoadedCpt :: R.Component LoadedProps
dashboardLayoutLoadedCpt = R.hooksComponent "G.P.C.D.dashboardLayoutLoaded" cpt
dashboardLayoutLoadedCpt = R.hooksComponent "G.C.N.C.D.dashboardLayoutLoaded" cpt
where
cpt props _ = do
pure $ H.div {} [
cpt props@{ corpusId, defaultListId, predefinedCharts: (predefinedCharts /\ setPredefinedCharts), session } _ = do
pure $
H.div {} ([
H.h1 {} [ H.text "DashBoard" ]
, H.div {className: "row"} [
--H.div {className: "col-md-9 content"} [ chart globalPublis ]
H.div {className: "col-md-12 content"} [ histo (globalPublisParams props) ]
--, H.div {className: "col-md-3 content"} [ chart naturePublis ]
]
--, chart distriBySchool
, pie (authorsParams props)
--, H.div {className: "row"} (aSchool <$> schools)
--, chart scatterEx
, metrics (termsParams props)
--, chart sankeyEx
, tree (institutesParams props)
--, chart treeMapEx
--, chart treeEx
] <> charts <> [addNew])
where
addNew = H.div { className: "row" } [
H.span { className: "btn btn-default"
, on: { click: onClick }} [ H.span { className: "fa fa-plus" } [] ]
]
authorsParams {corpusId, session} = {path, session}
where
path = {corpusId, tabType: TabCorpus (TabNgramType $ modeTabType Authors)}
globalPublisParams {corpusId, session} = { path, session}
onClick _ = setPredefinedCharts $ A.cons P.CDocsHistogram
charts = A.mapWithIndex chartIdx predefinedCharts
chartIdx idx chart =
renderChart { chart, corpusId, defaultListId, onChange, onRemove, session }
where
onChange c = setPredefinedCharts $
\cs -> fromMaybe cs (A.modifyAt idx (\_ -> c) cs)
onRemove _ = setPredefinedCharts $
\cs -> fromMaybe cs $ A.deleteAt idx cs
type PredefinedChartProps =
(
corpusId :: NodeID
, chart :: P.PredefinedChart
, defaultListId :: Int
, onChange :: P.PredefinedChart -> Effect Unit
, onRemove :: Unit -> Effect Unit
, session :: Session
)
renderChart :: Record PredefinedChartProps -> R.Element
renderChart props = R.createElement renderChartCpt props []
renderChartCpt :: R.Component PredefinedChartProps
renderChartCpt = R.hooksComponent "G.C.N.C.D.renderChart" cpt
where
path = {corpusId, tabType: TabCorpus TabDocs}
institutesParams {corpusId, defaultListId, session} = {path, session}
cpt { chart, corpusId, defaultListId, onChange, onRemove, session } _ = do
pure $ H.div { className: "row" } [
H.div {} [
R2.select { defaultValue: show chart
, on: { change: onSelectChange }
} (option <$> P.allPredefinedCharts)
]
, H.div {} [
H.span { className: "btn btn-danger"
, on: { click: onRemoveClick }} [ H.span { className: "fa fa-trash" } [] ]
]
, P.render chart params
]
where
path = { corpusId
, limit: Just 1000 -- TODO Fix
, listId: defaultListId -- TODO Is this correct?
, tabType: TabCorpus (TabNgramType $ modeTabType Institutes)
}
termsParams {corpusId, defaultListId, session} = {path, session}
option pc =
H.option { value: show pc } [ H.text $ show pc ]
onSelectChange e = onChange $ P.readChart' e
where
path = { corpusId
, limit: Just 1000 -- TODO Fix
, listId: defaultListId -- TODO Is this correct?
, tabType: TabCorpus (TabNgramType $ modeTabType Terms)
value = R2.unsafeEventValue e
onRemoveClick _ = onRemove unit
params = { corpusId
, limit: Just 1000
, listId: Just defaultListId
, session
}
aSchool school = H.div {className: "col-md-4 content"} [ chart $ focus school ]
schools = [ "Télécom Bretagne", "Mines Nantes", "Eurecom" ]
myData =
[seriesBarD1 {name: "Bar Data"}
[ dataSerie {name: "val1", value: 50.0}
, dataSerie {name: "val2", value: 70.0}
, dataSerie {name: "val3", value: 80.0} ] ]
focus :: String -> Options
focus school =
Options
{ mainTitle : "Focus " <> school
, subTitle : "Total scientific publications"
, xAxis : xAxis' ["2015", "2016", "2017"]
, yAxis : yAxis' { position: "left", show: false, min : 0 }
, series : myData
, addZoom : false
, tooltip : tooltipTriggerAxis } -- Necessary?
-- aSchool school = H.div {className: "col-md-4 content"} [ chart $ focus school ]
-- schools = [ "Télécom Bretagne", "Mines Nantes", "Eurecom" ]
-- myData =
-- [seriesBarD1 {name: "Bar Data"}
-- [ dataSerie {name: "val1", value: 50.0}
-- , dataSerie {name: "val2", value: 70.0}
-- , dataSerie {name: "val3", value: 80.0} ] ]
-- focus :: String -> Options
-- focus school =
-- Options
-- { mainTitle : "Focus " <> school
-- , subTitle : "Total scientific publications"
-- , xAxis : xAxis' ["2015", "2016", "2017"]
-- , yAxis : yAxis' { position: "left", show: false, min : 0 }
-- , series : myData
-- , addZoom : false
-- , tooltip : tooltipTriggerAxis } -- Necessary?
-----------------------------------------------------------------------------------------------------------
......
......@@ -16,6 +16,7 @@ import Prim.Row (class Union)
import URI.Query (Query)
newtype SessionId = SessionId String
type NodeID = Int
derive instance genericSessionId :: Generic SessionId _
......
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