From 5448099b80b0053f3c7cf30a2ac2fc1bc8e3cca8 Mon Sep 17 00:00:00 2001
From: Hammouda Elbez <hammouda.elbez@univ-lille.fr>
Date: Tue, 14 Mar 2023 17:23:28 +0100
Subject: [PATCH] FontAwsome added to UI

---
 VS2N.py                          |  2 +-
 src/Global_Var.py                | 28 ++++++++-----
 src/Modules/General/layout.py    |  4 +-
 src/Modules/Neuron/callbacks.py  |  4 +-
 src/Modules/Neuron/layout.py     |  2 +-
 src/Modules/Synapse/callbacks.py | 69 +++++++++++++++++++++++---------
 src/Modules/Synapse/layout.py    | 12 ++++--
 7 files changed, 82 insertions(+), 39 deletions(-)

diff --git a/VS2N.py b/VS2N.py
index 9a63eae..39a92a2 100755
--- a/VS2N.py
+++ b/VS2N.py
@@ -288,7 +288,7 @@ def processing():
 app_vis = dash.Dash(
     __name__,
     requests_pathname_prefix='/vis/',
-    external_stylesheets=[dbc.themes.BOOTSTRAP],
+    external_stylesheets=[dbc.themes.BOOTSTRAP,dbc.icons.FONT_AWESOME],
     suppress_callback_exceptions=True,
     title="VS2N")
 
diff --git a/src/Global_Var.py b/src/Global_Var.py
index ce8d739..5048ce8 100755
--- a/src/Global_Var.py
+++ b/src/Global_Var.py
@@ -9,7 +9,7 @@ from config import config
 import numpy as np
 import pymongo
 import socket
-import time
+import traceback
 
 
 class Global_Var():
@@ -84,8 +84,8 @@ class Global_Var():
             self.client.server_info() # will throw an exception if mongodb is not detected
             self.db = self.client.list_database_names()
             return 1
-        except Exception as e:
-            print("mongoConnect:" + str(e))
+        except Exception:
+            print("mongoConnect:" + traceback.format_exc())
             return 0
 
     def checkExistance(self, app, component):
@@ -175,12 +175,13 @@ class Global_Var():
 
         return x, y
 
-    def createHeatMap(self, x, y, data, depth):
+    def createHeatMap(self, x, y, data, depth, rotation):
         """ Create a heatmap from a set of synapses values .
 
         Args:
             x , y (int): shape 2D dimensions
             data (Array): synapses values
+            rotation: if to rotate the heatmap 90°
 
         Returns:
             Array: Heatmap vector
@@ -189,22 +190,27 @@ class Global_Var():
             heatmap = np.zeros((x, y))
             heatmap[:] = -1
             data = data.to_numpy()
-            
             if(depth == 0): # single depth
                 for d in data:
-                    heatmap[int(d[0])][int(d[1])] = d[3]
+                    if rotation:
+                        heatmap[int(d[0])][int(d[1])] = d[3]
+                    else:
+                        heatmap[int(d[1])][int(d[0])] = d[3]
             else: # multiple dimensions
                 for d in data:
                     if(d[2] == 0):
                     #if(heatmap[int(d[0])][int(d[1])] == -1):
-                        heatmap[int(d[0])][int(d[1])] = d[3]
+                        if rotation:
+                            heatmap[int(d[0])][int(d[1])] = d[3]
+                        else:
+                            heatmap[int(d[1])][int(d[0])] = d[3]
                     #else:
                     #    heatmap[int(d[0])][int(d[1])] = np.mean(heatmap[int(d[0])][int(d[1])]+d[3])
 
             return heatmap
         
-        except Exception as e:
-            print("createHeatMap: "+str(e))
+        except Exception:
+            print("createHeatMap: "+ traceback.format_exc())
 
     def createVerticalHeatMap(self, data):
         """ Create a vertical heat map from a given data array .
@@ -279,8 +285,8 @@ class Global_Var():
             if not self.config.DEBUG:
                 self.sparkSession.sparkContext.setLogLevel("Error")
             return self.sparkSession.version
-        except Exception as e:
-            print("createSparkSession:" + str(e))
+        except Exception:
+            print("createSparkSession:" + traceback.format_exc())
             return ""
         
 
