enabled pulling in siblings through right click menus in topic view
This commit is contained in:
parent
534bdae495
commit
8d3de3867f
6 changed files with 271 additions and 64 deletions
|
@ -37,8 +37,9 @@ Metamaps.JIT = {
|
|||
/**
|
||||
* convert our topic JSON into something JIT can use
|
||||
*/
|
||||
prepareVizData: function () {
|
||||
var self = Metamaps.JIT;
|
||||
convertModelsToJIT: function(topics, synapses) {
|
||||
var jitReady = [];
|
||||
|
||||
var synapsesToRemove = [];
|
||||
var topic;
|
||||
var mapping;
|
||||
|
@ -48,18 +49,14 @@ Metamaps.JIT = {
|
|||
var edge;
|
||||
var edges = [];
|
||||
|
||||
// reset/empty vizData
|
||||
self.vizData = [];
|
||||
Metamaps.Visualize.loadLater = false;
|
||||
|
||||
Metamaps.Topics.each(function (t) {
|
||||
topics.each(function (t) {
|
||||
node = t.createNode();
|
||||
nodes[node.id] = node;
|
||||
});
|
||||
Metamaps.Synapses.each(function (s) {
|
||||
synapses.each(function (s) {
|
||||
edge = s.createEdge();
|
||||
|
||||
if(Metamaps.Topics.get(s.get('node1_id')) === undefined || Metamaps.Topics.get(s.get('node2_id')) === undefined) {
|
||||
if (topics.get(s.get('node1_id')) === undefined || topics.get(s.get('node2_id')) === undefined) {
|
||||
// this means it's an invalid synapse
|
||||
synapsesToRemove.push(s);
|
||||
}
|
||||
|
@ -89,17 +86,31 @@ Metamaps.JIT = {
|
|||
}
|
||||
});
|
||||
|
||||
_.each(nodes, function (node) {
|
||||
jitReady.push(node);
|
||||
});
|
||||
|
||||
return [jitReady, synapsesToRemove];
|
||||
},
|
||||
prepareVizData: function () {
|
||||
var self = Metamaps.JIT;
|
||||
var mapping;
|
||||
|
||||
// reset/empty vizData
|
||||
self.vizData = [];
|
||||
Metamaps.Visualize.loadLater = false;
|
||||
|
||||
var results = self.convertModelsToJIT(Metamaps.Topics, Metamaps.Synapses);
|
||||
|
||||
self.vizData = results[0];
|
||||
|
||||
// clean up the synapses array in case of any faulty data
|
||||
_.each(synapsesToRemove, function (synapse) {
|
||||
_.each(results[1], function (synapse) {
|
||||
mapping = synapse.getMapping();
|
||||
Metamaps.Synapses.remove(synapse);
|
||||
Metamaps.Mappings.remove(mapping);
|
||||
});
|
||||
|
||||
_.each(nodes, function (node) {
|
||||
self.vizData.push(node);
|
||||
});
|
||||
|
||||
if (self.vizData.length == 0) {
|
||||
Metamaps.Visualize.loadLater = true;
|
||||
}
|
||||
|
@ -1319,7 +1330,9 @@ Metamaps.JIT = {
|
|||
if (Metamaps.Active.Map && Metamaps.Active.Mapper) menustring += '<li class="rc-delete ' + disabled + '"><div class="rc-icon"></div>Delete</li>';
|
||||
|
||||
|
||||
if (Metamaps.Active.Topic) menustring += '<li class="rc-center"><div class="rc-icon"></div>Center this topic</li>';
|
||||
if (Metamaps.Active.Topic) {
|
||||
menustring += '<li class="rc-center"><div class="rc-icon"></div>Center this topic</li>';
|
||||
}
|
||||
menustring += '<li class="rc-popout"><div class="rc-icon"></div>Open in new tab</li>';
|
||||
if (Metamaps.Active.Mapper) {
|
||||
var options = '<ul><li class="changeP toCommons"><div class="rc-perm-icon"></div>commons</li> \
|
||||
|
@ -1333,6 +1346,15 @@ Metamaps.JIT = {
|
|||
|
||||
menustring += '<li class="rc-metacode"><div class="rc-icon"></div>Change metacode' + metacodeOptions + '<div class="expandLi"></div></li>';
|
||||
}
|
||||
if (Metamaps.Active.Topic) {
|
||||
// set up the get sibling menu as a "lazy load"
|
||||
// only fill in the submenu when they hover over the get siblings list item
|
||||
var siblingMenu = '<ul id="fetchSiblingList"> \
|
||||
<li class="fetchAll">All</li> \
|
||||
<li id="loadingSiblings"></li> \
|
||||
</ul>';
|
||||
menustring += '<li class="rc-siblings"><div class="rc-icon"></div>Get siblings' + siblingMenu + '<div class="expandLi"></div></li>';
|
||||
}
|
||||
|
||||
menustring += '</ul>';
|
||||
rightclickmenu.innerHTML = menustring;
|
||||
|
@ -1426,7 +1448,70 @@ Metamaps.JIT = {
|
|||
Metamaps.Control.updateSelectedMetacodes($(this).attr('data-id'));
|
||||
});
|
||||
|
||||
}, //selectNodeOnRightClickHandler
|
||||
|
||||
// fetch relatives
|
||||
var fetched = false;
|
||||
$('.rc-siblings').hover(function () {
|
||||
if (!fetched) {
|
||||
Metamaps.JIT.populateRightClickSiblings(node);
|
||||
fetched = true;
|
||||
}
|
||||
});
|
||||
$('.rc-siblings .fetchAll').click(function () {
|
||||
$('.rightclickmenu').remove();
|
||||
// data-id is a metacode id
|
||||
Metamaps.Topic.fetchRelatives(node);
|
||||
});
|
||||
}, //selectNodeOnRightClickHandler,
|
||||
populateRightClickSiblings: function(node) {
|
||||
var self = Metamaps.JIT;
|
||||
|
||||
// depending on how many topics are selected, do different things
|
||||
/*if (Metamaps.Selected.Nodes.length > 1) {
|
||||
// we don't bother filling the submenu with
|
||||
// specific numbers, because there are too many topics
|
||||
// selected to find those numbers
|
||||
$('#loadingSiblings').remove();
|
||||
return;
|
||||
}*/
|
||||
|
||||
var topic = node.getData('topic');
|
||||
|
||||
// add a loading icon for now
|
||||
var loader = new CanvasLoader('loadingSiblings');
|
||||
loader.setColor('#4FC059'); // default is '#000000'
|
||||
loader.setDiameter(15); // default is 40
|
||||
loader.setDensity(41); // default is 40
|
||||
loader.setRange(0.9); // default is 1.3
|
||||
loader.show(); // Hidden by default
|
||||
|
||||
var topics = Metamaps.Topics.map(function(t){ return t.id });
|
||||
var topics_string = topics.join();
|
||||
|
||||
var successCallback = function(data) {
|
||||
$('#loadingSiblings').remove();
|
||||
|
||||
for (var key in data) {
|
||||
var string = Metamaps.Metacodes.get(key).get('name') + ' (' + data[key] + ')';
|
||||
$('#fetchSiblingList').append('<li class="getSiblings" data-id="' + key + '">' + string + '</li>');
|
||||
}
|
||||
|
||||
$('.rc-siblings .getSiblings').click(function () {
|
||||
$('.rightclickmenu').remove();
|
||||
// data-id is a metacode id
|
||||
Metamaps.Topic.fetchRelatives(node, $(this).attr('data-id'));
|
||||
});
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "Get",
|
||||
url: "/topics/" + topic.id + "/relative_numbers.json?network=" + topics_string,
|
||||
success: successCallback,
|
||||
error: function () {
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
selectEdgeOnClickHandler: function (adj, e) {
|
||||
if (Metamaps.Visualize.mGraph.busy) return;
|
||||
|
||||
|
|
|
@ -219,7 +219,6 @@ Metamaps.Backbone.init = function () {
|
|||
var mapping;
|
||||
var node = this.get('node');
|
||||
node.setData('topic', this);
|
||||
node.id = this.isNew() ? this.cid : this.id;
|
||||
|
||||
if (Metamaps.Active.Map) {
|
||||
mapping = this.getMapping();
|
||||
|
@ -1508,6 +1507,8 @@ Metamaps.Visualize = {
|
|||
mapping;
|
||||
|
||||
if (self.type == "RGraph") {
|
||||
var i, l, startPos, endPos, topic, synapse;
|
||||
|
||||
self.mGraph.graph.eachNode(function (n) {
|
||||
topic = Metamaps.Topics.get(n.id);
|
||||
topic.set({ node: n }, { silent: true });
|
||||
|
@ -3671,8 +3672,7 @@ Metamaps.Topic = {
|
|||
},
|
||||
centerOn: function (nodeid) {
|
||||
if (!Metamaps.Visualize.mGraph.busy) {
|
||||
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid);
|
||||
Metamaps.Visualize.mGraph.onClick(node.id, {
|
||||
Metamaps.Visualize.mGraph.onClick(nodeid, {
|
||||
hideLabels: false,
|
||||
duration: 1000,
|
||||
onComplete: function () {
|
||||
|
@ -3681,6 +3681,66 @@ Metamaps.Topic = {
|
|||
});
|
||||
}
|
||||
},
|
||||
fetchRelatives: function(node, metacode_id) {
|
||||
|
||||
var topics = Metamaps.Topics.map(function(t){ return t.id });
|
||||
var topics_string = topics.join();
|
||||
|
||||
var creators = Metamaps.Creators.map(function(t){ return t.id });
|
||||
var creators_string = creators.join();
|
||||
|
||||
var topic = node.getData('topic');
|
||||
|
||||
var successCallback = function(data) {
|
||||
if (data.creators.length > 0) Metamaps.Creators.add(data.creators);
|
||||
if (data.topics.length > 0) Metamaps.Topics.add(data.topics);
|
||||
if (data.synapses.length > 0) Metamaps.Synapses.add(data.synapses);
|
||||
|
||||
var topicColl = new Metamaps.Backbone.TopicCollection(data.topics);
|
||||
topicColl.add(topic);
|
||||
var synapseColl = new Metamaps.Backbone.SynapseCollection(data.synapses);
|
||||
|
||||
var graph = Metamaps.JIT.convertModelsToJIT(topicColl, synapseColl)[0];
|
||||
Metamaps.Visualize.mGraph.op.sum(graph, {
|
||||
type: 'fade',
|
||||
duration: 500,
|
||||
hideLabels: false
|
||||
});
|
||||
|
||||
var i, l, t, s;
|
||||
|
||||
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
|
||||
t = Metamaps.Topics.get(n.id);
|
||||
t.set({ node: n }, { silent: true });
|
||||
t.updateNode();
|
||||
|
||||
n.eachAdjacency(function (edge) {
|
||||
if(!edge.getData('init')) {
|
||||
edge.setData('init', true);
|
||||
|
||||
l = edge.getData('synapseIDs').length;
|
||||
for (i = 0; i < l; i++) {
|
||||
s = Metamaps.Synapses.get(edge.getData('synapseIDs')[i]);
|
||||
s.set({ edge: edge }, { silent: true });
|
||||
s.updateEdge();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var paramsString = metacode_id ? "metacode=" + metacode_id + "&" : "";
|
||||
paramsString += "network=" + topics_string + "&creators=" + creators_string;
|
||||
|
||||
$.ajax({
|
||||
type: "Get",
|
||||
url: "/topics/" + topic.id + "/relatives.json?" + paramsString,
|
||||
success: successCallback,
|
||||
error: function () {
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
/*
|
||||
*
|
||||
*
|
||||
|
@ -4739,8 +4799,6 @@ Metamaps.Account = {
|
|||
var destWidth = 84;
|
||||
var destHeight = 84;
|
||||
|
||||
//debugger;
|
||||
|
||||
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
|
||||
$('.userImageDiv').prepend($canvas);
|
||||
};
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
function fetchRelatives(node) {
|
||||
var myA = $.ajax({
|
||||
type: "Get",
|
||||
url: "/topics/" + node.id + "?format=json",
|
||||
success: function (data) {
|
||||
if (gType == "centered") {
|
||||
Mconsole.busy = true;
|
||||
Mconsole.op.sum(data, {
|
||||
type: 'fade',
|
||||
duration: 500,
|
||||
hideLabels: false
|
||||
});
|
||||
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');
|
||||
}
|
||||
});
|
||||
});
|
||||
Mconsole.busy = false;
|
||||
} else {
|
||||
Mconsole.op.sum(data, {
|
||||
type: 'nothing',
|
||||
});
|
||||
Mconsole.plot();
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
alert('failure');
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1244,7 +1244,9 @@ h3.realtimeBoxTitle {
|
|||
.rc-metacode li img {
|
||||
float: left;
|
||||
}
|
||||
.rightclickmenu .rc-permission ul, .rightclickmenu .rc-metacode ul {
|
||||
.rightclickmenu .rc-permission ul,
|
||||
.rightclickmenu .rc-metacode ul,
|
||||
.rightclickmenu .rc-siblings ul {
|
||||
display: none;
|
||||
background: white;
|
||||
top: 0;
|
||||
|
@ -1255,7 +1257,9 @@ float: left;
|
|||
border-top-right-radius: 2px;
|
||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.12), 0 3px 3px rgba(0,0,0,0.24);
|
||||
}
|
||||
.rightclickmenu .rc-permission:hover > ul, .rightclickmenu .rc-metacode:hover > ul {
|
||||
.rightclickmenu .rc-permission:hover > ul,
|
||||
.rightclickmenu .rc-metacode:hover > ul,
|
||||
.rightclickmenu .rc-siblings:hover > ul {
|
||||
display: block;
|
||||
}
|
||||
.rightclickmenu p {
|
||||
|
@ -1283,20 +1287,24 @@ float: left;
|
|||
.rightclickmenu li.toPrivate .rc-perm-icon {
|
||||
background-position: -24px 0;
|
||||
}
|
||||
.rightclickmenu .rc-metacode > ul > li {
|
||||
.rightclickmenu .rc-metacode > ul > li,
|
||||
.rightclickmenu .rc-siblings > ul > li {
|
||||
padding: 6px 10px 6px 8px;
|
||||
width: 100px;
|
||||
}
|
||||
.rightclickmenu .rc-metacode ul ul {
|
||||
.rightclickmenu .rc-metacode ul ul,
|
||||
.rightclickmenu .rc-siblings ul ul {
|
||||
display: none;
|
||||
max-height: 270px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.rightclickmenu .rc-metacode li:hover ul {
|
||||
.rightclickmenu .rc-metacode li:hover ul,
|
||||
.rightclickmenu .rc-siblings li:hover ul {
|
||||
display: block;
|
||||
}
|
||||
.rightclickmenu .rc-metacode ul ul li {
|
||||
.rightclickmenu .rc-metacode ul ul li,
|
||||
.rightclickmenu .rc-siblings ul ul li {
|
||||
padding: 4px 10px 4px 8px;
|
||||
width: 120px;
|
||||
}
|
||||
|
@ -1315,15 +1323,24 @@ float: left;
|
|||
display: block;
|
||||
}
|
||||
|
||||
.moveMenusUp .rc-metacode ul, .moveMenusUp .rc-permission ul {
|
||||
.moveMenusUp .rc-metacode ul,
|
||||
.moveMenusUp .rc-permission ul,
|
||||
.moveMenusUp .rc-siblings ul {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
}
|
||||
.moveMenusToLeft .rc-metacode ul, .moveMenusToLeft .rc-permission ul {
|
||||
.moveMenusToLeft .rc-metacode ul,
|
||||
.moveMenusToLeft .rc-permission ul,
|
||||
.moveMenusToLeft .rc-siblings ul {
|
||||
left: auto;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
#loadingSiblings div {
|
||||
width: 15px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
/* end right click menu */
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class TopicsController < ApplicationController
|
|||
@topic = Topic.find(params[:id]).authorize_to_show(@current)
|
||||
|
||||
if not @topic
|
||||
redirect_to root_url and return
|
||||
redirect_to root_url, notice: "Access denied. That topic is private." and return
|
||||
end
|
||||
|
||||
@alltopics = @topic.relatives.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) }
|
||||
|
@ -90,6 +90,85 @@ class TopicsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# GET topics/:id/relative_numbers
|
||||
def relative_numbers
|
||||
@current = current_user
|
||||
@topic = Topic.find(params[:id]).authorize_to_show(@current)
|
||||
|
||||
if not @topic
|
||||
redirect_to root_url, notice: "Access denied. That topic is private." and return
|
||||
end
|
||||
|
||||
@topicsAlreadyHas = params[:network] ? params[:network].split(',') : []
|
||||
|
||||
@alltopics = @topic.relatives.delete_if {|t|
|
||||
@topicsAlreadyHas.index(t.id.to_s) != nil ||
|
||||
(t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)))
|
||||
}
|
||||
|
||||
@alltopics.uniq!
|
||||
|
||||
@json = Hash.new()
|
||||
@alltopics.each do |t|
|
||||
if @json[t.metacode.id]
|
||||
@json[t.metacode.id] += 1
|
||||
else
|
||||
@json[t.metacode.id] = 1
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: @json }
|
||||
end
|
||||
end
|
||||
|
||||
# GET topics/:id/relatives
|
||||
def relatives
|
||||
@current = current_user
|
||||
@topic = Topic.find(params[:id]).authorize_to_show(@current)
|
||||
|
||||
if not @topic
|
||||
redirect_to root_url, notice: "Access denied. That topic is private." and return
|
||||
end
|
||||
|
||||
@topicsAlreadyHas = params[:network] ? params[:network].split(',') : []
|
||||
|
||||
@alltopics = @topic.relatives.delete_if {|t|
|
||||
@topicsAlreadyHas.index(t.id.to_s) != nil ||
|
||||
(params[:metacode] && t.metacode_id.to_s != params[:metacode]) ||
|
||||
(t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)))
|
||||
}
|
||||
|
||||
@alltopics.uniq!
|
||||
|
||||
@allsynapses = @topic.synapses.delete_if {|s|
|
||||
(s.topic1 == @topic && @alltopics.index(s.topic2) == nil) ||
|
||||
(s.topic2 == @topic && @alltopics.index(s.topic1) == nil)
|
||||
}
|
||||
|
||||
@creatorsAlreadyHas = params[:creators] ? params[:creators].split(',') : []
|
||||
@allcreators = []
|
||||
@alltopics.each do |t|
|
||||
if @allcreators.index(t.user) == nil && @creatorsAlreadyHas.index(t.user_id.to_s) == nil
|
||||
@allcreators.push(t.user)
|
||||
end
|
||||
end
|
||||
@allsynapses.each do |s|
|
||||
if @allcreators.index(s.user) == nil && @creatorsAlreadyHas.index(s.user_id.to_s) == nil
|
||||
@allcreators.push(s.user)
|
||||
end
|
||||
end
|
||||
|
||||
@json = Hash.new()
|
||||
@json['topics'] = @alltopics
|
||||
@json['synapses'] = @allsynapses
|
||||
@json['creators'] = @allcreators
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: @json }
|
||||
end
|
||||
end
|
||||
|
||||
# POST /topics
|
||||
# POST /topics.json
|
||||
def create
|
||||
|
|
|
@ -22,6 +22,8 @@ Metamaps::Application.routes.draw do
|
|||
get :autocomplete_topic, :on => :collection
|
||||
end
|
||||
match 'topics/:id/network', to: 'topics#network', via: :get, as: :network
|
||||
match 'topics/:id/relative_numbers', to: 'topics#relative_numbers', via: :get, as: :relative_numbers
|
||||
match 'topics/:id/relatives', to: 'topics#relatives', via: :get, as: :relatives
|
||||
|
||||
match 'explore/active', to: 'maps#index', via: :get, as: :activemaps
|
||||
match 'explore/featured', to: 'maps#index', via: :get, as: :featuredmaps
|
||||
|
|
Loading…
Reference in a new issue