Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality for modifing graph metadata using UI #456

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion applications/graphs/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def map_attributes(attributes):
if attributes and isinstance(attributes, dict) and DataType.forValue(attributes) == DataType.DICT:
for key, value in attributes.items():
value_type = DataType.forValue(value)
#If we are removing tags and left with empty dictionary, just set type to String
if (key == 'tags'):
value_type = DataType.forValue("String")

key_prefix = value_type.prefix()
mapped_key = key_prefix + key if not key.startswith(key_prefix) else key
if value_type == DataType.DICT:
Expand Down Expand Up @@ -255,6 +259,12 @@ def update_graph(request, graph_id, name=None, is_public=None, graph_json=None,
if name is not None:
G.set_name(name)

db.remove_tags_by_graph_id(request.db_session, graph_id=graph_id)

# Add graph tags
for tag in G.get_tags():
add_graph_tag(request, graph_id, tag)

db.remove_nodes_by_graph_id(request.db_session, graph_id=graph_id)
# Add graph nodes
node_name_to_id_map = add_graph_nodes(request, graph_id, G.nodes(data=True))
Expand All @@ -263,7 +273,7 @@ def update_graph(request, graph_id, name=None, is_public=None, graph_json=None,

graph['graph_json'] = json.dumps(G.get_graph_json())

body_data.update(map_attributes(G.get_graph_json))
body_data.update(map_attributes(G.get_graph_json()))

updated_graph = db.update_graph(request.db_session, id=graph_id, updated_graph=graph)
# If any information in Elasticsearch was changed
Expand Down
4 changes: 4 additions & 0 deletions applications/graphs/dal.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ def add_tag(db_session, name):
db_session.add(tag)
return tag

@with_session
def remove_tags_by_graph_id(db_session, graph_id):
db_session.query(GraphToTag).filter(GraphToTag.graph_id == graph_id).delete()


@with_session
def get_layout(db_session, owner_email, name, graph_id):
Expand Down
17 changes: 17 additions & 0 deletions applications/graphs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,27 @@ def _update_graph(request, graph_id, graph={}):
------

It will update the owner_email only if user has admin access otherwise user cannot update the owner email.
Fetching graph_json from old graph if the updated graph does not contain 'graph_json' as it's attribute.
Updating title, description, tags in the graph_json if present accordingly.


"""
authorization.validate(request, permission='GRAPH_UPDATE', graph_id=graph_id)
user_role = authorization.user_role(request)
old_graph = _get_graph(request, graph_id)

if ('title' in graph) or ('description' in graph) or ('tags' in graph):
if not ('graph_json' in graph):
graph['graph_json'] = old_graph['graph_json']

if 'title' in graph:
graph['graph_json']['data']['title'] = graph['title']

if 'description' in graph:
graph['graph_json']['data']['description'] = graph['description']

if 'tags' in graph:
graph['graph_json']['data']['tags'] = graph['tags']

if 'update_legend_format' in graph:
return utils.serializer(graphs.update_graph_with_html_legend(request, graph_id=graph_id, param=graph))
Expand Down
56 changes: 56 additions & 0 deletions docs/Interacting_with_Graphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,60 @@ If a layout is shared with other users who have access to the graph, user can cl

If a layout is set as default layout, user can click on the `Remove as Default Layout` button to unset the layout as the default layout for the graph.

## Editing Graph Data Attributes

GraphSpace includes a user interface to modify the [Graph Data Attributes](https://github.com/Murali-group/GraphSpace/blob/master/docs/GraphSpace_Network_Model.md#graph-data-attributes).
Through this interface a [GraphSpace](http://www.graphspace.org) user will be able to:

- [Modify graph title](#edit-graph-title)
- [Modify graph name](#edit-graph-name)
- [Modify graph information/legend](#edit-graph-description)
- [Add/remove tags](#edit-graph-tags)

The user can activate this functionality by clicking the `Edit` button on the page for an individual network.

### Edit graph title

A [Graphspace](http://www.graphspace.org) user can edit the graph title by following the given steps:

1. Click on the `Edit` button present on the right top corner of the page given for an individual network.
2. Enter the **new title** in the space provided under the `Title` heading.
3. Click on `Save` if you want to save the changes else click on the `Cancel` button to discard the changes.
4. On clicking the `Save` button you will be notified with a success or error message based on whether **title** of the graph has been updated or not.

![editing title](_static/gifs/gs-screenshot-user1-wnt-signaling-pathway-edit-title.gif)

### Edit graph name

A [Graphspace](http://www.graphspace.org) user can edit the graph name by following the given steps:

1. Click on the `Edit` button present on the right top corner of the page given for an individual network.
2. Enter the **new name** in the space provided under the `Name` heading.
3. Click on `Save` if you want to save the changes else click on the `Cancel` button to discard the changes.
4. On clicking the `Save` button you will be notified with a success or error message based on whether **name** of the graph has been updated or not.

![editing name](_static/gifs/gs-screenshot-user1-wnt-signaling-pathway-edit-name.gif)

### Edit graph description

A [Graphspace](http://www.graphspace.org) user can edit the graph description/legend by following the given steps:

1. Click on the `Edit` button present on the right top corner of the page given for an individual network.
2. Navigate to the `Graph Information` Page.
3. Enter the **new description** in the space provided under the `Description` heading.
3. Click on `Save` if you want to save the changes else click on the `Cancel` button to discard the changes.
4. On clicking the `Save` button you will be notified with a success or error message based on whether **description** of the graph has been updated or not.

![editing description](_static/gifs/gs-screenshot-user1-wnt-signaling-pathway-edit-description.gif)

### Edit graph tags

A [Graphspace](http://www.graphspace.org) user can add/remove tags by following the given steps:

1. Click on the `Edit` button present on the right top corner of the page given for an individual network.
2. Enter the **new tags** in the space provided under the `Add/Remove tags` heading with space separation.
3. You can remove the **old tags** by clicking on the `x` symbol provided for each tag.
4. Click on `Save` if you want to save the changes else click on the `Cancel` button to discard the changes.
5. On clicking the `Save` button you will be notified with a success or error message based on whether **tags** of the graph have been updated or not.

![editing tags](_static/gifs/gs-screenshot-user1-wnt-signaling-pathway-edit-tags.gif)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions static/css/graphspace.css
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,23 @@ p.lead {
}
}

/* Edit Graph metadata UI */
#edit-graph-table tr {
font-size: 16px;
}

#edit-graph-table td, th {
padding-left: 10px;
}

#edit-graph-table button {
height: 40px;
width: 80px;
border-radius: 5px;
font-weight: bold;
font-size: 16px;
}

/* Alerts */
.alert {
width: 100%;
Expand Down
63 changes: 63 additions & 0 deletions static/js/graphs_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ var uploadGraphPage = {
var graphPage = {
cyGraph: undefined,
timeout: null,
tagsEditor: null,
init: function () {
/**
* This function is called to setup the graph page.
Expand Down Expand Up @@ -550,6 +551,19 @@ var graphPage = {
$( '#inputSearchEdgesAndNodes' ).val( searchquery ).trigger( 'onkeyup' );
}

graphPage.tagsEditor = $(".add-remove-tags").select2({
tags: true,
tokenSeparators: [',', ' '],
width: '99%'
});

//adding on click event handlers to buttons used for editing graphs.
$('#cancel-edit-btn').click(function () {
$('#edit-tab').css('display','none');
$('#view-tab').css('display','');
$('#edit-desc').css('display','none');
$('#view-desc').css('display','');
});

graphPage.defaultLayoutWidget.init();
},
Expand Down Expand Up @@ -741,6 +755,55 @@ var graphPage = {
)
);
},

updateGraphAttributesBtn: function (e, graph_id) {

//takes name,title, description and tags and updates them by sending an ajax request to server.
apis.graphs.update(graph_id, {
'name': $('#new_name').val(),
'title': $('#new_title').val(),
'description': $('#new_description').val(),
'tags': graphPage.tagsEditor.val()
},
successCallback = function (response) {
// This method is called when attributes of the graph(name, title, tags...etc) have been successfully updated.
$.notify({message: 'Successfully updated the graph with id=' + graph_id.toString()}, {type: 'success'});
location.reload();
},
errorCallback = function (xhr, status, errorThrown) {
// This method is called when error occurs while trying to update the graph attributes.
$.notify({
message: xhr.responseJSON.error_message
}, {
type: 'danger'
});

});
},
graphEditFormatter: function(e, title, name, description) {

//populating input tags with appropriate values before showing the edit panel.
$('#new_name').val(name);
$('#new_title').val(title);
$('#new_description').val(description);
var hyper_links = $('#Tags').children();
graphPage.tagsEditor.find('option').remove().end();
$.each(hyper_links, function(idx) {
var tag = $.trim(hyper_links[idx].text);
graphPage.tagsEditor.append(new Option(tag, tag, true, true));
}
);
graphPage.tagsEditor.trigger('change');

//hides view tab and displays edit tab.
$('#view-tab').css('display','none');
$('#edit-tab').css('display','');

//hides view description tab and displays edit description tab.
$('#view-desc').css('display','none');
$('#edit-desc').css('display','');
},

onShareGraphWithPublicBtn: function ( e, graph_id ) {

apis.graphs.update( graph_id, {
Expand Down
17 changes: 16 additions & 1 deletion templates/graph/graph_details_tab.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@
img {
max-width: 200px;
}
textarea {
width: 90%;
height: 150px;
padding: 12px 20px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
resize: none;
font-size: 15px;
}
</style>
<div class="row">
<div class="col-md-6">
<div class="col-md-6" id="view-desc">
<div style="font-weight: bold; font-size: 15px">Description</div><br/>
<!-- <div class="table-responsive" id="convertHtmlLegendOption" style="display:none">
<div class="panel panel-info">
<div class="panel-heading">
Expand All @@ -22,6 +33,10 @@ <h3 class="panel-title">Important Note</h3>
{{ description|safe }}
</table>
</div>
<div class="col-md-6" style="display:none" id="edit-desc">
<div style="font-weight: bold; font-size: 15px">Description</div><br/>
<textarea id="new_description"> {{ description | safe}} </textarea>
</div>
<div class="col-md-6">
<div class="table-responsive">
<table class="table table-bordered">
Expand Down
51 changes: 51 additions & 0 deletions templates/graph/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
var default_layout_id = {% if default_layout_id %}{{ default_layout_id|safe }}{% else %}null{% endif %};
{% endif %}
</script>
<link href="{% static 'components/select2/dist/css/select2.min.css' %}" rel="stylesheet"/>
<script src="{% static 'components/select2/dist/js/select2.full.min.js' %}"></script>

<!--- Modals start here--->
<div>
Expand Down Expand Up @@ -184,6 +186,48 @@ <h6 class="modal-title" id="myModalLabel">Save the current x- and y-coordinates
<!--- Modals end here--->
<div class="container-fluid zero-margin zero-padding">
<div class="row zero-margin zero-padding padding-top-2 padding-bottom-2">
<div class="row zero-margin zero-padding padding-top-2 padding-bottom-2" id="edit-tab" style="display:none">
<table style="width:100%;" id="edit-graph-table">
<tr>
<th>Title</th>
<th>Name</th>
</tr>
<tr>
<td style="width: 58%">
<input type="text" style="width:100%;height: 38px" id="new_title"/>
</td>
<td style="width: 30%">
<input type="text" style=" width:99%;height: 38px;" id="new_name"/>
</td>
</tr>
<tr>
<td>
<div style="font-weight: bold">
Add/Remove tags
</div>
<div style="font-size: 15px;color:grey;">
(Enter multiple tags with space seperation)
</div>
</td>
</tr>
<tr>
<td style="width:88%">
<select class="add-remove-tags gs-full-width" multiple="multiple">
</select>
</td>
<td>
<button type="button" class="btn btn-default btn-sm" onclick="graphPage.updateGraphAttributesBtn(this,{{ graph.id }})">
Save
</button>
or
<button type="button" class="btn btn-danger" id="cancel-edit-btn">
Cancel
</button>
</td>
</tr>
</table>
</div>
<div class="row zero-margin zero-padding padding-top-2 padding-bottom-2" id="view-tab">
<div class="col-md-10">
<p class="lead">
{{ title }}
Expand Down Expand Up @@ -234,6 +278,13 @@ <h4 class="zero-margin d-inline-block">
<li><a onclick="graphPage.export('style');">Network Stylesheet (.json)</a></li>
</ul>
</div>
{% if uid and uid == graph.owner_email %}
<div class="btn-group pull-right">
<button class="btn btn-default btn-sm" onclick="graphPage.graphEditFormatter(this, '{{title}}', '{{graph.name}}', '{{description}}')" style="margin-right: 1.2em;">
<i class="fa fa-edit fa-lg"></i> &nbsp;Edit
</button>
</div>
{% endif %}
</div>

</div>
Expand Down