improved so many things

This commit is contained in:
Connor Turland 2013-01-25 00:47:32 -05:00
parent 3433e1f05c
commit 9bc07b04fa
13 changed files with 213 additions and 116 deletions

View file

@ -31,39 +31,41 @@ function selectNodeOnClickHandler(node, e) {
if (Mconsole.busy) return; if (Mconsole.busy) return;
//set final styles if (gType != "centered") {
if (!e.shiftKey) { //set final styles
Mconsole.graph.eachNode(function (n) { if (!e.shiftKey) {
if (n.id != node.id) { Mconsole.graph.eachNode(function (n) {
delete n.selected; if (n.id != node.id) {
n.setData('onCanvas',false); delete n.selected;
} n.setData('onCanvas',false);
}
n.setData('dim', 25, 'current'); n.setData('dim', 25, 'current');
n.eachAdjacency(function (adj) { n.eachAdjacency(function (adj) {
deselectEdge(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 }//selectNodeOnClickHandler
function canvasDoubleClickHandler(canvasLoc,e) { function canvasDoubleClickHandler(canvasLoc,e) {

View file

@ -124,28 +124,13 @@ function graphSettings(type) {
} else if (node && !node.nodeFrom) { } else if (node && !node.nodeFrom) {
//node is actually a node :) //node is actually a node :)
if (!Mconsole.busy) { if (!Mconsole.busy) {
$('h1.index').html('Viewing Topic: ' + node.name);
window.history.pushState(node.name, "Metamaps", "/topics/" + node.id);
Mconsole.onClick(node.id, { Mconsole.onClick(node.id, {
hideLabels: false, hideLabels: false,
duration: 1000,
onComplete: function() { onComplete: function() {
selectNodeOnClickHandler(node, e); fetchRelatives(node);
$('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');
}
});
} }
}); });
} }
@ -158,7 +143,7 @@ function graphSettings(type) {
return t; return t;
}//graphSettings }//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 renderMidArrow = function(from, to, dim, swap, canvas){
var ctx = canvas.getCtx(); var ctx = canvas.getCtx();
// invert edge direction // invert edge direction
@ -194,6 +179,38 @@ arrowPoint.y - vect.y);
ctx.lineTo(v2.x, v2.y); ctx.lineTo(v2.x, v2.y);
ctx.stroke(); 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 // defining custom node type
var nodeSettings = { 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); this.edgeHelper.line.render({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, canvas);
} }
else if (directionCat == "both") { else if (directionCat == "both") {
renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, true, canvas); this.edgeHelper.line.render({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, canvas);
renderMidArrow({ x: pos.x, y: pos.y }, { x: posChild.x, y: posChild.y }, 13, false, 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") { else if (directionCat == "from-to") {
var direction = adj.data.$direction; var direction = adj.data.$direction;
@ -376,7 +394,7 @@ function onDragEndTopicHandler(node, eventInfo, e, allowRealtime) {
tempNode = null; tempNode = null;
tempNode2 = null; tempNode2 = null;
tempInit = false; tempInit = false;
} else if (allowRealtime && dragged != 0 && goRealtime) { } else if (dragged != 0 && goRealtime) {
saveLayout(dragged); saveLayout(dragged);
} }
}//onDragEndTopicHandler }//onDragEndTopicHandler

View file

@ -219,41 +219,33 @@ function generateLittleHTML(node) {
<div class="label">$_name_$</div> \ <div class="label">$_name_$</div> \
<div class="nodeOptions">'; <div class="nodeOptions">';
if ((userid == null || mapid == null) && node.id != Mconsole.root) { if (userid == null || mapid == null || !mapperm) {
//unauthenticated, not on a map: can remove from canvas //unauthenticated, not on a map: can remove from canvas
littleHTML += ' \ littleHTML += ' \
<span class="removeFromCanvas" \ <span class="removeFromCanvas" \
onclick="removeFromCanvas($_id_$)" \ onclick="hideNode($_id_$)" \
title="Click to remove topic from canvas"> \ title="Click to remove topic from canvas"> \
</span>'; </span>';
} else if (mapid != null && userid != null && node.id != Mconsole.root) { } else if (mapperm) {
//not on a map, authenticated, and not looking at root node //permission to remove nodes from the map
//(you can't delete the root node of a JIT graph)
littleHTML += ' \ littleHTML += ' \
<span class="removeFromCanvas" \ <span class="removeFromCanvas" \
onclick="removeFromCanvas($_id_$)" \ onclick="hideNode($_id_$)" \
title="Click to remove topic from canvas"> \ title="Click to remove topic from canvas"> \
</span> \ </span> \
<a href="/topics/$_mapid_$/$_id_$/removefrommap" \ <span class="removeFromMap" \
title="Click to remove topic from map" \ onclick="removeNode($_id_$)" \
class="removeFromMap" \ title="Click to remove topic from map"> \
data-method="post" \ </span>';
data-remote="true" \
rel="nofollow"> \
</a>';
} }
if (userid != null && node.id != Mconsole.root) { if (userid == node.getData('userid')) {
//logged in, whether you're on a map or not //logged in, and owner of the topic, thus permission to delete
littleHTML += ' \ littleHTML += ' \
<a href="/topics/$_id_$" \ <span class="deleteTopic" \
title="Click to delete this topic" \ onclick="deleteNode($_id_$)" \
class="deleteTopic" \ title="Click to delete this topic"> \
data-confirm="Delete this topic and all synapses linking to it?" \ </span>';
data-method="delete" \
data-remote="true" \
rel="nofollow"> \
</a>';
} }
littleHTML += '</div>'; littleHTML += '</div>';
littleHTML = littleHTML.replace(/\$_id_\$/g, node.id); littleHTML = littleHTML.replace(/\$_id_\$/g, node.id);
@ -291,8 +283,9 @@ function bindCallbacks(showCard, nameContainer, node) {
$('.name').css('display','block'); $('.name').css('display','block');
$('.name.topic_' + node.id).css('display','none'); $('.name.topic_' + node.id).css('display','none');
$('.showcard.topic_' + node.id).fadeIn('fast'); $('.showcard.topic_' + node.id).fadeIn('fast');
selectNodeOnClickHandler(node,e); //selectNodeOnClickHandler(node,e);
node.setData('dim', 1, 'current'); node.setData('dim', 1, 'current');
Mconsole.plot();
}); });
nameContainer.onmouseover = function(){ nameContainer.onmouseover = function(){

View file

@ -165,32 +165,66 @@ function deselectEdge(edge) {
MetamapsModel.selectedEdges.indexOf(edge), 1); 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() { function hideSelectedNodes() {
Mconsole.graph.eachNode( function (n) { Mconsole.graph.eachNode( function (n) {
if (n.data.$onCanvas == true && n.id != Mconsole.root) { if (n.data.$onCanvas == true) {
removeFromCanvas(n.id); hideNode(n.id);
} }
}); });
} }
function removeNode(nodeid) {
if (mapperm) {
$.ajax({
type: "POST",
url: "/topics/" + mapid + "/" + nodeid + "/removefrommap",
});
}
}
function removeSelectedNodes() { function removeSelectedNodes() {
Mconsole.graph.eachNode( function (n) { if (mapperm) {
if (n.data.$onCanvas == true && n.id != Mconsole.root) { Mconsole.graph.eachNode( function (n) {
$.ajax({ if (n.data.$onCanvas == true) {
type: "POST", removeNode(n.id);
url: "/topics/" + mapid + "/" + n.id + "/removefrommap",
});
} }
}); });
}
} }
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() { function deleteSelectedNodes() {
Mconsole.graph.eachNode( function (n) { Mconsole.graph.eachNode( function (n) {
if (n.data.$onCanvas == true && n.id != Mconsole.root) { if (n.data.$onCanvas == true) {
$.ajax({ deleteNode(n.id);
type: "DELETE",
url: "/topics/" + n.id,
});
} }
}); });
} }

View file

@ -21,7 +21,7 @@
// other options are 'graph' // other options are 'graph'
var viewMode = "list"; 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() { $(document).ready(function() {
@ -175,6 +175,8 @@ function saveLayout(id) {
$('#map_coordinates').val(n.data.$mappingid + '/' + n.pos.x + '/' + n.pos.y); $('#map_coordinates').val(n.data.$mappingid + '/' + n.pos.x + '/' + n.pos.y);
$('#saveMapLayout').submit(); $('#saveMapLayout').submit();
dragged = 0; dragged = 0;
$('#saveLayout').attr('value','Saved!');
setTimeout(function(){$('#saveLayout').attr('value','Save Layout')},1500);
} }
// this is to save your console to a map // this is to save your console to a map
@ -201,22 +203,6 @@ function saveToMap() {
$('#new_map').fadeIn('fast'); $('#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() { function addMetacode() {
// code from http://www.professorcloud.com/mainsite/carousel-integration.htm // code from http://www.professorcloud.com/mainsite/carousel-integration.htm
//mouseWheel:true, //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() { function MconsoleReset() {
var tX = Mconsole.canvas.translateOffsetX; var tX = Mconsole.canvas.translateOffsetX;

View file

@ -1,7 +1,7 @@
class SynapsesController < ApplicationController class SynapsesController < ApplicationController
include TopicsHelper 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 respond_to :html, :js, :json

View file

@ -1,5 +1,5 @@
class TopicsController < ApplicationController 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 respond_to :html, :js, :json

View file

@ -98,7 +98,7 @@ belongs_to :metacode
#build a json object of everything connected to a specified node #build a json object of everything connected to a specified node
def network_as_json(current) def network_as_json(current)
Jbuilder.encode do |json| Jbuilder.encode do |json|
@topics = network(self,nil,2) @topics = network(self,nil,1)
if @topics.count > 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| 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 json.nodeFrom synapse.node1_id
@synapsedata = Hash.new @synapsedata = Hash.new
@synapsedata['$alpha'] = 0.4
@synapsedata['$desc'] = synapse.desc @synapsedata['$desc'] = synapse.desc
@synapsedata['$showDesc'] = false @synapsedata['$showDesc'] = false
@synapsedata['$category'] = synapse.category @synapsedata['$category'] = synapse.category

View file

@ -8,6 +8,8 @@
<%= form.autocomplete_field :desc, autocomplete_synapse_desc_synapses_path, :placeholder => "Describe the connection..." %> <%= form.autocomplete_field :desc, autocomplete_synapse_desc_synapses_path, :placeholder => "Describe the connection..." %>
<%= form.hidden_field :topic1id, :value => 0 %> <%= form.hidden_field :topic1id, :value => 0 %>
<%= form.hidden_field :topic2id, :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 %> <% end %>
</div> </div>

View file

@ -9,7 +9,9 @@
<%= form.hidden_field :metacode, :value => "Action" %> <%= form.hidden_field :metacode, :value => "Action" %>
<%= form.hidden_field :x, :value => 0 %> <%= form.hidden_field :x, :value => 0 %>
<%= form.hidden_field :y, :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 :grabTopic, :value => "null" %>
<%= form.hidden_field :addSynapse, :value => false %> <%= form.hidden_field :addSynapse, :value => false %>
<!--<input id="left-but" type="button" value="Left" />--> <!--<input id="left-but" type="button" value="Left" />-->

View file

@ -5,10 +5,12 @@
#%> #%>
<div class="headertop"> <div class="headertop">
<button onclick="if (!goRealtime) { this.innerHTML = 'Stop Realtime'; $('#saveLayout').css('display','none'); } else if (goRealtime) { this.innerHTML = 'Start Realtime'; $('#saveLayout').css('display','block');} goRealtime = !goRealtime;">Start Realtime</button> <button onclick="if (!goRealtime) { this.innerHTML = 'Stop Realtime'; } else if (goRealtime) { this.innerHTML = 'Start Realtime'; } goRealtime = !goRealtime;">Start Realtime</button>
<button onclick="hideSelectedEdges();hideSelectedNodes();">Hide Selected</button> <button onclick="hideSelectedEdges();hideSelectedNodes();">Hide Selected</button>
<% if authenticated? %> <% if authenticated? %>
<button onclick="removeSelectedEdges();removeSelectedNodes();">Remove Selected From Map</button> <% if (@map.permission == "commons" && authenticated?) || @map.user == user %>
<button onclick="removeSelectedEdges();removeSelectedNodes();">Remove Selected From Map</button>
<% end %>
<button onclick="var r=confirm('Are you sure you want to permanently delete selected objects?!'); if (r == true) {deleteSelectedEdges();deleteSelectedNodes();}">Permanently Delete Selected</button> <button onclick="var r=confirm('Are you sure you want to permanently delete selected objects?!'); if (r == true) {deleteSelectedEdges();deleteSelectedNodes();}">Permanently Delete Selected</button>
<% if (@map.permission == "commons" && authenticated?) || @map.user == user %> <% if (@map.permission == "commons" && authenticated?) || @map.user == user %>
<%= form_for @map, :url => savelayout_path(@map), :html => { :class => "saveMapLayout", :id => "saveMapLayout"}, remote: true do |form| %> <%= form_for @map, :url => savelayout_path(@map), :html => { :class => "saveMapLayout", :id => "saveMapLayout"}, remote: true do |form| %>
@ -55,6 +57,9 @@
<script> <script>
var dragged = 0; var dragged = 0;
mapid = <%= @map.id %>; mapid = <%= @map.id %>;
<% if (@map.permission == "commons" && authenticated?) || @map.user == user %>
mapperm = true;
<% end %>
var int = setInterval(function(){ var int = setInterval(function(){
if (goRealtime) { if (goRealtime) {
$('#MapRealtime').submit(); $('#MapRealtime').submit();

View file

@ -5,7 +5,15 @@
*/ */
if (Mconsole != null) { if (Mconsole != null) {
var node = Mconsole.graph.getNode(<%= @topic.id %>); var node = Mconsole.graph.getNode(<%= @topic.id %>);
if (node.id == Mconsole.root) {
Mconsole.graph.eachNode(function (n) {
if (n.id != node.id) Mconsole.root = n.id;
});
}
node.setData('alpha', 0, 'end'); node.setData('alpha', 0, 'end');
node.eachAdjacency(function(adj) { node.eachAdjacency(function(adj) {
adj.setData('alpha', 0, 'end'); adj.setData('alpha', 0, 'end');

View file

@ -9,6 +9,11 @@
if (Mconsole != null) { if (Mconsole != null) {
var node = Mconsole.graph.getNode(<%= @mapping.topic_id %>); var node = Mconsole.graph.getNode(<%= @mapping.topic_id %>);
if (node.id == Mconsole.root) {
Mconsole.graph.eachNode(function (n) {
if (n.id != node.id) Mconsole.root = n.id;
});
}
node.setData('alpha', 0, 'end'); node.setData('alpha', 0, 'end');
node.eachAdjacency(function(adj) { node.eachAdjacency(function(adj) {
adj.setData('alpha', 0, 'end'); adj.setData('alpha', 0, 'end');