diff --git a/src/Modules/General/layout.py b/src/Modules/General/layout.py
index 8809379..a73c001 100755
--- a/src/Modules/General/layout.py
+++ b/src/Modules/General/layout.py
@@ -308,10 +308,10 @@ class layout(layoutOp):
                 dcc.Tabs(tabs, id="tabs"),
                 # Control Layout
                 dbc.Row([
-                    html.Div([dbc.Button("<", id="btn-back", className="btn btn-default", style={"marginTop": "12px", "fontWeight": "500", "backgroundColor": "rgb(68, 71, 99)"}),
+                    html.Div([dbc.Button(html.I(className="fa-solid fa-angle-left"), id="btn-back", className="btn btn-default", style={"marginTop": "12px", "fontWeight": "500", "backgroundColor": "rgb(68, 71, 99)"}),
                               dbc.Button("Start", id="btnControle", className="btn btn-success", style={
                                          "marginTop": "12px", "marginLeft": "5px", "width": "100px", "fontWeight": "500"}),
-                              dbc.Button(">", id="btn-next", className="btn btn-default", style={"marginTop": "12px", "marginLeft": "5px", "fontWeight": "500", "backgroundColor": "rgb(68, 71, 99)"})], className="col-md-4 col-sm-12 col-lg-4"),
+                              dbc.Button(html.I(className="fa-solid fa-angle-right"), id="btn-next", className="btn btn-default", style={"marginTop": "12px", "marginLeft": "5px", "fontWeight": "500", "backgroundColor": "rgb(68, 71, 99)"})], className="col-md-4 col-sm-12 col-lg-4"),
                     html.Div([
                         html.Div([
                             html.Span("Update Speed (s)",
diff --git a/src/Modules/Neuron/callbacks.py b/src/Modules/Neuron/callbacks.py
index 96ea315..1db92ee 100755
--- a/src/Modules/Neuron/callbacks.py
+++ b/src/Modules/Neuron/callbacks.py
@@ -360,7 +360,7 @@ class callbacks(callbacksOp):
                             color="#28a745",
                             style={"marginLeft": "10px","marginRight": "10px"}
                             ),
-                            html.Div("−", className="btn-danger btn-circle", style={"fontWeight": "500","fontSize":"16px"}, id={"index": str(index), "type": "DeleteComponent"}),html.Div([html.Span(layer+" N: "+neuron, style={"fontSize": "13px", "paddingTop": "10px", "marginRight": "10px"}, className="badge alert-info")], className="d-flex", style={"direction": "rtl", "width": "100%"})], className="d-flex", style={"height": "35px"}),
+                            html.Button(html.I(className="fa-solid fa-trash"), style={"fontWeight": "500","fontSize":"16px", "marginLeft": "10px","color":"red","backgroundColor":"#00110000","border":"0"}, id={"index": str(index), "type": "DeleteComponent"}),html.Div([html.Span(layer+" N: "+neuron, style={"fontSize": "13px", "paddingTop": "10px", "marginRight": "10px"}, className="badge alert-info")], className="d-flex", style={"direction": "rtl", "width": "100%"})], className="d-flex", style={"height": "35px"}),
                             dcc.Graph(id={"index": str(index), "type": "FreqGraph", "layer": layer, "neuron": neuron}, style={
                             "width": "100%", "height": "290px"}, className="col-12", animate=False, config={"displaylogo": False}),
                         ], className="col-lg-4 col-sm-12 col-xs-12" if(g.finalLabels != None) else "col-lg-6 col-sm-12 col-xs-12"),
@@ -387,7 +387,7 @@ class callbacks(callbacksOp):
                             color="#28a745",
                             style={"marginLeft": "10px"})], className="row", style={"height": "35px"}),
                             dcc.Graph(id={"index": str(index), "type": "AccuracyGraph", "layer": layer, "neuron": neuron}, style={
-                            "width": "100%", "height": "290px"}, className="col-12", animate=False, config={"displaylogo": False})], className="col-lg-4 col-sm-6 col-xs-6" if(g.finalLabels != None) else "", style={} if(g.finalLabels != None) else {'display': 'none'})],className="row")], style={"background": "rgb(242, 248, 255)", "paddingBottom": "10px", "marginBottom": "10px", "margin": "5px", "borderRadius": "10px"}, id="VisComponent"+str(index))
+                            "width": "100%", "height": "290px"}, className="col-12", animate=False, config={"displaylogo": False})], className="col-lg-4 col-sm-6 col-xs-6" if(g.finalLabels != None) else "", style={} if(g.finalLabels != None) else {'display': 'none'})],className="row")], style={"background": "rgb(242, 248, 255)", "paddingBottom": "10px", "marginBottom": "10px", "padding": "5px", "borderRadius": "10px"}, id="VisComponent"+str(index))
 
             def addSpaceHolder(app):
                 """ Adds a space holder area when no graphs are selected.
diff --git a/src/Modules/Neuron/layout.py b/src/Modules/Neuron/layout.py
index 1ac5a3c..81c30ab 100755
--- a/src/Modules/Neuron/layout.py
+++ b/src/Modules/Neuron/layout.py
@@ -76,7 +76,7 @@ class layout(layoutOp):
                                     options=[],
                                     multi=False,
                                     style={'width': '150px', "marginLeft": "10px", "textAlign": "start"}),
-                                dbc.Button("+", id="AddComponentNeuron", n_clicks=0, style={
+                                dbc.Button(html.I(className="fa-solid fa-plus"), id="AddComponentNeuron", n_clicks=0, style={
                                     "fontWeight": "500", "marginLeft": "20px", "height": "36px", "backgroundColor": "rgb(68, 71, 99)", "borderColor": "rgb(68, 71, 99)"}), html.Div(id='clear-Neuron', children="False", style={'display': 'none'}), html.Div(id='display-Neuron', children="False", style={'display': 'none'})
                             ], className="d-flex"),
                             html.Div(id={'type': "GraphsAreaNeuron"}, children=[html.Div(id={'type': "OutputNeurons"}, children=[dcc.Graph(id="SpikePerNeuronFreq", figure=self.SpikePerNeuron3D(self.g), config={"displaylogo": False}, className="col-6"),
diff --git a/src/Modules/Synapse/callbacks.py b/src/Modules/Synapse/callbacks.py
index 739dca4..5bc3e67 100755
--- a/src/Modules/Synapse/callbacks.py
+++ b/src/Modules/Synapse/callbacks.py
@@ -41,9 +41,8 @@ class callbacks(callbacksOp):
                               [Input("AddComponentSynapse", "n_clicks"), Input(
                                   {"type": "DeleteComponent", "index": ALL}, "n_clicks")],
                               [State({"type": "GraphsAreaSynapse"}, "children"), State({"type": "GlobalHeatMapAreaSynapse"}, "children"),
-                               State("LayerFilterSynapse", "value"), State(
-                                  "NeuronFilterSynapse", "value")])
-                def InsertRemoveNewElement(addButtonClick, deleteButtonsClick, graphsArea, GlobalHeatmap, selectedLayer, selectedNeuron):
+                               State("LayerFilterSynapse", "value"), State("NeuronFilterSynapse", "value"),State("heatmapEditInfo", "data")])
+                def InsertRemoveNewElement(addButtonClick, deleteButtonsClick, graphsArea, GlobalHeatmap, selectedLayer, selectedNeuron, heatmapEditInfo):
                     """ Insert of remove element.
 
                     Args:
@@ -53,6 +52,7 @@ class callbacks(callbacksOp):
                         GlobalHeatmap (list): list of GLobalHeatma component children
                         selectedLayer (String): name of the selected layer
                         selectedNeuron (int): id of selected neuron
+                        heatmapEditInfo (Array): heatmap edit stats
 
                     Returns:
                         the updated content of 'GraphsAreaSynapse' and 'GlobalHeatMapAreaSynapse'
@@ -80,7 +80,7 @@ class callbacks(callbacksOp):
                                     data = self.getGlobalSynapseWeights(g,selectedLayer)
                                     super.globalHeatMap[selectedLayer] = data
 
-                            return [graphsArea, self.AddGlobalHeatmap(g, selectedLayer, data) if not data.empty else []]
+                            return [graphsArea, self.AddGlobalHeatmap(g, selectedLayer, data, heatmapEditInfo) if not data.empty else []]
                     else:
                         if(context[0]['prop_id'] != "."):
                             # Delete item
@@ -167,8 +167,8 @@ class callbacks(callbacksOp):
                     [Input("display-Synapse", "children")], [State("v-step", "children"), State("interval", "value"),
                     State({"index": MATCH, "layer": MATCH, "neuron": MATCH, "type": "SynapseFreqGraph"}, "id"),
                     State({"index": MATCH, "layer": MATCH, "neuron": MATCH, "type": 'Synapse-frequency-switch'}, 'on'),
-                    State({"index": MATCH, "layer": MATCH, "neuron": MATCH, "type": 'Synapse-HeatMap-switch'}, 'on')])
-                def processSynapseData(displayContent, sliderValue, updateInterval, selectedItem, isOnSynapseFreqGraph, isOnHeatmap):
+                    State({"index": MATCH, "layer": MATCH, "neuron": MATCH, "type": 'Synapse-HeatMap-switch'}, 'on'),State("heatmapEditInfo", "data")])
+                def processSynapseData(displayContent, sliderValue, updateInterval, selectedItem, isOnSynapseFreqGraph, isOnHeatmap, heatmapEditInfo):
                     """ Create two graphs using neuron synapses ('SynapseFreqGraph' and 'Heatmap')
 
                     Args:
@@ -178,6 +178,7 @@ class callbacks(callbacksOp):
                         selectedItem (list): selected neuron
                         isOnSynapseFreqGraph (bool): whether SynapseFreq graph is active or not
                         isOnHeatmap (bool): whether Heatmap graph is active or not
+                        heatmapEditInfo (Array): heatmap edit stats
 
                     Raises:
                         PreventUpdate: in case we don't want to update the content we rise this execption
@@ -201,7 +202,7 @@ class callbacks(callbacksOp):
                                 output = [self.synapseFreqDrawGraph(g, selectedItem["index"],
                                             data, super.xAxisSynapseFreqGraph[selectedItem["index"]], super.xAxisLabel[selectedItem["index"]], super.yAxisSynapseFreqGraph,
                                             super.HeatMapSynapseFreqGraph, isOnSynapseFreqGraph),
-                                            self.heatMap(g, selectedItem["index"], data, super.heatmaps, isOnHeatmap)]
+                                            self.heatMap(g, selectedItem["index"], data, super.heatmaps, isOnHeatmap, heatmapEditInfo)]
                                 
                                 return output
                             else:
@@ -217,7 +218,7 @@ class callbacks(callbacksOp):
                                 output = [self.synapseFreqDrawGraph(g, selectedItem["index"],
                                             data, super.xAxisSynapseFreqGraph[selectedItem["index"]], super.xAxisLabel[selectedItem["index"]], super.yAxisSynapseFreqGraph,
                                             super.HeatMapSynapseFreqGraph, isOnSynapseFreqGraph),
-                                            self.heatMap(g, selectedItem["index"], data, super.heatmaps, isOnHeatmap)]
+                                            self.heatMap(g, selectedItem["index"], data, super.heatmaps, isOnHeatmap, heatmapEditInfo)]
                                 
                                 return output
                             else:
@@ -237,7 +238,7 @@ class callbacks(callbacksOp):
                             output = [self.synapseFreqDrawGraph(g, selectedItem["index"],
                                         data, super.xAxisSynapseFreqGraph[selectedItem["index"]], super.xAxisLabel[selectedItem["index"]], super.yAxisSynapseFreqGraph,
                                         super.HeatMapSynapseFreqGraph, isOnSynapseFreqGraph),
-                                        self.heatMap(g, selectedItem["index"], data, super.heatmaps, isOnHeatmap)]
+                                        self.heatMap(g, selectedItem["index"], data, super.heatmaps, isOnHeatmap, heatmapEditInfo)]
                             
                             return output
                         else:
@@ -266,7 +267,34 @@ class callbacks(callbacksOp):
                         return [isTabOpen]
             except Exception:
                 print("GlobalHeatMapTab: "+ traceback.format_exc())
+            
+            try:
+                # Callback to handle heatmap flipping if needed
+                @app.callback([Output("heatmapEditInfo", "data")],[Input('FlipHeatmapH', 'n_clicks'),Input('FlipHeatmapV', 'n_clicks'),Input('RotateHeatmap', 'n_clicks'),State("heatmapEditInfo", "data")])
+                def HeatmapFlip(FlipHeatmapH, FlipHeatmapV, RotateHeatmap, heatmapEditInfo):
+                    """ Function called when flip button clicked
+
+                    Args:
+                        FlipHeatmapH (int): number of clicks on the FlipHeatmapH button
+                        FlipHeatmapV (int): number of clicks on the FlipHeatmapV button
+                        RotateHeatmap (int): number of clicks on the RotateHeatmap button
+                        heatmapEditInfo (Array): heatmap edit stats
+
+                    Returns:
+                        if global heatmaps tab should be opened or closed
+                    """
+                    context = dash.callback_context.triggered
+                    if "FlipHeatmapH" in context[0]['prop_id']:
+                        heatmapEditInfo[0] = not heatmapEditInfo[0]
+                    elif "FlipHeatmapV" in context[0]['prop_id']:
+                        heatmapEditInfo[1] = not heatmapEditInfo[1]
+                    else:
+                        heatmapEditInfo[2] = not heatmapEditInfo[2]
 
+                    return [heatmapEditInfo]
+            except Exception:
+                print("HeatmapFlip: "+ traceback.format_exc())
+            
     try:
 
         # ------------------------------------------------------------
@@ -293,7 +321,7 @@ class callbacks(callbacksOp):
                             id={"index": str(index), "layer": layer, "neuron": neuron,
                                 "type": "Synapse-frequency-switch"},
                             on='True', size=25, color="#28a745", style={"marginLeft": "10px"}),
-                            html.Div("−", className="btn-danger btn-circle", style={"fontWeight": "500","fontSize":"16px", "marginLeft": "10px"}, id={"index": str(index), "type": "DeleteComponent"}),
+                            html.Button(html.I(className="fa-solid fa-trash"), style={"fontWeight": "500","fontSize":"16px", "marginLeft": "10px","color":"red","backgroundColor":"#00110000","border":"0"}, id={"index": str(index), "type": "DeleteComponent"}),
                             html.Div([html.Span(layer+" N: "+neuron, style={"fontSize": "13px", "paddingTop": "10px", "marginRight": "10px"}, className="badge alert-info")], className="d-flex", style={"direction": "rtl", "width": "100%"})], className="d-flex", style={"height": "35px"}),
                         dcc.Graph(id={"index": str(index), "type": "SynapseFreqGraph", "layer": layer, "neuron": neuron}, style={
                             "width": "100%", "height": "290px"}, className="col-12", animate=False, config={"displaylogo": False}),
@@ -309,7 +337,7 @@ class callbacks(callbacksOp):
                             )], className="d-flex", style={"height": "35px", "direction": "rtl", "paddingRight": "30px"}),
                         dcc.Graph(id={"index": str(index), "type": "Heatmap", "layer": layer, "neuron": neuron}, style={"width": "100%", "height": "290px"}, className="col-12", animate=False, config={"displaylogo": False}),
                     ], className="col-lg-6 col-sm-12 col-xs-12")
-                ], className="row", style={"margin": "10px"})
+                ], className="row", style={"padding": "10px"})
 
             ], style={"background": "rgb(242, 248, 255)", "paddingBottom": "10px", "marginBottom": "10px",
                       "margin": "5px", "borderRadius": "10px"},
@@ -331,13 +359,14 @@ class callbacks(callbacksOp):
                 id="spaceHolder")
 
 
-        def AddGlobalHeatmap(self, g, selectedLayer, data):
+        def AddGlobalHeatmap(self, g, selectedLayer, data, heatmapEditInfo):
             """ Add global heatmap for selected layer.
 
             Args:
                 g (Global_Var): reference to access global variables
                 selectedLayer (String): layer name
                 data (dataframe): synapses weights of all neurons in the layer
