module Gargantext.Components.Charts.Options.Series where import Data.Array (foldl) import Data.Generic.Rep (class Generic) import Data.Maybe (Maybe(..), maybe) import Data.Newtype (class Newtype) import Data.Symbol (SProxy(..)) import Gargantext.Components.Charts.Options.Data (DataD1, DataD2) import Gargantext.Components.Charts.Options.Font (ItemStyle, Tooltip) import Gargantext.Components.Charts.Options.Legend (SelectedMode) import Gargantext.Types (class Optional) import Prelude (class Eq, class Show, bind, map, pure, show, ($), (+), (<<<), (<>)) import Record as Record import Record.Unsafe (unsafeSet) import Simple.JSON as JSON import Unsafe.Coerce (unsafeCoerce) newtype SeriesType = SeriesType String type SeriesName = String data Chart = Line | Bar | PictorialBar | Pie | Scatter | EffectScatter | Radar | Trees | Sunburst | Boxplot | Candlestick | Heatmap | Map | Parallel | Lines | Graph | Sankey | Funnel | Gauge | ThemeRiver -- Trees instance Show Chart where show Bar = "bar" show EffectScatter = "effectScatter" -- ^ https://ecomfe.github.io/echarts-examples/public/editor.html?c=scatter-effect show Funnel = "funnel" show Heatmap = "heatmap" show Line = "line" show Pie = "pie" show Sankey = "sankey" show Scatter = "scatter" -- ^ https://ecomfe.github.io/echarts-examples/public/editor.html?c=scatter-simple show Sunburst = "sunburst" show _ = "not implemented yet: should throw error here" seriesType :: Chart -> SeriesType seriesType = SeriesType <<< show -- | Scatter Dimension 2 data type OptionalSeries = ( name :: String , symbolSize :: Number , itemStyle :: ItemStyle -- ^ Graphic style of, *emphasis* is the style when it is highlighted, like being hovered by mouse, or highlighted via legend connect. -- https://ecomfe.github.io/echarts-doc/public/en/option.html#series-scatter.itemStyle , tooltip :: Tooltip , emphasis :: { itemStyle :: ItemStyle } , selectedMode :: SelectedMode , select :: { itemStyle :: ItemStyle } -- ^ need "selectedMode" to be defined -- many more... ) data Series unsafeSeries :: forall o. Record o -> Series unsafeSeries = unsafeCoerce type RequiredSeriesD1 o = { "type" :: SeriesType , "data" :: Array DataD1 | o } seriesD1 :: forall o. Optional o OptionalSeries => RequiredSeriesD1 o -> Series seriesD1 = unsafeSeries seriesFunnelD1 :: forall o. Optional o OptionalSeries => Record o -> Array DataD1 -> Series seriesFunnelD1 o ds = unsafeSeries (unsafeSet "data" ds (unsafeSet "type" (seriesType Funnel) o)) seriesBarD1 :: forall o. Optional o OptionalSeries => Record o -> Array DataD1 -> Series seriesBarD1 o ds = unsafeSeries (unsafeSet "data" ds (unsafeSet "type" (seriesType Bar) o)) seriesPieD1 :: forall o. Optional o OptionalSeries => Record o -> Array DataD1 -> Series seriesPieD1 o ds = unsafeSeries (unsafeSet "data" ds (unsafeSet "type" (seriesType Pie) o)) type RequiredSeriesD2 o = { "data" :: Array DataD2 , "type" :: SeriesType | o } seriesD2 :: forall o. Optional o OptionalSeries => RequiredSeriesD2 o -> Series seriesD2 = unsafeSeries seriesScatterD2 :: forall o. Optional o OptionalSeries => Record o -> Array DataD2 -> Series seriesScatterD2 o ds = unsafeCoerce (unsafeSet "data" ds (unsafeSet "type" (seriesType Scatter) o)) type Node = { name :: String} type Link = { source :: String , target :: String , value :: Number } -- | Sankey Chart -- https://ecomfe.github.io/echarts-examples/public/editor.html?c=sankey-simple type RequiredSankey o = { "data" :: Array Node , links :: Array Link | o } type OptionalSankey = ( layout :: String ) seriesSankey :: forall o. Optional o OptionalSankey => RequiredSankey o -> Series seriesSankey o = unsafeSeries ((unsafeCoerce o) { "type" = seriesType Sankey }) -- | * Trees Chart -- All these Trees are hierarchical Trees structure (or diagram) -- https://en.wikipedia.org/wiki/Tree_structure -- Tree types data Trees = TreeLine | TreeRadial | TreeMap instance Show Trees where show TreeLine = "tree" -- ^ https://ecomfe.github.io/echarts-examples/public/editor.html?c=tree-radial show TreeRadial = "tree" -- ^ https://ecomfe.github.io/echarts-examples/public/editor.html?c=scatter-simple show TreeMap = "treemap" -- ^ https://ecomfe.github.io/echarts-examples/public/editor.html?c=treemap-simple -- TreeLine is a 1-Dimension horizontal hierchical Tree -- TreeRadial is 1-Dimension radial (as circle) Tree with no surface meaning -- https://en.wikipedia.org/wiki/Radial_tree -- https://ecomfe.github.io/echarts-examples/public/editor.html?c=tree-radial -- TreeMap is a is 2-Dimension Tree with surface meaning -- TreeMap example implementation: -- https://ecomfe.github.io/echarts-examples/public/editor.html?c=treemap-simple type RequiredTree o = { "type" :: SeriesType , "data" :: Array TreeNode | o } type OptionalTree = ( layout :: String ) seriesTree :: forall o. Optional o OptionalTree => RequiredTree o -> Series seriesTree = unsafeSeries mkTree :: Trees -> Array TreeNode -> Series mkTree t ts = seriesTree { "type" : SeriesType (show t) , "data" : map (toJsTree Nothing) ts , layout : layout } where layout = case t of TreeRadial -> "radial" _ -> "none" -- ** Data Structure of the Trees data TreeData = Array TreeNode treeValue :: TreeNode -> Int treeValue (TreeNode x) = foldl (+) 0 $ [x.value] <> map treeValue x.children toJsTree :: Maybe String -> TreeNode -> TreeNode toJsTree maybeSurname (TreeNode x) = unsafeCoerce { name : name , value : foldl (+) 0 $ [x.value] <> map treeValue x.children , children : (map (toJsTree (Just name)) x.children) } where name = maybe "" (\x' -> x' <> ">") maybeSurname <> x.name newtype TreeNode = TreeNode { children :: Array TreeNode , name :: String , value :: Int } derive instance Generic TreeNode _ derive instance Newtype TreeNode _ derive instance Eq TreeNode instance JSON.ReadForeign TreeNode where readImpl f = do inst <- JSON.readImpl f pure $ TreeNode $ Record.rename labelP nameP inst instance JSON.WriteForeign TreeNode where writeImpl (TreeNode t) = JSON.writeImpl $ Record.rename nameP labelP t treeNode :: String -> Int -> Array TreeNode -> TreeNode treeNode n v ts = TreeNode {name : n, value:v, children:ts} treeLeaf :: String -> Int -> TreeNode treeLeaf n v = TreeNode { name : n, value : v, children : []} nameP = SProxy :: SProxy "name" labelP = SProxy :: SProxy "label" -- | TODO -- https://ecomfe.github.io/echarts-examples/public/data/asset/data/life-expectancy-table.json -- https://ecomfe.github.io/echarts-examples/public/editor.html?c=scatter3D-dataset&gl=1