upated tooltips

This commit is contained in:
Bashar Jabbour 2014-11-12 13:36:41 -05:00
commit 02d49c166a
45 changed files with 749 additions and 200 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

View file

@ -1,6 +1,3 @@
var requestAnimId;
/*
Copyright (c) 2011 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/)

View file

@ -20,19 +20,26 @@ Metamaps.JIT = {
$(".zoomIn").click(self.zoomIn);
$(".zoomOut").click(self.zoomOut);
$(".zoomExtents").click(self.zoomExtents);
self.synapseStarImage = new Image();
self.synapseStarImage.src = '/assets/synapsestar.png';
var zoomExtents = function (event) {
self.zoomExtents(event, Metamaps.Visualize.mGraph.canvas);
};
$(".zoomExtents").click(zoomExtents);
self.topicMediaImage = new Image();
self.topicMediaImage.src = '/assets/linkedmedia.png';
$(".takeScreenshot").click(Metamaps.Map.exportImage);
self.topicDescImage = new Image();
self.topicDescImage.src = '/assets/topic_description_signifier.png';
self.topicLinkImage = new Image();
self.topicLinkImage.src = '/assets/topic_link_signifier.png';
},
/**
* 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;
@ -42,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);
}
@ -83,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;
}
@ -123,24 +140,45 @@ Metamaps.JIT = {
var directionCat = synapse.get("category");
//label placement on edges
Metamaps.JIT.renderEdgeArrows($jit.Graph.Plot.edgeHelper, adj, synapse);
if (canvas.denySelected) {
var color = Metamaps.Settings.colors.synapses.normal;
canvas.getCtx().fillStyle = canvas.getCtx().strokeStyle = color;
}
Metamaps.JIT.renderEdgeArrows($jit.Graph.Plot.edgeHelper, adj, synapse, canvas);
//check for edge label in data
var desc = synapse.get("desc");
var showDesc = adj.getData("showDesc");
var drawStar = function (context, x, y) {
var starImage = Metamaps.JIT.synapseStarImage;
var starImageLoaded = starImage.complete ||
(typeof starImage.naturalWidth !== "undefined" &&
starImage.naturalWidth !== 0)
if (starImageLoaded) {
context.drawImage(starImage, x, y, 16, 16);
}
var drawSynapseCount = function (context, x, y, count) {
/*
circle size: 16x16px
positioning: overlay and center on top right corner of synapse label - 8px left and 8px down
color: #dab539
border color: #424242
border size: 1.5px
font: DIN medium
font-size: 14pt
font-color: #424242
*/
context.beginPath();
context.arc(x, y, 8, 0, 2 * Math.PI, false);
context.fillStyle = '#DAB539';
context.strokeStyle = '#424242';
context.lineWidth = 1.5;
context.closePath();
context.fill();
context.stroke();
// add the synapse count
context.fillStyle = '#424242';
context.textAlign = 'center';
context.font = '14px din-medium';
context.fillText(count, x, y - 6);
};
if (desc != "" && showDesc) {
if (!canvas.denySelected && desc != "" && showDesc) {
// '&' to '&'
desc = Metamaps.Util.decodeEntities(desc);
@ -155,7 +193,7 @@ Metamaps.JIT = {
for (index = 0; index < arrayOfLabelLines.length; ++index) {
lineWidths.push(ctx.measureText(arrayOfLabelLines[index]).width)
}
var width = Math.max.apply(null, lineWidths) + 8;
var width = Math.max.apply(null, lineWidths) + 16;
var height = (16 * arrayOfLabelLines.length) + 8;
var x = (pos.x + posChild.x - width) / 2;
@ -177,23 +215,29 @@ Metamaps.JIT = {
ctx.closePath();
ctx.fill();
// get number of synapses
var synapseNum = adj.getData("synapses").length;
//render text
ctx.fillStyle = '#222222';
ctx.fillStyle = '#424242';
ctx.textAlign = 'center';
for (index = 0; index < arrayOfLabelLines.length; ++index) {
ctx.fillText(arrayOfLabelLines[index], x + (width / 2), y + 5 + (16 * index));
ctx.fillText(arrayOfLabelLines[index], x + (width / 2), y + 7 + (16 * index));
}
if (adj.getData("synapses").length > 1) {
drawStar(ctx, x + width, y);
if (synapseNum > 1) {
drawSynapseCount(ctx, x + width, y, synapseNum);
}
}
else if (showDesc) {
if (adj.getData("synapses").length > 1) {
else if (!canvas.denySelected && showDesc) {
// get number of synapses
var synapseNum = adj.getData("synapses").length;
if (synapseNum > 1) {
var ctx = canvas.getCtx();
var x = (pos.x + posChild.x) / 2;
var y = (pos.y + posChild.y) / 2;
drawStar(ctx, x, y);
drawSynapseCount(ctx, x, y, synapseNum);
}
}
@ -400,7 +444,7 @@ Metamaps.JIT = {
ctx = canvas.getCtx();
// if the topic is selected draw a circle around it
if (node.selected) {
if (!canvas.denySelected && node.selected) {
ctx.beginPath();
ctx.arc(pos.x, pos.y, dim + 3, 0, 2 * Math.PI, false);
ctx.strokeStyle = Metamaps.Settings.colors.topics.selected;
@ -423,12 +467,22 @@ Metamaps.JIT = {
// if the topic has a link, draw a small image to indicate that
var hasLink = topic && topic.get('link') !== "" && topic.get('link') !== null;
var linkImage = Metamaps.JIT.topicMediaImage;
var linkImage = Metamaps.JIT.topicLinkImage;
var linkImageLoaded = linkImage.complete ||
(typeof linkImage.naturalWidth !== "undefined" &&
linkImage.naturalWidth !== 0)
if (hasLink && linkImageLoaded) {
ctx.drawImage(linkImage, pos.x + dim / 2, pos.y - dim - 8, 16, 16);
ctx.drawImage(linkImage, pos.x - dim - 8, pos.y - dim - 8, 16, 16);
}
// if the topic has a desc, draw a small image to indicate that
var hasDesc = topic && topic.get('desc') !== "" && topic.get('desc') !== null;
var descImage = Metamaps.JIT.topicDescImage;
var descImageLoaded = descImage.complete ||
(typeof descImage.naturalWidth !== "undefined" &&
descImage.naturalWidth !== 0)
if (hasDesc && descImageLoaded) {
ctx.drawImage(descImage, pos.x + dim - 8, pos.y - dim - 8, 16, 16);
}
},
'contains': function (node, pos) {
@ -469,7 +523,7 @@ Metamaps.JIT = {
if (-1 < pos.x && pos.x < 1) pos.x = 0;
if (-1 < pos.y && pos.y < 1) pos.y = 0;
return $jit.Graph.Plot.edgeHelper.line.contains(from, to, pos, adj.Edge.epsilon);
return $jit.Graph.Plot.edgeHelper.line.contains(from, to, pos, adj.Edge.epsilon + 5);
}
}
}
@ -865,6 +919,9 @@ Metamaps.JIT = {
};
}
}
else if ((e.button == 2 || (e.button == 0 && e.altKey) || e.buttons == 2) && Metamaps.Active.Topic) {
Metamaps.GlobalUI.notifyUser("Cannot create in Topic view.");
}
else if ((e.button == 2 || (e.button == 0 && e.altKey) || e.buttons == 2) && !authorized) {
Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
}
@ -959,6 +1016,10 @@ Metamaps.JIT = {
Metamaps.GlobalUI.notifyUser("Cannot edit Public map.");
return;
}
else if (Metamaps.Active.Topic) {
Metamaps.GlobalUI.notifyUser("Cannot create in Topic view.");
return;
}
// DOUBLE CLICK
//pop up node creation :)
Metamaps.Create.newTopic.addSynapse = false;
@ -1269,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> \
@ -1283,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;
@ -1376,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;
@ -1595,12 +1730,10 @@ Metamaps.JIT = {
ctx.lineTo(v2.x, v2.y);
ctx.stroke();
}, // renderMidArrow
renderEdgeArrows: function (edgeHelper, adj, synapse) {
renderEdgeArrows: function (edgeHelper, adj, synapse, canvas) {
var self = Metamaps.JIT;
var canvas = Metamaps.Visualize.mGraph.canvas;
var directionCat = synapse.get('category');
var direction = synapse.getDirection();
@ -1657,8 +1790,7 @@ Metamaps.JIT = {
Metamaps.Visualize.mGraph.canvas.scale(0.8,0.8);
$(document).trigger(Metamaps.JIT.events.zoom, [event]);
},
centerMap: function () {
var canvas = Metamaps.Visualize.mGraph.canvas;
centerMap: function (canvas) {
var offsetScale = canvas.scaleOffsetX;
canvas.scale(1/offsetScale,1/offsetScale);
@ -1674,7 +1806,8 @@ Metamaps.JIT = {
eX = Metamaps.Mouse.boxEndCoordinates.x,
eY = Metamaps.Mouse.boxEndCoordinates.y;
Metamaps.JIT.centerMap();
var canvas = Metamaps.Visualize.mGraph.canvas;
Metamaps.JIT.centerMap(canvas);
var height = $(document).height(),
width = $(document).width();
@ -1686,8 +1819,6 @@ Metamaps.JIT = {
var newRatio = Math.min(ratioX,ratioY);
var canvas = Metamaps.Visualize.mGraph.canvas;
if(canvas.scaleOffsetX *newRatio<= 5 && canvas.scaleOffsetX*newRatio >= 0.2){
canvas.scale(newRatio,newRatio);
}
@ -1711,15 +1842,14 @@ Metamaps.JIT = {
Metamaps.Visualize.mGraph.plot();
},
zoomExtents: function (event) {
Metamaps.JIT.centerMap();
var height = $(document).height(),
width = $(document).width(),
zoomExtents: function (event, canvas, denySelected) {
Metamaps.JIT.centerMap(canvas);
var height = canvas.getSize().height,
width = canvas.getSize().width,
maxX, minX, maxY, minY, counter = 0;
var canvas = Metamaps.Visualize.mGraph.canvas;
if (Metamaps.Selected.Nodes.length > 0) {
if (!denySelected && Metamaps.Selected.Nodes.length > 0) {
var nodes = Metamaps.Selected.Nodes;
}
else {

View file

@ -125,7 +125,7 @@
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty();
Metamaps.Visualize.mGraph.plot();
Metamaps.JIT.centerMap();
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
}
Metamaps.Famous.viz.show();
Metamaps.Topic.end();
@ -156,7 +156,7 @@
if (Metamaps.Visualize.mGraph) {
Metamaps.Visualize.mGraph.graph.empty();
Metamaps.Visualize.mGraph.plot();
Metamaps.JIT.centerMap();
Metamaps.JIT.centerMap(Metamaps.Visualize.mGraph.canvas);
}
Metamaps.Famous.viz.show();
Metamaps.Map.end();

View file

@ -82,6 +82,7 @@ Metamaps.Backbone.init = function () {
self.Metacode = Backbone.Model.extend({
initialize: function () {
var image = new Image();
image.crossOrigin = "Anonymous";
image.src = this.get('icon');
this.set('image',image);
},
@ -218,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();
@ -476,6 +476,9 @@ Metamaps.Backbone.init = function () {
Metamaps.Mappers = Metamaps.Mappers ? new self.MapperCollection(Metamaps.Mappers) : new self.MapperCollection();
// this is for topic view
Metamaps.Creators = Metamaps.Creators ? new self.MapperCollection(Metamaps.Creators) : new self.MapperCollection();
if (Metamaps.Active.Map) {
Metamaps.Mappings = Metamaps.Mappings ? new self.MappingCollection(Metamaps.Mappings) : new self.MappingCollection();
@ -1504,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 });
@ -3150,12 +3155,30 @@ Metamaps.Filter = {
var removed = [];
var added = [];
Metamaps[collection].each(function(model) {
var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
if (prop && newList.indexOf(prop) === -1) {
newList.push(prop);
}
});
// the first option enables us to accept
// ['Topics', 'Synapses'] as 'collection'
if (typeof collection === "object") {
Metamaps[collection[0]].each(function(model) {
var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
if (prop && newList.indexOf(prop) === -1) {
newList.push(prop);
}
});
Metamaps[collection[1]].each(function(model) {
var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
if (prop && newList.indexOf(prop) === -1) {
newList.push(prop);
}
});
}
else if (typeof collection === "string") {
Metamaps[collection].each(function(model) {
var prop = model.get(propertyToCheck) ? model.get(propertyToCheck).toString() : false;
if (prop && newList.indexOf(prop) === -1) {
newList.push(prop);
}
});
}
removed = _.difference(self.filters[filtersToUse], newList);
added = _.difference(newList, self.filters[filtersToUse]);
@ -3198,7 +3221,14 @@ Metamaps.Filter = {
},
checkMappers: function () {
var self = Metamaps.Filter;
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper');
var onMap = Metamaps.Active.Map ? true : false;
if (onMap) {
self.updateFilters('Mappings', 'user_id', 'Mappers', 'mappers', 'mapper');
}
else {
// on topic view
self.updateFilters(['Topics', 'Synapses'], 'user_id', 'Creators', 'mappers', 'mapper');
}
},
checkSynapses: function () {
var self = Metamaps.Filter;
@ -3279,7 +3309,11 @@ Metamaps.Filter = {
if (Metamaps.Active.Map) {
onMap = true;
}
else passesMapper = true; // for when you're on a topic page
else if (Metamaps.Active.Topic) {
onMap = false;
}
var opacityForFilter = onMap ? 0 : 0.4;
Metamaps.Topics.each(function(topic) {
var n = topic.get('node');
@ -3289,10 +3323,21 @@ Metamaps.Filter = {
else passesMetacode = true;
if (onMap) {
// when on a map,
// we filter by mapper according to the person who added the
// topic or synapse to the map
var user_id = topic.getMapping().get("user_id").toString();
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false;
else passesMapper = true;
}
else {
// when on a topic view,
// we filter by mapper according to the person who created the
// topic or synapse
var user_id = topic.get("user_id").toString();
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false;
else passesMapper = true;
}
if (passesMetacode && passesMapper) {
if (n) {
@ -3303,7 +3348,7 @@ Metamaps.Filter = {
else {
if (n) {
Metamaps.Control.deselectNode(n, true);
n.setData('alpha', 0, 'end');
n.setData('alpha', opacityForFilter, 'end');
n.eachAdjacency(function(e){
Metamaps.Control.deselectEdge(e, true);
});
@ -3320,10 +3365,13 @@ Metamaps.Filter = {
else passesSynapse = true;
if (onMap) {
var user_id = synapse.getMapping().get("user_id").toString();
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false;
else passesMapper = true;
// when on a map,
// we filter by mapper according to the person who added the
// topic or synapse to the map
user_id = synapse.getMapping().get("user_id").toString();
}
if (visible.mappers.indexOf(user_id) == -1) passesMapper = false;
else passesMapper = true;
var color = Metamaps.Settings.colors.synapses.normal;
if (passesSynapse && passesMapper) {
@ -3336,10 +3384,10 @@ Metamaps.Filter = {
else {
if (e) {
Metamaps.Control.deselectEdge(e, true);
e.setData('alpha', 0, 'end');
e.setData('alpha', opacityForFilter, 'end');
}
else console.log(synapse);
}
}
});
// run the animation
@ -3389,7 +3437,7 @@ Metamaps.Listeners = {
case 69: //if e or E is pressed
if (e.ctrlKey){
e.preventDefault();
Metamaps.JIT.zoomExtents();
Metamaps.JIT.zoomExtents(null, Metamaps.Visualize.mGraph.canvas);
}
break;
case 77: //if m or M is pressed
@ -3590,10 +3638,14 @@ Metamaps.Topic = {
var bb = Metamaps.Backbone;
var start = function (data) {
Metamaps.Active.Topic = new bb.Topic(data.topic);
Metamaps.Creators = new bb.MapperCollection(data.creators);
Metamaps.Topics = new bb.TopicCollection([data.topic].concat(data.relatives));
Metamaps.Synapses = new bb.SynapseCollection(data.synapses);
Metamaps.Backbone.attachCollectionEvents();
// set filter mapper H3 text
$('#filter_by_mapper h3').html('CREATORS');
// build and render the visualization
Metamaps.Visualize.type = "RGraph";
Metamaps.JIT.prepareVizData();
@ -3620,12 +3672,12 @@ Metamaps.Topic = {
$('.rightclickmenu').remove();
Metamaps.TopicCard.hideCard();
Metamaps.SynapseCard.hideCard();
Metamaps.Filter.close();
}
},
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 () {
@ -3634,6 +3686,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 () {
}
});
},
/*
*
*
@ -4048,6 +4160,9 @@ Metamaps.Map = {
$('.wrapper').addClass('commonsMap');
}
// set filter mapper H3 text
$('#filter_by_mapper h3').html('MAPPERS');
// build and render the visualization
Metamaps.Visualize.type = "ForceDirected";
Metamaps.JIT.prepareVizData();
@ -4086,6 +4201,7 @@ Metamaps.Map = {
Metamaps.SynapseCard.hideCard();
Metamaps.Create.newTopic.hide();
Metamaps.Create.newSynapse.hide();
Metamaps.Filter.close();
Metamaps.Realtime.endActiveMap();
}
},
@ -4094,31 +4210,37 @@ Metamaps.Map = {
var nodes_data = "",
synapses_data = "";
var synapses_array = new Array();
var nodes_array = [];
var synapses_array = [];
// collect the unfiltered topics
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
//don't add to the map if it was filtered out
// TODO
//if (categoryVisible[n.getData('metacode')] == false) {
// return;
//}
var x, y;
if (n.pos.x && n.pos.y) {
x = n.pos.x;
y = n.pos.y;
} else {
var x = Math.cos(n.pos.theta) * n.pos.rho;
var y = Math.sin(n.pos.theta) * n.pos.rho;
// if the opacity is less than 1 then it's filtered
if (n.getData('alpha') === 1) {
var id = n.getData('topic').id;
nodes_array.push(id);
var x, y;
if (n.pos.x && n.pos.y) {
x = n.pos.x;
y = n.pos.y;
} else {
var x = Math.cos(n.pos.theta) * n.pos.rho;
var y = Math.sin(n.pos.theta) * n.pos.rho;
}
nodes_data += id + '/' + x + '/' + y + ',';
}
nodes_data += n.id + '/' + x + '/' + y + ',';
n.eachAdjacency(function (adj) {
synapses_array.push(adj.getData("synapses")[0].id); // TODO
});
});
// collect the unfiltered synapses
Metamaps.Synapses.each(function(synapse){
var desc = synapse.get("desc");
//get unique values only
synapses_array = $.grep(synapses_array, function (value, key) {
return $.inArray(value, synapses_array) === key;
var descNotFiltered = Metamaps.Filter.visible.synapses.indexOf(desc) > -1;
// make sure that both topics are being added, otherwise, it
// doesn't make sense to add the synapse
var topicsNotFiltered = nodes_array.indexOf(synapse.get('node1_id')) > -1;
topicsNotFiltered = topicsNotFiltered && nodes_array.indexOf(synapse.get('node2_id')) > -1;
if (descNotFiltered && topicsNotFiltered) {
synapses_array.push(synapse.id);
}
});
synapses_data = synapses_array.join();
@ -4209,6 +4331,131 @@ Metamaps.Map = {
Metamaps.Map.sideLength = 1;
Metamaps.Map.timeToTurn = 0;
Metamaps.Map.turnCount = 0;
},
exportImage: function() {
var canvas = {};
canvas.canvas = document.createElement("canvas");
canvas.canvas.width = 1880; // 960;
canvas.canvas.height = 1260; // 630
canvas.scaleOffsetX = 1;
canvas.scaleOffsetY = 1;
canvas.translateOffsetY = 0;
canvas.translateOffsetX = 0;
canvas.denySelected = true;
canvas.getSize = function() {
if(this.size) return this.size;
var canvas = this.canvas;
return this.size = {
width: canvas.width,
height: canvas.height
};
};
canvas.scale = function(x, y) {
var px = this.scaleOffsetX * x,
py = this.scaleOffsetY * y;
var dx = this.translateOffsetX * (x -1) / px,
dy = this.translateOffsetY * (y -1) / py;
this.scaleOffsetX = px;
this.scaleOffsetY = py;
this.getCtx().scale(x, y);
this.translate(dx, dy);
};
canvas.translate = function(x, y) {
var sx = this.scaleOffsetX,
sy = this.scaleOffsetY;
this.translateOffsetX += x*sx;
this.translateOffsetY += y*sy;
this.getCtx().translate(x, y);
};
canvas.getCtx = function() {
return this.canvas.getContext("2d");
};
// center it
canvas.getCtx().translate(1880/2, 1260/2);
var mGraph = Metamaps.Visualize.mGraph;
var id = mGraph.root;
var root = mGraph.graph.getNode(id);
var T = !!root.visited;
// pass true to avoid basing it on a selection
Metamaps.JIT.zoomExtents(null, canvas, true);
var c = canvas.canvas,
ctx = canvas.getCtx(),
scale = canvas.scaleOffsetX;
// draw a grey background
ctx.fillStyle = '#d8d9da';
var xPoint = (-(c.width/scale)/2) - (canvas.translateOffsetX/scale),
yPoint = (-(c.height/scale)/2) - (canvas.translateOffsetY/scale);
ctx.fillRect(xPoint,yPoint,c.width/scale,c.height/scale);
// draw the graph
mGraph.graph.eachNode(function(node) {
var nodeAlpha = node.getData('alpha');
node.eachAdjacency(function(adj) {
var nodeTo = adj.nodeTo;
if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
mGraph.fx.plotLine(adj, canvas);
}
});
if(node.drawn) {
mGraph.fx.plotNode(node, canvas);
}
if(!mGraph.labelsHidden) {
if(node.drawn && nodeAlpha >= 0.95) {
mGraph.labels.plotLabel(canvas, node);
} else {
mGraph.labels.hideLabel(node, false);
}
}
node.visited = !T;
});
var imageData = {
encoded_image: canvas.canvas.toDataURL()
};
console.log(imageData.encoded_image);
var map = Metamaps.Active.Map;
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10) {
dd='0'+dd
}
if(mm<10) {
mm='0'+mm
}
today = mm+'/'+dd+'/'+yyyy;
var mapName = map.get("name").split(" ").join([separator = '-']);
var downloadMessage = "";
downloadMessage += "Captured map screenshot! ";
downloadMessage += "<a href='" + imageData.encoded_image + "' ";
downloadMessage += "download='metamap-" + map.id + "-" + mapName + "-" + today + ".png'>DOWNLOAD</a>";
Metamaps.GlobalUI.notifyUser(downloadMessage);
$.ajax({
type: "POST",
dataType: 'json',
url: "/maps/" + Metamaps.Active.Map.id + "/upload_screenshot",
data: imageData,
success: function (data) {
console.log('successfully uploaded map screenshot');
},
error: function () {
console.log('failed to save map screenshot');
}
});
}
};
@ -4559,8 +4806,6 @@ Metamaps.Account = {
var destWidth = 84;
var destHeight = 84;
//debugger;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
$('.userImageDiv').prepend($canvas);
};

View file

@ -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');
}
});
}

View file

@ -519,19 +519,19 @@ input[type="submit"]:active {
#new_topic .twitter-typeahead {
position: absolute !important;
top: 40px;
left: 35px;
top: 45px;
left: 41px;
z-index: 9999;
width: 270px;
width: 256px;
height: 42px;
}
.new_topic #topic_name,
.new_topic .tt-hint {
width: 254px;
width: 244px;
background: #FFFFFF;
height: 14px;
margin: 0;
padding: 14px 8px;
padding: 10px 6px;
border: none;
border-radius: 2px;
outline: none;
@ -581,11 +581,11 @@ input[type="submit"]:active {
}
.new_synapse #synapse_desc,
.new_synapse .tt-hint {
width: 254px;
width: 244px;
background: #FFFFFF;
height: 14px;
margin: 0;
padding: 14px 8px;
padding: 10px 6px;
border: none;
border-radius: 2px;
outline: none;
@ -1170,8 +1170,9 @@ h3.realtimeBoxTitle {
.rightclickmenu {
position: absolute;
width: 300px;
width: 260px;
background: #FFFFFF;
padding: 6px 0px 6px 0px;
z-index: 20;
border-radius: 2px;
color: black;
@ -1184,8 +1185,8 @@ h3.realtimeBoxTitle {
list-style: none;
padding: 6px 10px 6px 32px;
font-family: helvetica, sans-serif;
font-size: 12px;
line-height: 12px;
font-size: 13px;
line-height: 15px;
position: relative;
}
.rightclickmenu li:hover {
@ -1219,7 +1220,7 @@ h3.realtimeBoxTitle {
}
.rightclickmenu .rc-center .rc-icon {
background-image: url(context_topicview_sprite.png);
}
.rightclickmenu .rc-popout .rc-icon {
background-position: 0 -72px;
@ -1230,6 +1231,10 @@ h3.realtimeBoxTitle {
.rightclickmenu .rc-metacode .rc-icon {
background-position: 0 -120px;
}
.rightclickmenu .rc-siblings .rc-icon {
background-position: 0 -24px;
background-image: url(context_topicview_sprite.png);
}
.rightclickmenu .expandLi {
position: absolute;
top: 4px;
@ -1243,7 +1248,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;
@ -1254,7 +1261,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 {
@ -1282,20 +1291,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;
}
@ -1314,15 +1327,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 */
@ -1337,7 +1359,7 @@ float: left;
#new_topic .tt-suggestion,
#new_synapse .tt-suggestion {
background: #F5F5F5;
width: 270px;
width: 256px;
position: relative;
}
#new_topic .autocompleteSection {
@ -1606,7 +1628,7 @@ float: left;
background-position: 13px center;
}
.mapSynapses {
background-image: url(synapse32.png);
background-image: url(synapse32padded.png);
background-position: 13px center;
}
.mapInfoBox .mapPermission {
@ -1671,7 +1693,7 @@ float: left;
.mapInfoBox .mapInfoDesc {
font-family: helvetica, sans-serif;
color: #E0E0E0;
margin: 8px;
margin: 16px;
padding-right: 16px;
height: 115px;
font-size: 14px;

View file

@ -110,7 +110,7 @@
display:block;
padding: 8px 0 8px 16px;
height: 152px;
font-size: 12px;
font-size: 13px;
line-height:15px;
font-family: helvetica, sans-serif;
overflow-y: auto;
@ -120,7 +120,7 @@
}
.CardOnGraph .best_in_place_desc textarea {
font-size: 12px;
font-size: 13px;
line-height:15px;
font-family: helvetica, sans-serif;
color: #424242;
@ -170,8 +170,8 @@ resize: none;
z-index: 1;
position: relative;
color: #424242;
font-size: 12px;
line-height:12px;
font-size: 14px;
line-height:14px;
height:12px;
padding:17px 0;
}
@ -187,9 +187,9 @@ resize: none;
height: 48px;
}
.linkItem.contributor {
margin-left:32px;
margin-left:40px;
z-index:1;
padding:17px 16px 17px 32px;
padding:17px 16px 17px 30px;
position: relative;
}
.contributor .contributorIcon {
@ -202,8 +202,9 @@ resize: none;
display:none;
}
.linkItem.mapCount {
margin-left: 12px;
width: 24px;
padding:17px 0 17px 35px;
padding:17px 0 17px 36px;
}
.linkItem.mapCount .mapCountIcon {
position: absolute;
@ -219,8 +220,9 @@ resize: none;
background-position: 0 -32px;
}
.linkItem.synapseCount {
margin-left: 2px;
width: 24px;
padding:17px 0 17px 35px;
padding:17px 0 17px 32px;
}
.linkItem.synapseCount .synapseCountIcon {
position: absolute;
@ -241,6 +243,7 @@ resize: none;
padding: 0;
min-width: 32px;
margin-top: 8px;
margin-left: 8px;
background-image: url(permissions32_sprite.png);
background-position: 0 0;
}
@ -507,6 +510,8 @@ background-color: #E0E0E0;
width: 268px;
padding: 8px 16px 8px 16px;
position: relative;
border: none;
line-height: 14px;
}
#addLinkInput input{

View file

@ -191,7 +191,7 @@
.explorePage .sidebarSearchField,
.explorePage .sidebarSearch .tt-hint {
width: 380px;
padding: 7px 10px 3px 10px;
padding: 5px 10px 5px 10px;
}
.sidebarSearchField {
@ -207,7 +207,7 @@
border-bottom: 1px solid #BDBDBD;
border-left: none;
border-right: none;
padding: 7px 0 3px 0;
padding: 5px 0 5px 0;
width: 0px;
margin: 0;
outline: none;
@ -218,7 +218,7 @@
}
.sidebarSearch .tt-dropdown-menu {
top: 40px !important;
background: #FFF;
background: #F5F5F5;
width: 472px;
overflow-y: auto;
overflow-x: hidden;
@ -577,7 +577,7 @@
top: 0;
}
.topicPage .sidebarCollaborate, .topicPage .sidebarFilter {
.topicPage .sidebarCollaborate {
display: none;
}
@ -767,6 +767,20 @@
.mapControls:hover, .infoAndHelp:hover {
z-index: 4;
}
.takeScreenshot {
margin-bottom: 5px;
border-radius: 2px;
background-image: url(screenshot_sprite.png);
display: none;
}
.takeScreenshot:hover {
background-position: -32px 0;
}
.canEditMap .takeScreenshot {
display: block;
}
.zoomExtents {
margin-bottom:5px;
border-radius: 2px;
@ -1026,6 +1040,10 @@
line-height:14px;
}
.toast a {
color: #4fc059;
}
/* end toast */
/* feedback */

View file

@ -1,6 +1,6 @@
class MapsController < ApplicationController
before_filter :require_user, only: [:create, :update, :destroy]
before_filter :require_user, only: [:create, :update, :screenshot, :destroy]
respond_to :html, :json
@ -83,7 +83,14 @@ class MapsController < ApplicationController
@allmappers = @map.contributors
@alltopics = @map.topics.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) }
@allsynapses = @map.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) }
@allmappings = @map.mappings
@allmappings = @map.mappings.delete_if {|m|
if m.category == "Synapse"
object = m.synapse
elsif m.category == "Topic"
object = m.topic
end
!object || (object.permission == "private" && (!authenticated? || (authenticated? && @current.id != object.user_id)))
}
respond_with(@allmappers, @allmappings, @allsynapses, @alltopics, @map)
}
@ -104,7 +111,14 @@ class MapsController < ApplicationController
@allmappers = @map.contributors
@alltopics = @map.topics.delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) }
@allsynapses = @map.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) }
@allmappings = @map.mappings
@allmappings = @map.mappings.delete_if {|m|
if m.category == "Synapse"
object = m.synapse
elsif m.category == "Topic"
object = m.topic
end
!object || (object.permission == "private" && (!authenticated? || (authenticated? && @current.id != object.user_id)))
}
@json = Hash.new()
@json['map'] = @map
@ -183,6 +197,30 @@ class MapsController < ApplicationController
end
end
# POST maps/:id/upload_screenshot
def screenshot
@current = current_user
@map = Map.find(params[:id]).authorize_to_edit(@current)
if @map
png = Base64.decode64(params[:encoded_image]['data:image/png;base64,'.length .. -1])
StringIO.open(png) do |data|
data.class.class_eval { attr_accessor :original_filename, :content_type }
data.original_filename = "map-" + @map.id.to_s + "-screenshot.png"
data.content_type = "image/png"
@map.screenshot = data
end
if @map.save
render :json => {:message => "Successfully uploaded the map screenshot."}
else
render :json => {:message => "Failed to upload image."}
end
else
render :json => {:message => "Unauthorized to set map screenshot."}
end
end
# DELETE maps/:id
def destroy
@current = current_user

View file

@ -29,7 +29,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
respond_to do |format|
@ -37,7 +37,19 @@ class TopicsController < ApplicationController
@alltopics = ([@topic] + @topic.relatives).delete_if {|t| t.permission == "private" && (!authenticated? || (authenticated? && @current.id != t.user_id)) } # should limit to topics visible to user
@allsynapses = @topic.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) }
respond_with(@allsynapses, @alltopics, @topic)
@allcreators = []
@alltopics.each do |t|
if @allcreators.index(t.user) == nil
@allcreators.push(t.user)
end
end
@allsynapses.each do |s|
if @allcreators.index(s.user) == nil
@allcreators.push(s.user)
end
end
respond_with(@allsynapses, @alltopics, @allcreators, @topic)
}
format.json { render json: @topic }
end
@ -49,14 +61,27 @@ 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)) }
@allsynapses = @topic.synapses.delete_if {|s| s.permission == "private" && (!authenticated? || (authenticated? && @current.id != s.user_id)) }
@allcreators = []
@allcreators.push(@topic.user)
@alltopics.each do |t|
if @allcreators.index(t.user) == nil
@allcreators.push(t.user)
end
end
@allsynapses.each do |s|
if @allcreators.index(s.user) == nil
@allcreators.push(s.user)
end
end
@json = Hash.new()
@json['topic'] = @topic
@json['creators'] = @allcreators
@json['relatives'] = @alltopics
@json['synapses'] = @allsynapses
@ -65,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

View file

@ -8,12 +8,12 @@ class Map < ActiveRecord::Base
has_many :topics, :through => :topicmappings
has_many :synapses, :through => :synapsemappings
after_touch :save_screenshot
#after_touch :save_screenshot
# This method associates the attribute ":image" with a file attachment
has_attached_file :screenshot, :styles => {
:thumb => ['188x126#', :png],
:full => ['940x630#', :png]
:thumb => ['188x126#', :png]
#:full => ['940x630#', :png]
},
:default_url => "/assets/missing-map.png"

View file

@ -112,19 +112,20 @@
<li>Asana</li>
<li>Invision App <a href="http://invis.io/541GCFJRM">*</a></li>
<li>Docracy <a href="https://www.docracy.com/userprofile/show?userId=7366">*</a></li>
<li>Google Hangouts</li>
<li>Google Plus <a href="https://plus.google.com/communities/115060009262157699234">*</a></li>
<li>Hipchat</li>
<li>Hackpad <a href="http://metamaps.hackpad.com/">*</a></li>
<li>Loomio <a href="https://www.loomio.org/g/bu3L1tIW/topos-ffo">*</a></li>
<li>Twitter <a href="http://twitter.com/metamapps">*</a></li>
<li>Hipchat</li>
<li>Google Hangouts</li>
<li>Vimeo </li>
<li>Youtube</li></ul>
<br>
<h4 id="colophonSection">Development</h4>
<h4 id="colophonSection">Design & Development</h4>
<ul>
<li>Git</li>
<li>Github<a href="https://github.com/Connoropolous/metamaps_gen002">*</a></li></ul>
<li>Github<a href="https://github.com/metamaps">*</a></li>
<li>Pixelapse<a href="https://www.pixelapse.com/poietic/projects/Metamaps.cc/overview">*</a></li>
</ul>
<h4 id="colophonSection">Documentation</h4>
<ul><li>Dropbox <a href="https://www.dropbox.com/sh/qqkesm0pmzaihfa/AAAv9aCVZeawUzDXrdM9y3T5a?dl=0">*</a></li>
<li>Google Drive <a href="https://drive.google.com/folderview?id=0B_RQI2WcwEHLckplOHhhdnZkSUE&usp=sharing">*</a></li>
@ -158,7 +159,7 @@
<div class="lightboxContent" id="donate">
<h3>Donate!</h3>
<p>The Metamaps.cc project has been bootstrapped through our own pockets, lots of time, and a couple of small grants which have gone to supporting our small full-time team. Some of us have used Metamaps.cc as a tool for our own freelance consulting practice, and we are starting to create hosted and customized installations of Metamaps for different clients as one business model.</p>
<p>The Metamaps.cc project has been bootstrapped through our own pockets, passion, and patrons - including a couple of small grants which have gone to supporting our core contributors. Some of us have used Metamaps.cc as a tool for our own freelance consulting practice, and we are starting to create hosted and customized installations of Metamaps for different clients as one business model.</p>
<p>We will continue to bootstrap this project and experiment with alternative business models that are aligned with our values and mission and do not involve exploitation of our users, exclusivity or privatization of the technology. </p>
@ -188,26 +189,25 @@
<div class="clearfloat"></div>
</div>
</div>
<div class="lightboxContent" id="getInvolved">
<h3>GET INVOLVED!</h3>
<div class="leaveSpace"></div>
<div class="leaveSpace"></div>
<p>Want to help us with design, code, community building, and communications for Metamaps? We're an open value network, which for us means we want to invite and empower peers to participate in creating value together.
<p>Want to help with design, code, community building, or communications for Metamaps? We're an open value network, which for us means we want to invite and empower peers to participate in creating value together.
<p>To be a user, request an invite! We'll expect you to abide by our <a href="http://metamaps.cc/maps/331" target="_blank">terms of service</a>.</p>
<p>To be a <b>USER</b>, request an invite! We'll expect you to abide by our <a href="http://metamaps.cc/maps/331" target="_blank">terms of service</a>.</p>
<p>To be a contributor, simply enter our space and join the conversation! We'll expect you to behave well.</p>
<p>To be a <b>CONTRIBUTOR</b>, simply <a href="https://docs.google.com/document/d/1z8FsSmYkHbLRLOsXc8i8M5ubKky8_WB2E9bLBoXJapU" target="_blank">enter our space</a> and join the conversation! We'll expect you to follow some guidelines.</p>
<p>Members are contributors who act as stewards and guardians of the collective and are responsible for maintaining our culture and purpose. We're working on a set of agreements to formalize what it means to be a member.</p>
<p><b>MEMBERS</b> are contributors who act as stewards and guardians of the collective and are responsible for maintaining our culture and purpose. We're working on a set of agreements to formalize what it means to be a member.</p>
<p>We welcome people of all skillsets to create value within our network. There's open possibilities for designers, researchers, academics, strategists, and facilitators to contribute. If you're a developer, help us advance the code and take a look around our <a href="http://github.com/connoropolous/metamaps_gen002" target="_blank">Github</a>.</p>
<p>Thanks for your interest in helping out with Metamaps! Hopefully this gets you pointed in the right direction to get involved. The next step is to read the links on this page and then contribute! </p>
</div>
<div class="clearfloat"></div>
</div>
@ -225,7 +225,7 @@
<h3>SHARE INVITE</h3>
<div class="leaveSpace"></div>
<p>The Metamaps platform is currently in an invite-only beta with the express purpose of creating a high value knowledge ecosystem, as well as building a community of contributors. As a valued beta tester, you have the ability to invite your peers, colleagues and collaborators onto the platform.</p>
<p>The Metamaps platform is currently in an invite-only beta with the express purpose of creating a high value knowledge ecosystem, as well as building an active community of contributors and healthy culture. As a valued beta tester, you have the ability to invite your peers, colleagues and collaborators onto the platform.</p>
<p>Copy and send the link + access code below. The access code below is your personal code and can be used multiple times.</p>
<div id="joinCodesBox">
<p class="joinCodes">HTTP://METAMAPS.CC/JOIN</p>

View file

@ -1,4 +1,5 @@
<div class="mapControls mapElement">
<div class="takeScreenshot mapControl"></div>
<div class="zoomExtents mapControl"><div class="tooltips">Center View</div></div>
<div class="zoomIn mapControl"><div class="tooltips">Zoom In</div></div>
<div class="zoomOut mapControl"><div class="tooltips">Zoom In</div></div>

View file

@ -17,22 +17,41 @@
#and metacodes is filled with all the metacodes that are being used on the map.
if @map
@map.topics.each_with_index do |topic, index|
@alltopics.each_with_index do |topic, index|
if @metacodes.index(topic.metacode) == nil
@metacodes.push(topic.metacode)
end
end
@map.synapses.each_with_index do |synapse, index|
@allsynapses.each_with_index do |synapse, index|
if @synapses.index{|s| s.desc == synapse.desc} == nil
@synapses.push(synapse)
end
end
@map.mappings.each_with_index do |mapping, index|
@allmappings.each_with_index do |mapping, index|
if @mappers.index(mapping.user) == nil
@mappers.push(mapping.user)
end
end
elsif @topic
@alltopics.each_with_index do |topic, index|
if @metacodes.index(topic.metacode) == nil
@metacodes.push(topic.metacode)
end
if @mappers.index(topic.user) == nil
@mappers.push(topic.user)
end
end
@allsynapses.each_with_index do |synapse, index|
if @synapses.index{|s| s.desc == synapse.desc} == nil
@synapses.push(synapse)
end
if @mappers.index(synapse.user) == nil
@mappers.push(synapse.user)
end
end
end
if @map || @topic
@metacodes.sort! {|x,y|
n1 = x.name || ""
n2 = y.name || ""
@ -70,7 +89,7 @@
<div class="filterBox">
<h2>FILTER BY</h2>
<div id="filter_by_mapper" class="filterBySection">
<h3>MAPPERS</h3>
<h3><%= @map ? "MAPPERS" : @topic ? "CREATORS" : "" %></h3>
<span class="hideAll hideAllMappers">NONE</span>
<span class="showAll showAllMappers">ALL</span>
<div class="clearfloat"></div>

View file

@ -19,6 +19,7 @@
Metamaps.currentSection = "topic";
Metamaps.currentPage = <%= @topic.id.to_s %>;
Metamaps.Active.Topic = <%= @topic.to_json.html_safe %>;
Metamaps.Creators = <%= @allcreators.to_json.html_safe %>;
Metamaps.Topics = <%= @alltopics.to_json.html_safe %>;
Metamaps.Synapses = <%= @allsynapses.to_json.html_safe %>;
Metamaps.Visualize.type = "RGraph";

View file

@ -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
@ -30,6 +32,7 @@ Metamaps::Application.routes.draw do
match 'maps/topics/:id', to: 'maps#index', via: :get, as: :topicmaps
resources :maps, except: [:new, :edit]
match 'maps/:id/contains', to: 'maps#contains', via: :get, as: :contains
match 'maps/:id/upload_screenshot', to: 'maps#screenshot', via: :post, as: :screenshot
devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords', sessions: 'devise/sessions' }, :skip => [:sessions]

View file

@ -6,7 +6,7 @@ t.logoContent = '<div class="logo">METAMAPS</div>';
t.logoContent += '<ul class="bottomLinks">';
t.logoContent += '<li onclick="Metamaps.GlobalUI.openLightbox(\'about\')">About /&nbsp;</li>';
t.logoContent += '<li onclick="Metamaps.GlobalUI.openLightbox(\'colophon\')">Colophon /&nbsp;</li>';
t.logoContent += '<li onclick="Metamaps.GlobalUI.openLightbox(\'donate\')">Donate!</li>';
t.logoContent += '<li onclick="Metamaps.GlobalUI.openLightbox(\'donate\')">Donate! /&nbsp;</li>';
t.logoContent += '<li onclick="Metamaps.GlobalUI.openLightbox(\'getInvolved\')">Get Involved!</li>';
t.logoContent += '</ul>';