Skip to content
Snippets Groups Projects
Commit 9c764e66 authored by acc71121's avatar acc71121
Browse files

init

parents
Branches main
No related tags found
No related merge requests found
Showing
with 351 additions and 0 deletions
## Installation
Install necessary libraries with pip:
```bash
pip install -r requirements.txt
```
## Run
```bash
python3 app.py
```
app.py 0 → 100644
import dash
from dash import html, no_update
from dash import dcc, dash_table
import dash_cytoscape as cyto
from dash.dependencies import Input, Output, State
import json
import pandas as pd
import functions
from dash.exceptions import PreventUpdate
import base64
POSSIBLE_VALUES = ['X', 'XY', 'XYZ']
EXPRESSION_VALUES = ['X(?!.*Y)', 'Y(?!.*Z)', 'Z']
COLUMNS = ['graph_1', 'graph_2', 'cstr_1','cstr_2','phon_aff_1','phon_aff_2','generalization_1','generalization_2','phon_stem_1','phon_stem_2']
COLUMN_NAMES = ['graph1', 'graph2', 'cstr1','cstr2','aff1','aff2','gen1','gen2','phon1','phon2']
TAGS = ['Vmii---:', 'Vmip3p-:', 'Vmip-s-:', 'Vmpp---:','Vmmp-s-:', 'Vmmp-p-:', 'Vmsp-s-:', 'Vmsp-p-:', 'Vmn----:', 'Vmif---:', 'Vmis---:', 'Vmps---:']
# Loading data into a Pandas DataFrame
data = pd.read_csv('data/data.csv', sep='\t', lineterminator='\n', encoding='utf8', dtype='unicode')
nodes_list = data['generalization_1'].to_list()
nodes_list += data['generalization_2'].to_list()
nodes_list = set(nodes_list)
nodes_list = list(nodes_list)
# Extraction of unique labels
unique_labels = nodes_list
elements_dict = {}
# Compute nodes and edges for each filter and store in the dictionary
for filter_value in POSSIBLE_VALUES:
elements = functions.compute_nodes_and_edges(data, filter_value)
elements_dict[filter_value] = elements
app = dash.Dash(__name__)
app.title = "GenGraph"
frame = html.Div(
className='frame', # Style for InformationFrame
style={
'border': '1px solid #ccc',
'padding': '1px',
'margin-bottom': '20px',
'font-size': '18px',
'font-family': 'monospace',
'font-weight': 'bold',
'color': '#5f9ea0'
},
children=[
html.P("1. Choose desired Generalyzation Pattern and wait till the graph nodes arranged"),
html.P("2. Scroll to zoom in and out the frame, drag canvas to move arround"),
html.P("3. Drag nodes to place them as needed"),
html.P("4. Click on the node to display all the relations that include respective generalization"),
html.P("5. Search table, filter the entries"),
html.P("6. Export filtered data as csv table"),
html.P("__"),
html.P("1. Choisissez le modèle de généralisation souhaité et attendez que les nœuds du graphique soient arrangés"),
html.P("2. Faites défiler pour zoomer et dézoomer le cadre, faites glisser le canevas pour le déplacer"),
html.P("3. Faites glisser les nœuds pour les placer selon vos besoins"),
html.P("4. Cliquez sur le nœud pour afficher toutes les relations qui incluent la généralisation respective"),
html.P("5. Recherche dans le tableau, filtrage des entrées, survol des étiquettes de généralisation pour voir la comparaison"),
html.P("6. Exporter les données filtrées sous forme de tableau csv"),
]
)
# Dash_cytoscape Defenition
layout={'name': 'cose', 'idealEdgeLength': 40, 'nodeOverlap': 5000, 'refresh': 40, 'fit': True, 'padding': 20, 'randomize': False, 'componentSpacing': 100, 'nodeRepulsion': 1000000, 'edgeElasticity': 100, 'nestingFactor': 3, 'gravity': 10, 'numIter': 200, 'initialTemp': 100}
# Layout Defenition
app.layout = html.Div(
className='container',
children=[
html.Div(
className='graph-container',
children=[
html.Label('Generate Graph according to Generalization pattern:', className='label'),
html.Div (
children = [
dcc.Dropdown(
id='dropdown1',
options=[
{'label': value, 'value': value} for value in POSSIBLE_VALUES
],
style={'width': '45%', 'margin-bottom': '5px', 'margin-top': '5px'},
clearable=True
),
]
),
cyto.Cytoscape(
id='graph',
elements=[],
layout=layout,
style={
'height': '700px',
'border': '3px solid #ccc',
'padding': '1px',
'margin-bottom': '20px',
'width': '40%',
'display': 'inline-block',
},
),
html.Div(
className='table-container',
id='dialogue-container',
children = [
dash_table.DataTable(id = 'table')
],
style={'width': '58%',
'display': 'inline-block',
'float': 'right'}
),
html.Button("Save as JSON", id="save-button", className="export"),
dcc.Download(id="download"),
dcc.Upload(
id='upload-data',
children=html.Div([
'Drag and Drop or ',
html.A('Select Files')
]),
style={
'width': '100%',
'height': '60px',
'lineHeight': '60px',
'borderWidth': '1px',
'borderStyle': 'dashed',
'borderRadius': '5px',
'textAlign': 'center',
'margin': '10px'
},
multiple=False
),
dcc.Markdown(id='cytoscape-selectedNodeData-markdown')
]
),
]
)
# Callback to output filtered table based on the node tapped
@app.callback(Output('dialogue-container', 'children', allow_duplicate=True),
Input('graph', 'tapNodeData'),
prevent_initial_call=True)
def displayTapNodeData(input):
if input:
filtered_data = data[
((data['generalization_1'].str.contains(f"^{input['label'].split(' ')[0]}$", regex=True)) |
(data['generalization_2'].str.contains(f"^{input['label'].split(' ')[0]}$", regex=True)))
]
tooltip_data = [
{
column: {'value': functions.define_value(row,column,value), 'type': 'markdown'}
for column, value in row.items()
} for row in filtered_data.to_dict('records')
]
table = dash_table.DataTable(
columns = [{"name": name, "id": col} for col, name in zip(COLUMNS, COLUMN_NAMES)],
data=filtered_data.to_dict('records'),
style_cell={
'overflow': 'hidden',
'textOverflow': 'ellipsis',
'maxWidth': 200
},
tooltip_data = tooltip_data,
css=[{
'selector': '.dash-table-tooltip',
'rule': 'background-color: white; font-family: monospace; color: black;position:absolute'
}],
tooltip_duration=None,
filter_action="native",
page_size=20,
export_format='csv'
)
return table
else:
return frame
# Callback to output filtered table based on the edge tapped
@app.callback(Output('dialogue-container', 'children'),
Input('graph', 'tapEdgeData'))
def displayTapNodeData(input):
if input:
filtered_data = data[
((data['generalization_1'].str.contains(f"^{input['target'].split(' ')[0]}$", regex=True)) &
(data['generalization_2'].str.contains(f"^{input['source'].split(' ')[0]}$", regex=True))) +
((data['generalization_2'].str.contains(f"^{input['target'].split(' ')[0]}$", regex=True)) &
(data['generalization_1'].str.contains(f"^{input['source'].split(' ')[0]}$", regex=True)))
]
tooltip_data = [
{
column: {'value': functions.define_value(row,column,value), 'type': 'markdown'}
for column, value in row.items()
} for row in filtered_data.to_dict('records')
]
table = dash_table.DataTable(
columns = [{"name": name, "id": col} for col, name in zip(COLUMNS, COLUMN_NAMES)],
data=filtered_data.to_dict('records'),
style_cell={
'overflow': 'hidden',
'textOverflow': 'ellipsis',
'maxWidth': 200
},
tooltip_data = tooltip_data,
css=[{
'selector': '.dash-table-tooltip',
'rule': 'background-color: white; font-family: monospace; color: black;position:absolute'
}],
tooltip_duration=None,
filter_action="native",
page_size=20,
export_format='csv'
)
return table
else:
return frame
# Callback to update the graph
@app.callback(
Output('graph', 'layout', allow_duplicate=True),
Output('graph', 'elements', allow_duplicate=True),
Output('dropdown1', 'value'),
Input('dropdown1', 'value'),
prevent_initial_call=True
)
def update_graph(filter1):
return layout, elements_dict.get(filter1, []), []
# Callback to save json of the graph
@app.callback(
Output("download", "data"),
[Input("save-button", "n_clicks")],
[State("graph", "elements")],
prevent_initial_call=True
)
def save_as_json(n_clicks, elements):
if n_clicks:
content = json.dumps(elements)
return {
"content": content,
"filename": "graph_elements.json"
}
raise PreventUpdate
# Callback to upload the layout of cytoscape from json
@app.callback(
Output("graph", "layout"),
Output("graph", "elements"),
[Input("upload-data", "contents")],
prevent_initial_call=True
)
def update_elements(contents):
if contents:
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
new_elements = json.loads(decoded)
return {
"name": "preset",
#"positions": {element["data"]["id"]: element["position"] for element in new_elements if "position" in element},
#"style": {element["data"]["id"]: element["style"] for element in new_elements if "position" in element}
}, new_elements
raise PreventUpdate
if __name__ == '__main__':
app.run_server( app.run_server(host='0.0.0.0', debug=True, port=8050))
\ No newline at end of file
assets/favicon.ico

