diff --git a/app/assets/javascripts/Jit/graphsettings-event-handlers.js b/app/assets/javascripts/Jit/graphsettings-event-handlers.js index 055c22a2..6ec0a25e 100644 --- a/app/assets/javascripts/Jit/graphsettings-event-handlers.js +++ b/app/assets/javascripts/Jit/graphsettings-event-handlers.js @@ -30,40 +30,42 @@ function selectEdgeOnClickHandler(adj, e) { function selectNodeOnClickHandler(node, e) { if (Mconsole.busy) return; - - //set final styles - if (!e.shiftKey) { - Mconsole.graph.eachNode(function (n) { - if (n.id != node.id) { - delete n.selected; - n.setData('onCanvas',false); - } - n.setData('dim', 25, 'current'); - n.eachAdjacency(function (adj) { - deselectEdge(adj); + if (gType != "centered") { + //set final styles + if (!e.shiftKey) { + Mconsole.graph.eachNode(function (n) { + if (n.id != node.id) { + delete n.selected; + n.setData('onCanvas',false); + } + + n.setData('dim', 25, 'current'); + n.eachAdjacency(function (adj) { + deselectEdge(adj); + }); + }); + } + if (!node.selected) { + node.selected = true; + node.setData('dim', 30, 'current'); + node.setData('onCanvas',true); + node.eachAdjacency(function (adj) { + selectEdge(adj); }); + Mconsole.plot(); + } else { + node.setData('dim', 25, 'current'); + delete node.selected; + node.setData('onCanvas',false); + } + //trigger animation to final styles + Mconsole.fx.animate({ + modes: ['edge-property:lineWidth:color:alpha'], + duration: 500 }); + Mconsole.plot(); } - if (!node.selected) { - node.selected = true; - node.setData('dim', 30, 'current'); - node.setData('onCanvas',true); - node.eachAdjacency(function (adj) { - selectEdge(adj); - }); - Mconsole.plot(); - } else { - node.setData('dim', 25, 'current'); - delete node.selected; - node.setData('onCanvas',false); - } - //trigger animation to final styles - Mconsole.fx.animate({ - modes: ['edge-property:lineWidth:color:alpha'], - duration: 500 - }); - Mconsole.plot(); }//selectNodeOnClickHandler function canvasDoubleClickHandler(canvasLoc,e) { diff --git a/app/assets/javascripts/Jit/graphsettings.js b/app/assets/javascripts/Jit/graphsettings.js index 4362dba6..bc0e4d5c 100644 --- a/app/assets/javascripts/Jit/graphsettings.js +++ b/app/assets/javascripts/Jit/graphsettings.js @@ -124,28 +124,13 @@ function graphSettings(type) { } else if (node && !node.nodeFrom) { //node is actually a node :) if (!Mconsole.busy) { + $('h1.index').html('Viewing Topic: ' + node.name); + window.history.pushState(node.name, "Metamaps", "/topics/" + node.id); Mconsole.onClick(node.id, { hideLabels: false, + duration: 1000, onComplete: function() { - selectNodeOnClickHandler(node, e); - $('h1.index').html('Viewing Topic: ' + node.name); - window.history.pushState(node.name, "Metamaps", "/topics/" + node.id); - var myA = $.ajax({ - type: "Get", - url: "/topics/" + node.id + "?format=json", - success: function(data) { - console.log(data); - Mconsole.op.morph(data, { - type: 'fade', - duration: 1500, - hideLabels: false, - transition: $jit.Trans.Quart.easeOut - }); - }, - error: function(){ - alert('failure'); - } - }); + fetchRelatives(node); } }); } @@ -158,7 +143,7 @@ function graphSettings(type) { return t; }//graphSettings -// defining code to draw edges with arrows pointing in the middle of them +// defining code to draw edges with arrows pointing in one direction var renderMidArrow = function(from, to, dim, swap, canvas){ var ctx = canvas.getCtx(); // invert edge direction @@ -194,6 +179,38 @@ arrowPoint.y - vect.y); ctx.lineTo(v2.x, v2.y); ctx.stroke(); }; +// defining code to draw edges with arrows pointing in both directions +var renderMidArrows = function(from, to, dim, swap, canvas){ + var ctx = canvas.getCtx(); + // invert edge direction + if (swap) { + var tmp = from; + from = to; + to = tmp; + } + // vect represents a line from tip to tail of the arrow + var vect = new $jit.Complex(to.x - from.x, to.y - from.y); + // scale it + vect.$scale(dim / vect.norm()); + // compute the midpoint of the edge line + var midPoint = new $jit.Complex((to.x + from.x) / 2, (to.y + from.y) / 2); + // move midpoint by half the "length" of the arrow so the arrow is centered on the midpoint + var arrowPoint = new $jit.Complex((vect.x / 0.7) + midPoint.x, (vect.y / 0.7) + midPoint.y); + // compute the tail intersection point with the edge line + var intermediatePoint = new $jit.Complex(arrowPoint.x - vect.x, +arrowPoint.y - vect.y); + // vector perpendicular to vect + var normal = new $jit.Complex(-vect.y / 2, vect.x / 2); + var v1 = intermediatePoint.add(normal); + var v2 = intermediatePoint.$add(normal.$scale(-1)); + + //ctx.strokeStyle = "#222222"; + ctx.beginPath(); + ctx.moveTo(v1.x, v1.y); + ctx.lineTo(arrowPoint.x, arrowPoint.y); + ctx.lineTo(v2.x, v2.y); + ctx.stroke(); +}; // defining custom node type var nodeSettings = { @@ -248,8 +265,9 @@ var nodeSettings = { this.edgeHelper.line.render({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, canvas); } else if (directionCat == "both") { - renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, true, canvas); - renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, false, canvas); + this.edgeHelper.line.render({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, canvas); + renderMidArrows({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, true, canvas); + renderMidArrows({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, false, canvas); } else if (directionCat == "from-to") { var direction = adj.data.$direction; @@ -376,7 +394,7 @@ function onDragEndTopicHandler(node, eventInfo, e, allowRealtime) { tempNode = null; tempNode2 = null; tempInit = false; - } else if (allowRealtime && dragged != 0 && goRealtime) { + } else if (dragged != 0 && goRealtime) { saveLayout(dragged); } }//onDragEndTopicHandler diff --git a/app/assets/javascripts/Jit/onCreateLabelHandler.js b/app/assets/javascripts/Jit/onCreateLabelHandler.js index 6fc4dd53..c67f6cf7 100644 --- a/app/assets/javascripts/Jit/onCreateLabelHandler.js +++ b/app/assets/javascripts/Jit/onCreateLabelHandler.js @@ -219,41 +219,33 @@ function generateLittleHTML(node) {
$_name_$
\
'; - if ((userid == null || mapid == null) && node.id != Mconsole.root) { + if (userid == null || mapid == null || !mapperm) { //unauthenticated, not on a map: can remove from canvas littleHTML += ' \ \ '; - } else if (mapid != null && userid != null && node.id != Mconsole.root) { - //not on a map, authenticated, and not looking at root node - //(you can't delete the root node of a JIT graph) + } else if (mapperm) { + //permission to remove nodes from the map littleHTML += ' \ \ \ - \ - '; + \ + '; } - if (userid != null && node.id != Mconsole.root) { - //logged in, whether you're on a map or not - littleHTML += ' \ - \ - '; + if (userid == node.getData('userid')) { + //logged in, and owner of the topic, thus permission to delete + littleHTML += ' \ + \ + '; } littleHTML += '
'; littleHTML = littleHTML.replace(/\$_id_\$/g, node.id); @@ -291,8 +283,9 @@ function bindCallbacks(showCard, nameContainer, node) { $('.name').css('display','block'); $('.name.topic_' + node.id).css('display','none'); $('.showcard.topic_' + node.id).fadeIn('fast'); - selectNodeOnClickHandler(node,e); + //selectNodeOnClickHandler(node,e); node.setData('dim', 1, 'current'); + Mconsole.plot(); }); nameContainer.onmouseover = function(){ diff --git a/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js b/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js index 6bbf8334..c96eecfa 100644 --- a/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js +++ b/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js @@ -165,32 +165,66 @@ function deselectEdge(edge) { MetamapsModel.selectedEdges.indexOf(edge), 1); } +// this is for hiding one topic from your canvas +function hideNode(nodeid) { + var node = Mconsole.graph.getNode(nodeid); + if (nodeid == Mconsole.root && gType == "centered") { + alert("You can't hide this topic, it is the root of your graph."); + return; + } + + node.setData('alpha', 0, 'end'); + node.eachAdjacency(function(adj) { + adj.setData('alpha', 0, 'end'); + }); + Mconsole.fx.animate({ + modes: ['node-property:alpha', + 'edge-property:alpha'], + duration: 1000 + }); + Mconsole.graph.removeNode(nodeid); + Mconsole.labels.disposeLabel(nodeid); +} function hideSelectedNodes() { Mconsole.graph.eachNode( function (n) { - if (n.data.$onCanvas == true && n.id != Mconsole.root) { - removeFromCanvas(n.id); + if (n.data.$onCanvas == true) { + hideNode(n.id); } }); } +function removeNode(nodeid) { + if (mapperm) { + $.ajax({ + type: "POST", + url: "/topics/" + mapid + "/" + nodeid + "/removefrommap", + }); + } +} function removeSelectedNodes() { - Mconsole.graph.eachNode( function (n) { - if (n.data.$onCanvas == true && n.id != Mconsole.root) { - $.ajax({ - type: "POST", - url: "/topics/" + mapid + "/" + n.id + "/removefrommap", - }); + if (mapperm) { + Mconsole.graph.eachNode( function (n) { + if (n.data.$onCanvas == true) { + removeNode(n.id); } - }); + }); + } } +function deleteNode(nodeid) { + if (nodeid == Mconsole.root && gType == "centered") { + alert("You can't delete this topic, it is the root of your graph."); + return; + } + $.ajax({ + type: "DELETE", + url: "/topics/" + nodeid, + }); +} function deleteSelectedNodes() { Mconsole.graph.eachNode( function (n) { - if (n.data.$onCanvas == true && n.id != Mconsole.root) { - $.ajax({ - type: "DELETE", - url: "/topics/" + n.id, - }); + if (n.data.$onCanvas == true) { + deleteNode(n.id); } }); } diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 02c9aa93..66dc905b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -21,7 +21,7 @@ // other options are 'graph' var viewMode = "list"; -var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null; +var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false; $(document).ready(function() { @@ -175,6 +175,8 @@ function saveLayout(id) { $('#map_coordinates').val(n.data.$mappingid + '/' + n.pos.x + '/' + n.pos.y); $('#saveMapLayout').submit(); dragged = 0; + $('#saveLayout').attr('value','Saved!'); + setTimeout(function(){$('#saveLayout').attr('value','Save Layout')},1500); } // this is to save your console to a map @@ -201,22 +203,6 @@ function saveToMap() { $('#new_map').fadeIn('fast'); } -// this is for hiding one topic from your canvas -function removeFromCanvas(topic_id) { - var node = Mconsole.graph.getNode(topic_id); - node.setData('alpha', 0, 'end'); - node.eachAdjacency(function(adj) { - adj.setData('alpha', 0, 'end'); - }); - Mconsole.fx.animate({ - modes: ['node-property:alpha', - 'edge-property:alpha'], - duration: 1000 - }); - Mconsole.graph.removeNode(topic_id); - Mconsole.labels.disposeLabel(topic_id); -} - function addMetacode() { // code from http://www.professorcloud.com/mainsite/carousel-integration.htm //mouseWheel:true, @@ -234,6 +220,47 @@ function addMetacode() { } } +function fetchRelatives(node) { + var myA = $.ajax({ + type: "Get", + url: "/topics/" + node.id + "?format=json", + success: function(data) { + if (gType == "centered") { + Mconsole.op.sum(data, { + type: 'fade', + duration: 500 + }); + Mconsole.graph.eachNode(function (n) { + n.eachAdjacency(function (a) { + if (!a.getData('showDesc')) { + a.setData('alpha', 0.4, 'start'); + a.setData('alpha', 0.4, 'current'); + a.setData('alpha', 0.4, 'end'); + } + }); + }); + } + else { + Mconsole.op.sum(data, { + type: 'nothing', + }); + Mconsole.plot(); + } + /*Mconsole.op.contract(node, { + type: 'replot' + }); + Mconsole.op.expand(node, { + type: 'animate', + transition: $jit.Trans.Elastic.easeOut, + duration: 1000 + });*/ + }, + error: function(){ + alert('failure'); + } + }); +} + function MconsoleReset() { var tX = Mconsole.canvas.translateOffsetX; diff --git a/app/controllers/synapses_controller.rb b/app/controllers/synapses_controller.rb index c329bc25..18c52140 100644 --- a/app/controllers/synapses_controller.rb +++ b/app/controllers/synapses_controller.rb @@ -1,7 +1,7 @@ class SynapsesController < ApplicationController include TopicsHelper - before_filter :require_user, only: [:new, :create, :edit, :update, :destroy] + before_filter :require_user, only: [:new, :create, :edit, :update, :removefrommap, :destroy] respond_to :html, :js, :json diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 9ad6353a..054eacef 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -1,5 +1,5 @@ class TopicsController < ApplicationController - before_filter :require_user, only: [:new, :create, :edit, :update, :destroy] + before_filter :require_user, only: [:new, :create, :edit, :update, :removefrommap, :destroy] respond_to :html, :js, :json diff --git a/app/models/topic.rb b/app/models/topic.rb index 3c9b2d41..7214f712 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -98,7 +98,7 @@ belongs_to :metacode #build a json object of everything connected to a specified node def network_as_json(current) Jbuilder.encode do |json| - @topics = network(self,nil,2) + @topics = network(self,nil,1) if @topics.count > 1 json.array!(@topics.delete_if{|topic| (not topic.authorize_to_view(current)) || (not topic.has_viewable_synapses(current))}) do |topic| @@ -108,6 +108,7 @@ belongs_to :metacode json.nodeFrom synapse.node1_id @synapsedata = Hash.new + @synapsedata['$alpha'] = 0.4 @synapsedata['$desc'] = synapse.desc @synapsedata['$showDesc'] = false @synapsedata['$category'] = synapse.category diff --git a/app/views/maps/_newsynapse.html.erb b/app/views/maps/_newsynapse.html.erb index 33d3e758..f34b9218 100644 --- a/app/views/maps/_newsynapse.html.erb +++ b/app/views/maps/_newsynapse.html.erb @@ -8,6 +8,8 @@ <%= form.autocomplete_field :desc, autocomplete_synapse_desc_synapses_path, :placeholder => "Describe the connection..." %> <%= form.hidden_field :topic1id, :value => 0 %> <%= form.hidden_field :topic2id, :value => 0 %> - <%= form.hidden_field :map, :value => @map.id %> + <% if (@map.permission == "commons" && authenticated?) || @map.user == user %> + <%= form.hidden_field :map, :value => @map.id %> + <% end %> <% end %> diff --git a/app/views/maps/_newtopic.html.erb b/app/views/maps/_newtopic.html.erb index 273ef15e..075a9321 100644 --- a/app/views/maps/_newtopic.html.erb +++ b/app/views/maps/_newtopic.html.erb @@ -9,7 +9,9 @@ <%= form.hidden_field :metacode, :value => "Action" %> <%= form.hidden_field :x, :value => 0 %> <%= form.hidden_field :y, :value => 0 %> - <%= form.hidden_field :map, :value => @map.id %> + <% if (@map.permission == "commons" && authenticated?) || @map.user == user %> + <%= form.hidden_field :map, :value => @map.id %> + <% end %> <%= form.hidden_field :grabTopic, :value => "null" %> <%= form.hidden_field :addSynapse, :value => false %> diff --git a/app/views/maps/show.html.erb b/app/views/maps/show.html.erb index e9def1b7..a41e2c16 100644 --- a/app/views/maps/show.html.erb +++ b/app/views/maps/show.html.erb @@ -5,10 +5,12 @@ #%>
- + <% if authenticated? %> - + <% if (@map.permission == "commons" && authenticated?) || @map.user == user %> + + <% end %> <% if (@map.permission == "commons" && authenticated?) || @map.user == user %> <%= form_for @map, :url => savelayout_path(@map), :html => { :class => "saveMapLayout", :id => "saveMapLayout"}, remote: true do |form| %> @@ -55,6 +57,9 @@