Commit 8e4975ab authored by arturo's avatar arturo

>>> continue

parent 6014c01f
...@@ -12,6 +12,7 @@ import Data.HTTP.Method (Method(..)) ...@@ -12,6 +12,7 @@ import Data.HTTP.Method (Method(..))
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Effect.Aff (Aff, launchAff_) import Effect.Aff (Aff, launchAff_)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Gargantext.Components.PhyloExplorer.Layout (layout)
import Gargantext.Components.PhyloExplorer.Types (PhyloDataset) import Gargantext.Components.PhyloExplorer.Types (PhyloDataset)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
import Gargantext.Types (NodeID) import Gargantext.Types (NodeID)
...@@ -36,38 +37,20 @@ phyloLayoutCpt = here.component "phyloLayout" cpt where ...@@ -36,38 +37,20 @@ phyloLayoutCpt = here.component "phyloLayout" cpt where
cpt _ _ = do cpt _ _ = do
fetchedDataBox <- T.useBox (Nothing :: Maybe PhyloDataset) fetchedDataBox <- T.useBox (Nothing :: Maybe PhyloDataset)
fetchedData <- T.useLive T.unequal fetchedDataBox fetchedData <- T.useLive T.unequal fetchedDataBox
R.useEffectOnce' $ launchAff_ do R.useEffectOnce' $ launchAff_ do
result <- fetchPhyloJSON result <- fetchPhyloJSON
liftEffect $ case result of liftEffect $ case result of
Left err -> log2 "error" err Left err -> log2 "error" err
Right res -> T.write_ (Just res) fetchedDataBox Right res -> T.write_ (Just res) fetchedDataBox
pure $ case fetchedData of pure case fetchedData of
Nothing -> mempty Nothing -> mempty
Just fdata -> Just phyloDataset -> layout { phyloDataset } []
H.div
{ className:"phyloCorpus" }
[ H.text $ show fdata ]
-- ,
-- infoCorpusR
-- ,
-- infoPhyloR
-- ,
-- timelineR
-- ,
-- isolineR
-- ,
-- wordcloudR
-- ,
-- phyloR
fetchPhyloJSON :: Aff (Either String PhyloDataset) fetchPhyloJSON :: Aff (Either String PhyloDataset)
-- fetchPhyloJSON :: ReadForeign PhyloDataset => Aff Unit
fetchPhyloJSON = fetchPhyloJSON =
let let
request = AX.defaultRequest request = AX.defaultRequest
......
module Gargantext.Components.PhyloExplorer.Draw where
module Gargantext.Components.PhyloExplorer.Layout
( layout
) where
import Gargantext.Prelude
import DOM.Simple.Console (log2)
import Data.Array as Array
import Data.Int (fromString)
import Data.Maybe (maybe)
import Data.String as String
import Gargantext.Components.PhyloExplorer.Types (PhyloDataset(..))
import Gargantext.Utils (nbsp)
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Toestand as T
here :: R2.Here
here = R2.here "Gargantext.Components.PhyloExplorer"
type Props =
( phyloDataset :: PhyloDataset
)
layout :: R2.Component Props
layout = R.createElement layoutCpt
layoutCpt :: R.Component Props
layoutCpt = here.component "layout" cpt where
cpt { phyloDataset: (PhyloDataset phyloDataset)
} _ = do
-- States
let
{ phyloDocs
, phyloBranches
, phyloGroups
, phyloTerms
, phyloPeriods
, phyloFoundations
, phyloSources
} = phyloDataset
nbDocs = parseInt phyloDocs
nbBranches = parseInt phyloBranches
nbGroups = parseInt phyloGroups
nbTerms = parseInt phyloTerms
nbPeriods = parseInt phyloPeriods
nbFoundations = parseInt phyloFoundations
sourcesBox <- T.useBox (mempty :: Array String)
sources <- T.useLive T.unequal sourcesBox
-- Hooks
R.useEffectOnce' $ do
sources' <- pure $ stringArrToArr phyloSources
T.write_ sources' sourcesBox
-- @hightlightSource
let
highlightSource = \_ -> unit
-- Render
pure $
H.div
{ className: "phylo" }
[
-- <!-- row 1 -->
H.div
{ className: "phylo-title font-bold" }
[ H.text "Mèmiescape" ]
,
H.div
{ className: "phylo-folder" }
[
-- <!-- title bar (static mode) -->
H.label
{ id: "phyloName"
, className: "phylo-name"
}
[]
,
-- <!-- folder bar -->
-- H.label
-- { id: "file-label"
-- , for: "file-path"
-- , className: "input-file"
-- }
-- [ H.text "load a phylomemy →" ]
-- ,
-- H.input
-- { id: "file-path"
-- , type: "file"
-- , maxLength: "10"
-- }
-- ,
-- H.label
-- { id: "file-name"
-- , className: "input-name"
-- }
-- []
-- ,
-- H.button
-- { id: "draw"
-- , className: "button draw"
-- }
-- [ H.text "draw" ]
-- ,
-- <!-- source selector -->
R2.select
{ id: "checkSource"
, className: "select-source"
, defaultValue: ""
, on: { change: \_ -> unit }
} $
[
H.option
{ disabled: true
, value: ""
}
[ H.text "select a source ↴" ]
,
H.option
{ value: "unselect" }
[ H.text "unselect source ✕" ]
]
<>
flip Array.mapWithIndex sources
( \idx val ->
H.option
{ value: idx }
[ H.text val ]
)
,
-- <!-- search bar -->
H.label
{ id: "search-label"
, className: "search-label"
}
[ H.text "find a term →" ]
,
H.input
{ id: "search-box"
, type: "text"
, className: "search"
}
,
H.input
{ id: "search-autocomplete"
, text: "text"
, className: "autocomplete"
, disabled: true
, value: ""
}
]
,
-- <!-- row 2 & 3 -->
phyloCorpus {} []
,
phyloCorpusInfo
{ nbDocs, nbFoundations, nbPeriods }
[]
,
-- H.div
-- { id: "phyloHow"
-- , className: "phylo-how"
-- }
-- []
-- ,
phyloPhylo {} []
,
phyloPhyloInfo
{ nbTerms, nbGroups, nbBranches }
[]
,
H.div
{ id: "phyloIsoLine"
, className: "phylo-isoline-info"
}
[
H.div
{ className: "btn-group" }
[
H.button
{ id: "reset"
, className: "button reset"
}
[
H.i
{ className: "fas fa-expand-arrows-alt" }
[]
]
,
H.button
{ id: "label"
, className: "button label"
}
[
H.i
{ className: "fas fa-dot-circle" }
[]
]
,
H.button
{ id: "heading"
, className: "button heading"
}
[
H.i
{ className: "fas fa-sort-alpha-down" }
[]
]
,
H.button
{ id: "export"
, className: "button export"
}
[
H.i
{ className: "fas fa-camera" }
[]
]
]
]
,
-- <!-- row 4 -->
H.div
{ id: "phyloScape"
, className: "phylo-scape"
}
[]
,
H.div
{ id: "phyloTimeline"
, className: "phylo-timeline"
}
[]
,
H.div
{ id: "phyloGraph"
, className: "phylo-graph"
}
[]
,
-- <!-- row 5 -->
H.div
{ className: "phylo-footer font-bold font-small"
}
[ H.text "iscpif // cnrs // 2021" ]
]
parseInt :: String -> Int
parseInt s = maybe 0 identity $ fromString s
stringArrToArr :: String -> Array String
stringArrToArr
= String.replace (String.Pattern "[") (String.Replacement "")
>>> String.replace (String.Pattern "]") (String.Replacement "")
>>> String.split (String.Pattern ",")
>>> Array.filter (\s -> not eq 0 $ String.length s)
--------------------------------------------------------
type PhyloCorpusProps = ()
phyloCorpus :: R2.Component PhyloCorpusProps
phyloCorpus = R.createElement phyloCorpusCpt
phyloCorpusCpt :: R.Component PhyloCorpusProps
phyloCorpusCpt = here.component "phyloCorpus" cpt where
cpt _ _ = do
-- Render
pure $
H.div
{ id: "phyloCorpus"
, className: "phylo-corpus"
}
[ H.text "corpus" ]
---------------------------------------------------------
type PhyloPhyloProps = ()
phyloPhylo :: R2.Component PhyloPhyloProps
phyloPhylo = R.createElement phyloPhyloCpt
phyloPhyloCpt :: R.Component PhyloPhyloProps
phyloPhyloCpt = here.component "phyloPhylo" cpt where
cpt _ _ = do
-- Render
pure $
H.div
{ id: "phyloPhylo"
, className: "phylo-phylo"
}
[ H.text "phylomemy" ]
---------------------------------------------------------
type PhyloCorpusInfoProps =
( nbDocs :: Int
, nbFoundations :: Int
, nbPeriods :: Int
)
phyloCorpusInfo :: R2.Component PhyloCorpusInfoProps
phyloCorpusInfo = R.createElement phyloCorpusInfoCpt
phyloCorpusInfoCpt :: R.Component PhyloCorpusInfoProps
phyloCorpusInfoCpt = here.component "phyloCorpusInfo" cpt where
cpt props _ = do
-- Render
pure $
H.div
{ id: "phyloCorpusInfo"
, className: "phylo-corpus-info"
}
[
H.span
{}
[
H.b {} [ H.text $ show props.nbDocs ]
, H.text $ nbsp 1 <> "docs"
]
,
H.span
{}
[
H.b {} [ H.text $ show props.nbFoundations ]
, H.text $ nbsp 1 <> "foundations"
]
,
H.span
{}
[
H.b {} [ H.text $ show props.nbPeriods ]
, H.text $ nbsp 1 <> "periods"
]
]
---------------------------------------------------------
type PhyloPhyloInfoProps =
( nbTerms :: Int
, nbGroups :: Int
, nbBranches :: Int
)
phyloPhyloInfo :: R2.Component PhyloPhyloInfoProps
phyloPhyloInfo = R.createElement phyloPhyloInfoCpt
phyloPhyloInfoCpt :: R.Component PhyloPhyloInfoProps
phyloPhyloInfoCpt = here.component "phyloPhyloInfo" cpt where
cpt props _ = do
-- Render
pure $
H.div
{ id: "phyloPhyloInfo"
, className: "phylo-phylo-info"
}
[
H.span
{}
[
H.b
{ id: "phyloTerms" }
[ H.text $ show props.nbTerms ]
, H.text $ nbsp 1 <> "terms"
]
,
H.span
{}
[
H.b
{ id: "phyloGroups" }
[ H.text $ show props.nbGroups ]
, H.text $ nbsp 1 <> "groups"
]
,
H.span
{}
[
H.b
{ id: "phyloBranches" }
[ H.text $ show props.nbBranches ]
, H.text $ nbsp 1 <> "branches"
]
]
This diff is collapsed.
'use strict';
function readJson(file, callback) {
var raw = new XMLHttpRequest();
raw.overrideMimeType("application/json");
raw.open("GET", file, true);
raw.onreadystatechange = function() {
if (raw.readyState === 4 && raw.status == "200") {
callback(raw.responseText);
}
}
raw.send(null);
}
function unhide(mode) {
document.querySelector("#reset").style.visibility = "visible";
document.querySelector("#label").style.visibility = "visible";
document.querySelector("#heading").style.visibility = "visible";
if (mode != "static") {
document.querySelector("#export").style.visibility = "visible";
}
}
window.addEventListener("load", function() {
// read the config
readJson("./config.json",function(data1){
var conf = JSON.parse(data1);
// available config modes are "static" or "explorable"
if (conf.mode == "static") {
var path = "";
var name = "";
if (conf.path == null || conf.path == "") {
path = conf.defaultPath;
name = conf.defaultName;
} else {
path = conf.path;
name = conf.pathName;
}
document.querySelector("#file-label").style.display = "none";
document.querySelector("#spin").style.visibility = "visible";
document.getElementById("phyloName").innerHTML = name;
document.querySelector("#phyloName").style.visibility = "visible";
readJson(path,function(data2){
phylo = JSON.parse(data2);
unhide("static");
draw(phylo);
})
}
})
})
function readPhylo(file) {
var reader = new FileReader();
reader.onload = (function(f) {
return function(e) {
try {
json = JSON.parse(e.target.result);
unhide("explorable");
draw(json)
} catch (error) {
console.log(error)
}
};
})(file);
reader.readAsText(file, "UTF-8");
}
// display the Draw button after loading a phylo
document.querySelector("#file-path").onchange = function(){
document.querySelector("#file-name").textContent = (this.files[0].name).substring(0,15) + "...";
// document.querySelector("#file-name").textContent = this.files[0].name;
document.querySelector("#draw").style.display = "inline-block";
}
// draw the phylo
document.querySelector("#draw").onclick = function() {
document.querySelector("#spin").style.visibility = "visible";
readPhylo(document.getElementById("file-path").files[0]);
}
function drawPhyloInfo(elemClass, docs, foundations, branches, groups, terms, periods) {
ReactDOM.render(React.createElement(phyloCorpus,{}),document.getElementById('phyloCorpus'));
ReactDOM.render(React.createElement(phyloPhylo,{}),document.getElementById('phyloPhylo'));
ReactDOM.render(React.createElement(phyloHow,{}),document.getElementById('phyloHow'));
ReactDOM.render(React.createElement(phyloCorpusInfo,{
nbDocs : docs,
nbFoundations : foundations,
nbPeriods : periods
}),document.getElementById('phyloCorpusInfo'));
ReactDOM.render(React.createElement(phyloPhyloInfo,{
nbTerms : terms,
nbGroups : groups,
nbBranches : branches
}),document.getElementById('phyloPhyloInfo'));
}
function draw(json) {
// draw PhyloInfo
window.freq = {};
window.terms = {};
window.sources = [];
window.nbDocs = parseFloat(json.phyloDocs);
window.nbBranches = parseFloat(json.phyloBranches);
window.nbGroups = parseFloat(json.phyloGroups);
window.nbTerms = parseFloat(json.phyloTerms);
window.nbPeriods = parseFloat(json.phyloPeriods);
window.nbFoundations = parseFloat(json.phyloFoundations);
window.timeScale = json.phyloTimeScale;
if (json.phyloSources != undefined) {
var sources = stringArrToArr(json.phyloSources);
var checkSource = document.getElementById("checkSource");
for (var i = 0; i < sources.length; i++) {
window.sources.push({source:sources[i],index:i});
}
window.sources.sort(function(a, b){
if(a.source < b.source) { return -1; }
if(a.source > b.source) { return 1; }
return 0;
})
for (var i = 0; i < window.sources.length; i++) {
var option = document.createElement("option");
option.text = window.sources[i].source;
option.value = window.sources[i].index;
checkSource.add(option);
}
}
// original bounding box
bb = ((json.bb).split(',')).map(xy => parseFloat(xy))
drawPhyloInfo("", window.nbDocs, window.nbFoundations, window.nbBranches, window.nbGroups, window.nbTerms, window.nbPeriods)
// draw PhyloIsoline
var branches = json.objects.filter(node => node.nodeType == "branch").map(function(b){
return { x1 : b.branch_x ,
y : b.branch_y ,
x2 : parseFloat(((b.pos).split(','))[0]) ,
label : b.label,
bId : parseInt(b.bId),
gvid : parseInt(b._gvid)
}
});
var periods = json.objects.filter(node => node.nodeType == "period").map(function(p){
var from = yearToDate(p.from),
to = yearToDate(p.to);
if (p.strFrom != undefined) {
if (window.timeScale == "epoch") {
from = utcStringToDate(p.strFrom)
} else {
from = stringToDate(p.strFrom)
}
}
if (p.strTo != undefined) {
if (window.timeScale == "epoch") {
to = utcStringToDate(p.strTo)
} else {
to = stringToDate(p.strTo)
}
}
return { from : from,
to : to,
y : parseFloat(((p.pos).split(','))[1])}
});
// groups
window.weighted = false;
var groups = json.objects.filter(node => node.nodeType == "group").map(function(g){
// console.log(g.weight)
if ((g.weight != undefined) && (g.weight != "Nothing"))
window.weighted = true;
var keys = (g.foundation.slice(1, g.foundation.length - 1)).split('|')
var labels = (g.lbl.slice(1, g.lbl.length - 1)).split('|')
for (var i = 0; i < keys.length; i++) {
// freq
if (!((keys[i]).trim() in window.freq)) {
window.freq[(keys[i]).trim()] = 0;
} else {
window.freq[(keys[i]).trim()] += 1;
}
// terms
if (!((keys[i]).trim() in window.terms)) {
window.terms[(keys[i]).trim()] = {label:(labels[i]).trim(),fdt:(keys[i]).trim()}
}
}
var from = yearToDate(g.from),
to = yearToDate(g.to),
weight = 0;
source = [];
if (g.strFrom != undefined) {
if (window.timeScale == "epoch") {
from = utcStringToDate(g.strFrom)
} else {
from = stringToDate(g.strFrom)
}
}
if (g.strTo != undefined) {
if (window.timeScale == "epoch") {
to = utcStringToDate(g.strTo)
} else {
to = stringToDate(g.strTo)
}
}
if (g.source != undefined)
source = intArrToArr(g.source);
if (g.weight != undefined)
weight = parseFloat((g.weight).replace("Just ",""));
return { from : from,
to : to,
x : parseFloat(((g.pos).split(','))[0]) ,
y : parseFloat(((g.pos).split(','))[1]) ,
bId : parseInt(g.bId) ,
gId : parseInt(g._gvid) ,
size : parseInt(g.support),
source : source,
weight : weight,
label : labels,
foundation : keys,
role : ((g.role.slice(1, g.role.length - 1)).split('|')).map(e => parseInt(e.trim()))}
});
var links = json.edges.filter(edges => edges.edgeType == "link").map(function(l){
return { lId : parseInt(l._gvid),
from : parseInt(l.tail) ,
to : parseInt(l.head) ,
label : l.label}
});
var aLinks = json.edges.filter(edges => edges.edgeType == "ancestorLink").map(function(l){
return { lId : parseInt(l._gvid),
from : parseInt(l.tail) ,
to : parseInt(l.head) ,
label : l.label }
});
var bLinks = json.edges.filter(edges => edges.edgeType == "branchLink").map(function(l){
return { from : parseInt(l.tail) ,
to : parseInt(l.head) }
});
window.terms = Object.values(window.terms)
// draw the phylo
drawPhylo(branches,periods,groups,links,aLinks,bLinks,bb);
}
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