14.7 KiB

.export {
color: #fff;
background-color: #5f9ea0;
border-color: #17a2b8;
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border: 1px solid transparent;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: .25rem;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
margin-bottom: 3px;
}
.label {
font-weight: bold;
font-family: monospace;
color:darkcyan;
}
.dataTable {
width: 50%;
margin: auto;
}
.cytoscape {
width: 40%;
border: 3px solid #ccc;
padding: 1px;
margin-bottom: 20px;
display: inline-block;
}
.dropdown {
width: 35%;
margin-bottom: 5px;
margin-top: 5px;
}
assets/tmp/0005f280c496b268ba89cb3118a34212.jpg

1.88 KiB

assets/tmp/0006610bb4eb3d2eea9f8277e2a8e708.jpg

1.97 KiB

assets/tmp/00090106ac218c4cbac9a42f60c3588b.jpg

1.62 KiB

assets/tmp/001339530ad91e6b16b842fd219d2801.jpg

1.81 KiB

assets/tmp/001699fe693a2989903d34801ae96eb1.jpg

1.82 KiB

assets/tmp/001e556ab3ff1dbe9ad009fae3ebacfb.jpg

1.44 KiB

assets/tmp/002fa56cbfba91cc0462f1c6487c7971.jpg

2.06 KiB

assets/tmp/00355f70c8e23af9cd62f6981fbc7077.jpg

1.96 KiB

assets/tmp/00388b365017ea1bbf516a1bb74694f8.jpg

1.32 KiB

assets/tmp/0039ad914a13c9c9cd3d9ee3ff895298.jpg

1.56 KiB

assets/tmp/0039f7549e8b2ab676ae43a0a5dc2a96.jpg

1.31 KiB

assets/tmp/0041c140a00dc4cdb1a5f8e5043e5457.jpg

1.95 KiB

assets/tmp/0046cee62be061dbbba7629ea813f3ed.jpg

2.46 KiB

assets/tmp/00491609e6fea1f6c0b54547d0292d32.jpg

2.25 KiB

assets/tmp/0051394532de08ce51281531febeacd8.jpg

1.27 KiB

assets/tmp/00569ecae9b29097fb39bb600e2e8127.jpg

1.78 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment