Commit 5ce2b2e2 authored by Janez's avatar Janez

Merge branch 'graphs' of /home/git/repositories/kt/mothra

parents c58fe07d 2f9b6219
[
{
"pk": 20,
"model": "workflows.category",
"fields": {
"uid": "c11e969f-cac7-493c-b65c-471b7c4ea59b",
"parent": null,
"workflow": null,
"user": null,
"order": 1,
"name": "Graphs"
}
},
{
"pk": 98,
"model": "workflows.abstractwidget",
"fields": {
"category": 20,
"treeview_image": "",
"name": "Create Integer List",
"is_streaming": false,
"uid": "ef19723e-f6bf-4429-87c9-0dc961848da3",
"interaction_view": "",
"image": "",
"package": "graphs",
"static_image": "construction_work .png",
"post_interact_action": "",
"user": null,
"visualization_view": "",
"action": "graphs_create_integers",
"wsdl_method": "",
"wsdl": "",
"interactive": false,
"has_progress_bar": false,
"order": 1,
"description": ""
}
},
{
"pk": 248,
"model": "workflows.abstractinput",
"fields": {
"widget": 98,
"name": "Integer List String",
"short_name": "str",
"uid": "572f1ff6-2e49-49f6-8eff-0d14882387a1",
"default": "3\r\n2\r\n1\r\n4",
"required": false,
"multi": false,
"parameter_type": "textarea",
"variable": "intStr",
"parameter": true,
"order": 1,
"description": "Comma or new-line separated list of integers"
}
},
{
"pk": 253,
"model": "workflows.abstractinput",
"fields": {
"widget": 98,
"name": "Sort list",
"short_name": "bol",
"uid": "aaa5de34-4649-4a92-aba4-5541d35190fe",
"default": "true",
"required": true,
"multi": false,
"parameter_type": "checkbox",
"variable": "sort",
"parameter": true,
"order": 2,
"description": "Should the list be sorted"
}
},
{
"pk": 104,
"model": "workflows.abstractoutput",
"fields": {
"widget": 98,
"name": "Integer List",
"short_name": "lst",
"variable": "intList",
"uid": "66313be2-7f5e-4bb7-a5b0-6772f7522206",
"order": 1,
"description": "List of integers"
}
},
{
"pk": 101,
"model": "workflows.abstractwidget",
"fields": {
"category": 20,
"treeview_image": "",
"name": "Filter Integers",
"is_streaming": false,
"uid": "7968fad4-eaee-48eb-ab83-f8df800726de",
"interaction_view": "graphs_filter_integers",
"image": "",
"package": "graphs",
"static_image": "construction_work .png",
"post_interact_action": "graphs_post_filter_integers",
"user": null,
"visualization_view": "",
"action": "graphs_pre_filter_integers",
"wsdl_method": "",
"wsdl": "",
"interactive": true,
"has_progress_bar": false,
"order": 2,
"description": ""
}
},
{
"pk": 250,
"model": "workflows.abstractinput",
"fields": {
"widget": 101,
"name": "Integer List",
"short_name": "lst",
"uid": "ad5fff6e-8266-465d-a112-05be0221147d",
"default": "",
"required": true,
"multi": false,
"parameter_type": null,
"variable": "intList",
"parameter": false,
"order": 1,
"description": "List of integers"
}
},
{
"pk": 106,
"model": "workflows.abstractoutput",
"fields": {
"widget": 101,
"name": "Filtered Integer List",
"short_name": "lst",
"variable": "intList",
"uid": "d668ae94-05af-4f18-9ca8-4150883a82f8",
"order": 1,
"description": "Filtered list of integers"
}
},
{
"pk": 99,
"model": "workflows.abstractwidget",
"fields": {
"category": 20,
"treeview_image": "",
"name": "Sum Integers",
"is_streaming": false,
"uid": "8fab8b54-05cf-4b00-a4cd-a91791ef29ab",
"interaction_view": "",
"image": "",
"package": "graphs",
"static_image": "construction_work .png",
"post_interact_action": "",
"user": null,
"visualization_view": "",
"action": "graphs_sum_integers",
"wsdl_method": "",
"wsdl": "",
"interactive": false,
"has_progress_bar": false,
"order": 3,
"description": ""
}
},
{
"pk": 249,
"model": "workflows.abstractinput",
"fields": {
"widget": 99,
"name": "Integer List",
"short_name": "lst",
"uid": "0bea4e32-379b-458b-809c-1969203d8e69",
"default": "",
"required": true,
"multi": false,
"parameter_type": null,
"variable": "intList",
"parameter": false,
"order": 1,
"description": "List of integers"
}
},
{
"pk": 105,
"model": "workflows.abstractoutput",
"fields": {
"widget": 99,
"name": "Sum",
"short_name": "int",
"variable": "sum",
"uid": "c93c814d-f512-4445-a1c7-0a0e90e48d3d",
"order": 1,
"description": "Sum of integer list"
}
},
{
"pk": 100,
"model": "workflows.abstractwidget",
"fields": {
"category": 20,
"treeview_image": "",
"name": "Display Summation",
"is_streaming": false,
"uid": "7ba1842e-0b72-441b-b820-d4bc37597d73",
"interaction_view": "",
"image": "",
"package": "graphs",
"static_image": "construction_work .png",
"post_interact_action": "",
"user": null,
"visualization_view": "graphs_display_summation",
"action": "graphs_pre_display_summation",
"wsdl_method": "",
"wsdl": "",
"interactive": false,
"has_progress_bar": false,
"order": 4,
"description": ""
}
},
{
"pk": 251,
"model": "workflows.abstractinput",
"fields": {
"widget": 100,
"name": "Integer List",
"short_name": "lst",
"uid": "2bbc19f6-e0fb-49d2-b835-fc40b4d841ce",
"default": "",
"required": false,
"multi": false,
"parameter_type": null,
"variable": "intList",
"parameter": false,
"order": 1,
"description": "List of integers"
}
},
{
"pk": 252,
"model": "workflows.abstractinput",
"fields": {
"widget": 100,
"name": "Sum",
"short_name": "int",
"uid": "63b93459-6277-4d3e-98a8-523e3377371d",
"default": "",
"required": false,
"multi": false,
"parameter_type": null,
"variable": "sum",
"parameter": false,
"order": 2,
"description": "Sum (possibly correct) of integer list"
}
}
]
\ No newline at end of file
from django.shortcuts import render
def graphs_filter_integers(request,input_dict,output_dict,widget):
return render(request, 'interactions/graphs_filter_integers.html',{'widget':widget,'intList':input_dict['intList']})
\ No newline at end of file
import re
def graphs_create_integers(input_dict):
intStr = input_dict['intStr']
intList = []
for i in re.findall(r'\w+', intStr):
try:
intList.append(int(i))
except:
pass
if input_dict['sort'].lower() == "true":
intList.sort()
return {'intList':intList}
def graphs_sum_integers(input_dict):
intList = input_dict['intList']
return {'sum':sum(intList)}
def graphs_pre_filter_integers(input_dict):
return input_dict
def graphs_post_filter_integers(postdata,input_dict,output_dict):
intListOut = postdata['intListOut']
intList = []
for i in intListOut:
try:
intList.append(int(i))
except:
pass
return {'intList': intList}
def graphs_pre_display_summation(input_dict):
return {}
###########################################
def graphs_visualize_visjs(input_dict):
return {}
def graphs_json2networkx(input_dict):
from json import loads
from networkx.readwrite import json_graph
gtext = loads(input_dict['graph'])
g = json_graph.node_link_graph(gtext)
return {'nxgraph': g}
\ No newline at end of file
{
"model": "workflows.category",
"fields": {
"name": "Visualization",
"parent": "d67b50ed-fd8a-4f91-aeb4-a9a19678f3fa",
"order": 1,
"uid": "09b22013-3469-497c-86e7-6d71ce9c78cd"
}
}
\ No newline at end of file
{
"model": "workflows.category",
"fields": {
"name": "Transformation",
"parent": "d67b50ed-fd8a-4f91-aeb4-a9a19678f3fa",
"order": 1,
"uid": "a2a18b9a-e222-4013-a69e-cb793e4ab6a6"
}
}
\ No newline at end of file
{
"model": "workflows.category",
"fields": {
"name": "Graphs",
"parent": null,
"order": 1,
"uid": "d67b50ed-fd8a-4f91-aeb4-a9a19678f3fa"
}
}
\ No newline at end of file
[
{
"model": "workflows.abstractwidget",
"fields": {
"category": "09b22013-3469-497c-86e7-6d71ce9c78cd",
"treeview_image": "",
"uid": "25d69ccd-3bd8-4e7b-a16a-304d6713be97",
"windows_queue": false,
"package": "graphs",
"interaction_view": "",
"has_progress_bar": false,
"image": "",
"description": "Interactive graph visualization using vis.js",
"static_image": "",
"action": "graphs_visualize_visjs",
"visualization_view": "graphs_visualize_visjs",
"streaming_visualization_view": "",
"post_interact_action": "",
"wsdl_method": "",
"wsdl": "",
"interactive": false,
"is_streaming": false,
"order": 1,
"name": "graph visualization (vis.js)"
}
},
{
"model": "workflows.abstractinput",
"fields": {
"widget": "25d69ccd-3bd8-4e7b-a16a-304d6713be97",
"name": "Graph object",
"short_name": "nxg",
"default": "",
"description": "Graph as a networkx graph object.",
"required": false,
"multi": false,
"parameter_type": null,
"variable": "graph",
"parameter": false,
"order": 1,
"uid": "00b3c79f-f8bb-42c9-94bf-472fb891aa1a"
}
},
{
"model": "workflows.abstractinput",
"fields": {
"widget": "25d69ccd-3bd8-4e7b-a16a-304d6713be97",
"name": "Graph as text (Pajek format)",
"short_name": "paj",
"default": "*network test\r\n*vertices 4\r\n1 \"A\"\r\n2 \"B\"\r\n3 \"C\"\r\n4 \"D\"\r\n*arcs\r\n2 1 0.1 label \"one\"\r\n3 1 0.2 label \"two\"\r\n4 1 0.3 label \"three\"",
"description": "Graph as a text in Pajek format. IMPORTANT: this is IGNORED if workflow input is present!",
"required": false,
"multi": false,
"parameter_type": "textarea",
"variable": "gtext",
"parameter": true,
"order": 2,
"uid": "ae0e4cce-6cbb-4b6d-8ee2-2d421ffe071b"
}
}
]
\ No newline at end of file
[
{
"model": "workflows.abstractwidget",
"fields": {
"category": "a2a18b9a-e222-4013-a69e-cb793e4ab6a6",
"treeview_image": "",
"uid": "8e5290c8-7cff-4447-83b6-6703c3ea74a6",
"windows_queue": false,
"package": "graphs",
"interaction_view": "",
"has_progress_bar": false,
"image": "",
"description": "Loads a JSON graph description into a NetworkX graph object",
"static_image": "",
"action": "graphs_json2networkx",
"visualization_view": "",
"streaming_visualization_view": "",
"post_interact_action": "",
"wsdl_method": "",
"wsdl": "",
"interactive": false,
"is_streaming": false,
"order": 1,
"name": "JSON to NetworkX"
}
},
{
"model": "workflows.abstractinput",
"fields": {
"widget": "8e5290c8-7cff-4447-83b6-6703c3ea74a6",
"name": "Graph as JSON",
"short_name": "jsn",
"default": "",
"description": "Input graph as a JSON string",
"required": true,
"multi": false,
"parameter_type": null,
"variable": "graph",
"parameter": false,
"order": 1,
"uid": "8e945c4a-4cfb-4425-9d8d-8645e975cb0d"
}
},
{
"model": "workflows.abstractoutput",
"fields": {
"widget": "8e5290c8-7cff-4447-83b6-6703c3ea74a6",
"name": "NetworkX graph object",
"short_name": "nxg",
"description": "Graph as a NetworkX object",
"variable": "nxgraph",
"order": 1,
"uid": "db0923c5-db8a-4d7b-aa47-7426287ec2cb"
}
}
]
\ No newline at end of file
import os
# === STANDARD PACKAGE SETTINGS ===
PACKAGE_ROOT = os.path.dirname(__file__)
# === AUTO IMPORT OPTIONS ===
#If auto_import_package_data is true then given data file is automatically imported when ClowdFlows project is newly deployed or refreshed from git
AUTO_IMPORT_DB = False
#For auto_import_package_data_replace_option description see the 'replace' option in workflows/import_package command
AUTO_IMPORT_DB_REPLACE_OPTION = True
#If file(s) other than ./db/package_data.json should be imported, auto_import_package_data_files should be corrected
AUTO_IMPORT_DB_FILES = [os.path.join(PACKAGE_ROOT,'db/package_data.json')]
<div id="widgetinteract-{{widget.pk}}" rel="{{widget.pk}}" class="widgetinteractdialog" title="{{widget.name}} wants your input!">
<form id="interactionform-{{widget.pk}}" name="interactionform-{{widget.pk}}">
{% for i in intList %}
<input type="checkbox" name="intListOut" value="{{i}}" style="display:inline;width:auto;">{{i}}<br>
{% endfor %}
<input type="hidden" name="widget_id" value="{{widget.pk}}">
</form>
</div>
\ No newline at end of file
<div id="widgetvisualization-{{widget.pk}}" rel="{{widget.pk}}" class="widgetvisualizationdialog" title="{{widget.name}} visualization">
<div style="width:400px;font-family:monospace;">
<table style="width:auto; border-collapse:collapse;">
{% for i in input_dict.intList %}
<tr style="width:auto">
<td style="text-align: right; width:auto; line-height: 0.5em; padding: 2px; padding-bottom: 4px; padding-top: 0; margin:2px;">
{% if forloop.first %} {% else %}+{% endif %}
</td>
<td style="text-align: right; width:auto; line-height: 0.5em; padding: 2px; padding-bottom: 4px; padding-top: 0; margin:2px;">
{{ i }}
</td>
</tr>
{% endfor %}
<tr style="width:auto">
<td style="text-align: right; width:auto; line-height: 0.5em; border-top: 1px solid black; padding: 2px; padding-top: 4px; margin:2px;">
=
</td>
<td style="text-align: right; width:auto; line-height: 0.5em; border-top: 1px solid black; padding: 2px;margin:2px;">
{{ input_dict.sum }}
</td>
</tr>
</table>
<br/>
{{ check }}
</div>
</div>
\ No newline at end of file
<div id="widgetvisualization-{{ widget.pk }}" rel="{{ widget.pk }}"
class="widgetvisualizationdialog" title="{{ widget.name }} visualization" width="800" height="600">
<div id="controls">
<button id="freezeBtn" class='controlElement' type="button"></button>
<label for="etype">edge type</label>
<select name="etype" id="etypeSelect" class='controlElement'>
<option selected="selected">continuous</option>
<option>dynamic</option>
<option>straight</option>
</select>
</div>
<div id="networkvis">
</div>
</div>
<style>
#networkvis{
overflow-y: hidden;
overflow-x: hidden;
float: right;
/* display: block;*/
}
#controls {
width: 85px;
text-align:center;
padding-top: 11px;
float: left;
/* display: block;*/
font-size: 80%;
}
.controlElement {
/* margin: 0 auto;*/
margin-bottom: 5px;
}
</style>
<script>
$('head').append('<link rel="stylesheet" type="text/css" href="https://cdn.rawgit.com/almende/vis/v4.9.0/dist/vis.min.css">');
$("#widgetvisualization-{{ widget.pk }}").bind("dialogresize", function (event, ui) {
$('#networkvis').height($('#networkvis').parent().height());
$('#networkvis').width($('#networkvis').parent().width()-100);
});
$('#freezeBtn').button({
label: 'freeze'
});
$('#redrawBtn').button({
label: 'redraw'
});
// $('#etypeSelect').selectmenu();
</script>
<script>
$.getScript('https://cdn.rawgit.com/ryanve/verge/master/verge.min.js', function () {
$('#networkvis').height($('#networkvis').parent().height());
$('#networkvis').width($('#networkvis').parent().width()-100);
$.getScript("https://cdn.rawgit.com/almende/vis/v4.9.0/dist/vis.min.js", function () {
function onDragStart(obj) {
if (obj.hasOwnProperty('nodes') && obj.nodes.length==1) {
var nid = obj.nodes[0];
nodes.update({id: nid, fixed: false});
}
}
function onDragEnd(obj) {
if (isFrozen==false)
return
var nid = obj.nodes;
if (obj.hasOwnProperty('nodes') && obj.nodes.length==1) {
var nid = obj.nodes[0];
nodes.update({id: nid, fixed: true});
}
}
function freezeNodes(state){
nodes.forEach(function(node, id){
nodes.update({id: id, fixed: state});
});
}
$('#freezeBtn').on('click', function () {
if ($(this).find('span').text()=='release'){
isFrozen = false;
freezeNodes(false);
$(this).find('span').text('freeze');
}
else {
isFrozen = true;
freezeNodes(true);
$(this).find('span').text('release');
}
});
$("#etypeSelect").change(function() {
var t = $(this).val();
if (t=='continuous') {
network.setOptions({edges: {smooth: {type: 'continuous'}}});
}
else if (t=='dynamic') {
network.setOptions({edges: {smooth: {type: 'dynamic'}}})
}
else if (t=='straight') {
network.setOptions({edges: {smooth: false}})
}
});
var network = null;
var nodes = new vis.DataSet();
var edges = new vis.DataSet();
var isFrozen = false;
nodes.add({{ nodes|safe }});
edges.add({{ edges|safe }});
var data = {
nodes: nodes,
edges: edges
};
var options = {
autoResize: true,
edges: {
smooth: {
// type: 'dynamic'
type: 'continuous'
}
},
nodes: {
color: {
background: '#D2E5FF',
hover: {
background: '#97C2FC'
}
}
},
interaction: {
hover: true,
navigationButtons: true
},
manipulation: {
enabled: true,
initiallyActive: false,
addNode: function(nodeData,callback) {
nodeData.label = 'new node';
var name = prompt('Enter node label', nodeData.label);
if (name != null) {
nodeData.label = name;
};