+                heatmapEditInfo (Array): heatmap edit stats
 
             Returns:
                 html component that contains the global heatmaps
@@ -368,11 +397,14 @@ class callbacks(callbacksOp):
                                 zmin=0,
                                 zmax=1,
                                 z=g.createHeatMap(
-                                    heatMapX, heatMapY, data[data.To == index],depth),
+                                    heatMapX, heatMapY, data[data.To == index],depth, heatmapEditInfo[2]),
                                 colorscale='jet',
                                 name=str(index)),
                             row=xx, col=yy)
-                        fig.update_yaxes(autorange="reversed", row=xx, col=yy)
+                        if heatmapEditInfo[0]:
+                            fig.update_xaxes(autorange="reversed")
+                        if heatmapEditInfo[1]:
+                            fig.update_yaxes(autorange="reversed")
                         fig.update_layout(height=80, width=80)
                         index += 1
 
@@ -545,7 +577,7 @@ class callbacks(callbacksOp):
             except Exception:
                 print("synapseFreqDrawGraph: "+ traceback.format_exc())
 
-        def heatMap(self, g, index, data, heatmaps, isOn):
+        def heatMap(self, g, index, data, heatmaps, isOn, heatmapEditInfo):
             """ Create heatmap for selected neuron synapses.
 
             Args:
@@ -554,6 +586,7 @@ class callbacks(callbacksOp):
                 data (list): data to be added to the graph
                 heatmaps (list): list of heatmaps created
                 isOn (bool): whether this graph is active or not
+                heatmapEditInfo (Array): heatmap edit stats
 
             Returns:
                 heatmap content (data and layout)
@@ -563,8 +596,8 @@ class callbacks(callbacksOp):
                 layout = go.Layout(
                             margin={'l': 0, 'r': 0, 't': 0, 'b': 25},
                             uirevision='no reset of zoom',
-                            yaxis={"autorange": "reversed"},
-                            xaxis={'showticklabels': False,"ticks":"inside"},
+                            xaxis={'showticklabels': False,"ticks":"inside","autorange": "reversed"} if heatmapEditInfo[0] else {'showticklabels': False,"ticks":"inside"},
+                            yaxis={"autorange": "reversed"} if heatmapEditInfo[1] else {},
                             width=400, height=300,
                             paper_bgcolor= "rgba(255, 255, 255,0)",
                             plot_bgcolor= "rgba(255, 255, 255,0)")
@@ -590,7 +623,7 @@ class callbacks(callbacksOp):
                                 print("heatMap1: "+ traceback.format_exc())
                         return {'data': [
                             go.Heatmap(
-                                z=g.createHeatMap(heatMapX, heatMapY, pd.DataFrame(heatMapWithIndexs), depth),
+                                z=g.createHeatMap(heatMapX, heatMapY, pd.DataFrame(heatMapWithIndexs), depth, heatmapEditInfo[2]),
                                 zmin=0,
                                 zmax=1,
                                 colorscale="jet")],
diff --git a/src/Modules/Synapse/layout.py b/src/Modules/Synapse/layout.py
index d73a80f..6b981d0 100755
--- a/src/Modules/Synapse/layout.py
+++ b/src/Modules/Synapse/layout.py
@@ -56,6 +56,7 @@ class layout(layoutOp):
                     [
                         html.Div(id="synapse-vis", children=[
                         html.Div([
+                        dcc.Store(id="heatmapEditInfo",data=[False,False,False]),
                         dcc.Dropdown(
                         id='LayerFilterSynapse',
                         options=[{'label': str(i), 'value': str(i)} for i in (
@@ -64,11 +65,14 @@ class layout(layoutOp):
                         dcc.Dropdown(
                         id='NeuronFilterSynapse', options=[], multi=False,
                         style={'width': '150px', "marginLeft": "10px", "textAlign": "start"}),
-                        dbc.Button("+", id="AddComponentSynapse", n_clicks=0, style={
+                        dbc.Button(html.I(className="fa-solid fa-plus"), id="AddComponentSynapse", n_clicks=0, style={
                         "fontWeight": "500", "marginLeft": "20px", "height": "36px",
-                        "backgroundColor":"rgb(68, 71, 99)","borderColor":"rgb(68, 71, 99)"})         
-                        ,html.Div(id='clear-Synapse',children="False", style={'display': 'none'})
-                        ,html.Div(id='display-Synapse',children="False", style={'display': 'none'})
+                        "backgroundColor":"rgb(68, 71, 99)","borderColor":"rgb(68, 71, 99)"}),
+                        dbc.Button(html.I(className="fa-solid fa-left-right"), id="FlipHeatmapH", n_clicks=0, style={"fontWeight": "500", "marginLeft": "20px", "height": "36px","backgroundColor":"rgb(68, 71, 99)","borderColor":"rgb(68, 71, 99)", "color":"white"}),
+                        dbc.Button(html.I(className="fa-solid fa-up-down"), id="FlipHeatmapV", n_clicks=0, style={"fontWeight": "500", "marginLeft": "20px", "height": "36px","backgroundColor":"rgb(68, 71, 99)","borderColor":"rgb(68, 71, 99)", "color":"white"}),
+                        dbc.Button(html.I(className="fa-solid fa-rotate"), id="RotateHeatmap", n_clicks=0, style={"fontWeight": "500", "marginLeft": "20px", "height": "36px","backgroundColor":"rgb(68, 71, 99)","borderColor":"rgb(68, 71, 99)", "color":"white"}),
+                        html.Div(id='clear-Synapse',children="False", style={'display': 'none'}),
+                        html.Div(id='display-Synapse',children="False", style={'display': 'none'})
                     ], className="d-flex", style={"paddingBottom": "10px"}),
                         dbc.Card( dbc.CardBody([dbc.Card([dbc.CardHeader(
                         dbc.Button( "Layer HeatMap", color="none",
-- 
GitLab