initial code for realtime, got new topic, new synapse, and topic drag working

This commit is contained in:
Connor Turland 2014-09-30 16:55:25 -04:00
parent b1d27d42ff
commit 86e78919b3
3 changed files with 287 additions and 119 deletions

View file

@ -1,6 +1,11 @@
Metamaps.JIT = { Metamaps.JIT = {
events: { events: {
mouseMove: 'Metamaps:JIT:events:mouseMove', mouseMove: 'Metamaps:JIT:events:mouseMove',
topicDrag: 'Metamaps:JIT:events:topicDrag',
newTopic: 'Metamaps:JIT:events:newTopic',
removeTopic: 'Metamaps:JIT:events:removeTopic',
newSynapse: 'Metamaps:JIT:events:newSynapse',
removeSynapse: 'Metamaps:JIT:events:removeSynapse',
pan: 'Metamaps:JIT:events:pan', pan: 'Metamaps:JIT:events:pan',
zoom: 'Metamaps:JIT:events:zoom' zoom: 'Metamaps:JIT:events:zoom'
}, },
@ -703,6 +708,11 @@ Metamaps.JIT = {
var self = Metamaps.JIT; var self = Metamaps.JIT;
// this is used to send nodes that are moving to
// other realtime collaborators on the same map
var positionsToSend = {};
var topic;
if (node && !node.nodeFrom) { if (node && !node.nodeFrom) {
var pos = eventInfo.getPos(); var pos = eventInfo.getPos();
// if it's a left click, or a touch, move the node // if it's a left click, or a touch, move the node
@ -710,13 +720,23 @@ Metamaps.JIT = {
//if the node dragged isn't already selected, select it //if the node dragged isn't already selected, select it
var whatToDo = self.handleSelectionBeforeDragging(node, e); var whatToDo = self.handleSelectionBeforeDragging(node, e);
if (node.pos.rho || node.pos.rho === 0) { if (node.pos.rho || node.pos.rho === 0) {
// this means we're in topic view
var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y); var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
var theta = Math.atan2(pos.y, pos.x); var theta = Math.atan2(pos.y, pos.x);
node.pos.setp(theta, rho); node.pos.setp(theta, rho);
} else if (whatToDo == 'only-drag-this-one') { } else if (whatToDo == 'only-drag-this-one') {
node.pos.setc(pos.x, pos.y); node.pos.setc(pos.x, pos.y);
node.setData('xloc', pos.x);
node.setData('yloc', pos.y); if (Metamaps.Active.Map) {
topic = node.getData('topic');
// we use the topic ID not the node id
// because we can't depend on the node id
// to be the same as on other collaborators
// maps
positionsToSend[topic.id] = pos;
$(document).trigger(Metamaps.JIT.events.topicDrag, [positionsToSend]);
$(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
}
} else { } else {
var len = Metamaps.Selected.Nodes.length; var len = Metamaps.Selected.Nodes.length;
@ -734,9 +754,21 @@ Metamaps.JIT = {
var x = pos.x + xOffset[i]; var x = pos.x + xOffset[i];
var y = pos.y + yOffset[i]; var y = pos.y + yOffset[i];
n.pos.setc(x, y); n.pos.setc(x, y);
n.setData('xloc', x);
n.setData('yloc', y); if (Metamaps.Active.Map) {
topic = n.getData('topic');
// we use the topic ID not the node id
// because we can't depend on the node id
// to be the same as on other collaborators
// maps
positionsToSend[topic.id] = n.pos;
}
} //for } //for
if (Metamaps.Active.Map) {
$(document).trigger(Metamaps.JIT.events.topicDrag, [positionsToSend]);
$(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
}
} //if } //if
if (whatToDo == 'deselect') { if (whatToDo == 'deselect') {
@ -807,6 +839,7 @@ Metamaps.JIT = {
x: pos.x, x: pos.x,
y: pos.y y: pos.y
}; };
$(document).trigger(Metamaps.JIT.events.mouseMove, [pos]);
} }
} }
} }

View file

@ -1506,7 +1506,7 @@ Metamaps.Realtime = {
}); });
$('body').click(self.close); $('body').click(self.close);
self.socket = io.connect('http://gentle-savannah-1303.herokuapp.com'); self.socket = io.connect('http://localhost:5001');
self.startActiveMap(); self.startActiveMap();
}, },
toggleBox: function (event) { toggleBox: function (event) {
@ -1619,14 +1619,30 @@ Metamaps.Realtime = {
// receive word that there's a mapper turned on realtime // receive word that there's a mapper turned on realtime
socket.on('maps-' + Metamaps.Active.Map.id + '-lostrealtime', self.lostCollaborator); socket.on('maps-' + Metamaps.Active.Map.id + '-lostrealtime', self.lostCollaborator);
socket.on('maps-' + Metamaps.Active.Map.id, self.contentUpdate); //
socket.on('maps-' + Metamaps.Active.Map.id + '-topicDrag', self.topicDrag);
//
socket.on('maps-' + Metamaps.Active.Map.id + '-newTopic', self.newTopic);
//
socket.on('maps-' + Metamaps.Active.Map.id + '-removeTopic', self.removeTopic);
//
socket.on('maps-' + Metamaps.Active.Map.id + '-newSynapse', self.newSynapse);
//
socket.on('maps-' + Metamaps.Active.Map.id + '-removeSynapse', self.removeSynapse);
// update mapper compass position // update mapper compass position
socket.on('maps-' + Metamaps.Active.Map.id + '-updatePeerCoords', self.updatePeerCoords); socket.on('maps-' + Metamaps.Active.Map.id + '-updatePeerCoords', self.updatePeerCoords);
// local event listeners that trigger events
var sendCoords = function (event, coords) { var sendCoords = function (event, coords) {
self.sendCoords(coords); self.sendCoords(coords);
}; };
$(document).on(Metamaps.JIT.events.mouseMove, sendCoords);
var zoom = function (event, e) { var zoom = function (event, e) {
if (e) { if (e) {
var pixels = { var pixels = {
@ -1638,9 +1654,35 @@ Metamaps.Realtime = {
} }
self.positionPeerIcons(); self.positionPeerIcons();
}; };
$(document).on(Metamaps.JIT.events.mouseMove, sendCoords);
$(document).on(Metamaps.JIT.events.zoom, zoom); $(document).on(Metamaps.JIT.events.zoom, zoom);
$(document).on(Metamaps.JIT.events.pan, self.positionPeerIcons); $(document).on(Metamaps.JIT.events.pan, self.positionPeerIcons);
var sendTopicDrag = function (event, positions) {
self.sendTopicDrag(positions);
};
$(document).on(Metamaps.JIT.events.topicDrag, sendTopicDrag);
var sendNewTopic = function (event, data) {
self.sendNewTopic(data);
};
$(document).on(Metamaps.JIT.events.newTopic, sendNewTopic);
var sendRemoveTopic = function (event, data) {
self.sendRemoveTopic(data);
};
$(document).on(Metamaps.JIT.events.removeTopic, sendRemoveTopic);
var sendNewSynapse = function (event, data) {
self.sendNewSynapse(data);
};
$(document).on(Metamaps.JIT.events.newSynapse, sendNewSynapse);
var sendRemoveSynapse = function (event, data) {
self.sendRemoveSynapse(data);
};
$(document).on(Metamaps.JIT.events.removeSynapse, sendRemoveSynapse);
}, },
sendRealtimeOn: function () { sendRealtimeOn: function () {
var self = Metamaps.Realtime; var self = Metamaps.Realtime;
@ -1899,120 +1941,150 @@ Metamaps.Realtime = {
socket.emit('updateMapperCoords', update); socket.emit('updateMapperCoords', update);
} }
}, },
contentUpdate: function (data) { sendTopicDrag: function (positions) {
var self = Metamaps.Realtime; var self = Metamaps.Realtime;
var socket = Metamaps.Realtime.socket; var socket = self.socket;
var graph = Metamaps.Visualize.mGraph.graph;
//as long as you weren't the origin of the changes, update your map if (Metamaps.Active.Map && self.status) {
if (data.origin != Metamaps.Active.Mapper.id && self.status) { positions.mapid = Metamaps.Active.Map.id;
if (data.resource == 'Topic') { socket.emit('topicDrag', positions);
topic = $.parseJSON(data.obj);
if (data.action == 'create') {
self.addTopicToMap(topic);
} else if (data.action == 'update' && graph.getNode(topic.id) != 'undefined') {
self.updateTopicOnMap(topic);
} else if (data.action == 'destroy' && graph.getNode(topic.id) != 'undefined') {
Metamaps.Control.hideNode(topic.id)
}
return;
} else if (data.resource == 'Synapse') {
synapse = $.parseJSON(data.obj);
if (data.action == 'create') {
self.addSynapseToMap(synapse);
} else if (data.action == 'update' &&
graph.getAdjacence(synapse.data.$direction['0'], synapse.data.$direction['1']) != 'undefined') {
self.updateSynapseOnMap(synapse);
} else if (data.action == 'destroy' &&
graph.getAdjacence(synapse.data.$direction['0'], synapse.data.$direction['1']) != 'undefined') {
var edge = graph.getAdjacence(synapse.data.$direction['0'], synapse.data.$direction['1']);
Metamaps.Control.hideEdge(edge);
}
return;
}
} }
}, },
addTopicToMap: function (topic) { topicDrag: function (positions) {
var self = Metamaps.Realtime;
var socket = self.socket;
// TODO var topic;
var newPos, tempForT; var node;
Metamaps.Visualize.mGraph.graph.addNode(topic);
tempForT = Metamaps.Visualize.mGraph.graph.getNode(topic.id);
tempForT.setData('dim', 1, 'start');
tempForT.setData('dim', 25, 'end');
newPos = new $jit.Complex();
newPos.x = tempForT.data.$xloc;
newPos.y = tempForT.data.$yloc;
tempForT.setPos(newPos, 'start');
tempForT.setPos(newPos, 'current');
tempForT.setPos(newPos, 'end');
Metamaps.Visualize.mGraph.fx.plotNode(tempForT, Metamaps.Visualize.mGraph.canvas);
},
updateTopicOnMap: function (topic) {
// TODO if (Metamaps.Active.Map && self.status) {
var newPos, tempForT; for (var key in positions) {
tempForT = Metamaps.Visualize.mGraph.graph.getNode(topic.id); topic = Metamaps.Topics.get(key);
tempForT.data = topic.data; if (topic) node = topic.get('node');
tempForT.name = topic.name; if (node) node.pos.setc(positions[key].x, positions[key].y);
if (MetamapsModel.showcardInUse === topic.id) { } //for
populateShowCard(tempForT); Metamaps.Visualize.mGraph.plot();
}
},
// newTopic
sendNewTopic: function (data) {
var self = Metamaps.Realtime;
var socket = self.socket;
if (Metamaps.Active.Map && self.status) {
data.mapid = Metamaps.Active.Map.id;
socket.emit('newTopic', data);
}
},
newTopic: function (data) {
var topic, mapping, cancel;
function test() {
if (topic && mapping) {
Metamaps.Topic.renderTopic(mapping, topic, false, false);
}
else if (!cancel) {
setTimeout(test, 10);
}
}
test();
$.ajax({
url: "/topics/" + data.topicid + ".json",
success: function (response) {
Metamaps.Topics.add(response);
topic = Metamaps.Topics.get(response.id);
},
error: function () {
cancel = true;
}
});
$.ajax({
url: "/mappings/" + data.mappingid + ".json",
success: function (response) {
Metamaps.Mappings.add(response);
mapping = Metamaps.Mappings.get(response.id);
},
error: function () {
cancel = true;
} }
newPos = new $jit.Complex();
newPos.x = tempForT.data.$xloc;
newPos.y = tempForT.data.$yloc;
tempForT.setPos(newPos, 'start');
tempForT.setPos(newPos, 'current');
tempForT.setPos(newPos, 'end');
return Metamaps.Visualize.mGraph.fx.animate({
modes: ['linear', 'node-property:dim', 'edge-property:lineWidth'],
transition: $jit.Trans.Quad.easeInOut,
duration: 500
}); });
}, },
addSynapseToMap: function (synapse) { // removeTopic
sendRemoveTopic: function (data) {
var self = Metamaps.Realtime;
var socket = self.socket;
// TODO if (Metamaps.Active.Map && self.status) {
var Node1, Node2, tempForS; data.mapid = Metamaps.Active.Map.id;
Node1 = Metamaps.Visualize.mGraph.graph.getNode(synapse.data.$direction[0]); socket.emit('removeTopic', data);
Node2 = Metamaps.Visualize.mGraph.graph.getNode(synapse.data.$direction[1]); }
Metamaps.Visualize.mGraph.graph.addAdjacence(Node1, Node2, {}); },
tempForS = Metamaps.Visualize.mGraph.graph.getAdjacence(Node1.id, Node2.id); removeTopic: function (data) {
tempForS.setDataset('start', {
lineWidth: 0.4 },
// newSynapse
sendNewSynapse: function (data) {
var self = Metamaps.Realtime;
var socket = self.socket;
if (Metamaps.Active.Map && self.status) {
data.mapid = Metamaps.Active.Map.id;
socket.emit('newSynapse', data);
}
},
newSynapse: function (data) {
var topic1, topic2, node1, node2, synapse, mapping, cancel;
function test() {
if (synapse && mapping) {
topic1 = synapse.getTopic1();
node1 = topic1.get('node');
topic2 = synapse.getTopic2();
node2 = topic2.get('node');
Metamaps.Synapse.renderSynapse(mapping, synapse, node1, node2, false);
}
else if (!cancel) {
setTimeout(test, 10);
}
}
test();
$.ajax({
url: "/synapses/" + data.synapseid + ".json",
success: function (response) {
Metamaps.Synapses.add(response);
synapse = Metamaps.Synapses.get(response.id);
},
error: function () {
cancel = true;
}
}); });
tempForS.setDataset('end', { $.ajax({
lineWidth: 2 url: "/mappings/" + data.mappingid + ".json",
}); success: function (response) {
tempForS.data = synapse.data; Metamaps.Mappings.add(response);
Metamaps.Visualize.mGraph.fx.plotLine(tempForS, Metamaps.Visualize.mGraph.canvas); mapping = Metamaps.Mappings.get(response.id);
return Metamaps.Visualize.mGraph.fx.animate({ },
modes: ['linear', 'node-property:dim', 'edge-property:lineWidth'], error: function () {
transition: $jit.Trans.Quad.easeInOut, cancel = true;
duration: 500 }
}); });
}, },
updateSynapseOnMap: function (synapse) { // removeSynapse
sendRemoveSynapse: function (data) {
var self = Metamaps.Realtime;
var socket = self.socket;
// TODO if (Metamaps.Active.Map && self.status) {
var k, tempForS, v, wasShowDesc, _ref; data.mapid = Metamaps.Active.Map.id;
tempForS = Metamaps.Visualize.mGraph.graph.getAdjacence(synapse.data.$direction[0], synapse.data.$direction[1]); socket.emit('removeSynapse', data);
wasShowDesc = tempForS.data.$showDesc;
_ref = synapse.data;
for (k in _ref) {
v = _ref[k];
tempForS.data[k] = v;
}
tempForS.data.$showDesc = wasShowDesc;
if (MetamapsModel.edgecardInUse === synapse.data.$id) { // TODO
editEdge(tempForS, false);
}
return Metamaps.Visualize.mGraph.plot();
} }
},
removeSynapse: function (data) {
},
}; // end Metamaps.Realtime }; // end Metamaps.Realtime
@ -2902,7 +2974,7 @@ Metamaps.Topic = {
* *
* *
*/ */
renderTopic: function (mapping, topic, createNewInDB) { renderTopic: function (mapping, topic, createNewInDB, permitCreateSynapseAfter) {
var self = Metamaps.Topic; var self = Metamaps.Topic;
var nodeOnViz, tempPos; var nodeOnViz, tempPos;
@ -2935,7 +3007,7 @@ Metamaps.Topic = {
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), "start"); nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), "start");
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), "end"); nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), "end");
} }
if (Metamaps.Create.newTopic.addSynapse) { if (Metamaps.Create.newTopic.addSynapse && permitCreateSynapseAfter) {
Metamaps.Create.newSynapse.topic1id = tempNode.getData('topic').id; Metamaps.Create.newSynapse.topic1id = tempNode.getData('topic').id;
// position the form // position the form
@ -2986,10 +3058,22 @@ Metamaps.Topic = {
}); });
} }
var mappingSuccessCallback = function (mappingModel, response) {
var newTopicData = {
mappingid: mappingModel.id,
topicid: mappingModel.get('topic_id')
};
var successCallback = function (topicModel, response) { $(document).trigger(Metamaps.JIT.events.newTopic, [newTopicData]);
};
var topicSuccessCallback = function (topicModel, response) {
if (Metamaps.Active.Map) { if (Metamaps.Active.Map) {
mapping.save({ topic_id: topicModel.id }); mapping.save({ topic_id: topicModel.id }, {
success: mappingSuccessCallback,
error: function (model, response) {
console.log('error saving mapping to database');
}
});
} }
if (Metamaps.Create.newTopic.addSynapse) { if (Metamaps.Create.newTopic.addSynapse) {
@ -3000,13 +3084,15 @@ Metamaps.Topic = {
if (!Metamaps.Settings.sandbox && createNewInDB) { if (!Metamaps.Settings.sandbox && createNewInDB) {
if (topic.isNew()) { if (topic.isNew()) {
topic.save(null, { topic.save(null, {
success: successCallback, success: topicSuccessCallback,
error: function (model, response) { error: function (model, response) {
console.log('error saving topic to database'); console.log('error saving topic to database');
} }
}); });
} else if (!topic.isNew() && Metamaps.Active.Map) { } else if (!topic.isNew() && Metamaps.Active.Map) {
mapping.save(); mapping.save(null, {
success: mappingSuccessCallback
});
} }
} }
}, },
@ -3034,7 +3120,7 @@ Metamaps.Topic = {
//these can't happen until the value is retrieved, which happens in the line above //these can't happen until the value is retrieved, which happens in the line above
Metamaps.Create.newTopic.hide(); Metamaps.Create.newTopic.hide();
self.renderTopic(mapping, topic, true); // this function also includes the creation of the topic in the database self.renderTopic(mapping, topic, true, true); // this function also includes the creation of the topic in the database
}, },
getTopicFromAutocomplete: function (id) { getTopicFromAutocomplete: function (id) {
var self = Metamaps.Topic; var self = Metamaps.Topic;
@ -3051,7 +3137,7 @@ Metamaps.Topic = {
}); });
Metamaps.Mappings.add(mapping); Metamaps.Mappings.add(mapping);
self.renderTopic(mapping, topic, true); self.renderTopic(mapping, topic, true, true);
} }
}; // end Metamaps.Topic }; // end Metamaps.Topic
@ -3110,20 +3196,34 @@ Metamaps.Synapse = {
Metamaps.Visualize.mGraph.fx.plotLine(edgeOnViz, Metamaps.Visualize.mGraph.canvas); Metamaps.Visualize.mGraph.fx.plotLine(edgeOnViz, Metamaps.Visualize.mGraph.canvas);
Metamaps.Control.selectEdge(edgeOnViz); Metamaps.Control.selectEdge(edgeOnViz);
var mappingSuccessCallback = function (mappingModel, response) {
var newSynapseData = {
mappingid: mappingModel.id,
synapseid: mappingModel.get('synapse_id')
};
$(document).trigger(Metamaps.JIT.events.newSynapse, [newSynapseData]);
};
var synapseSuccessCallback = function (synapseModel, response) {
if (Metamaps.Active.Map) {
mapping.save({ synapse_id: synapseModel.id }, {
success: mappingSuccessCallback
});
}
};
if (!Metamaps.Settings.sandbox && createNewInDB) { if (!Metamaps.Settings.sandbox && createNewInDB) {
if (synapse.isNew()) { if (synapse.isNew()) {
synapse.save(null, { synapse.save(null, {
success: function (synapseModel, response) { success: synapseSuccessCallback,
if (Metamaps.Active.Map) {
mapping.save({ synapse_id: synapseModel.id });
}
},
error: function (model, response) { error: function (model, response) {
console.log('error saving synapse to database'); console.log('error saving synapse to database');
} }
}); });
} else if (!synapse.isNew() && Metamaps.Active.Map) { } else if (!synapse.isNew() && Metamaps.Active.Map) {
mapping.save(); mapping.save(null, {
success: mappingSuccessCallback
});
} }
} }
}, },

View file

@ -113,6 +113,41 @@ function start() {
socket.broadcast.emit('maps-' + data.mapid + '-updatePeerCoords', peer); socket.broadcast.emit('maps-' + data.mapid + '-updatePeerCoords', peer);
}); });
socket.on('topicDrag', function (data) {
var mapId = data.mapid;
delete data.mapid;
socket.broadcast.emit('maps-' + mapId + '-topicDrag', data);
});
socket.on('newTopic', function (data) {
var mapId = data.mapid;
delete data.mapid;
socket.broadcast.emit('maps-' + mapId + '-newTopic', data);
});
socket.on('removeTopic', function (data) {
var mapId = data.mapid;
delete data.mapid;
socket.broadcast.emit('maps-' + mapId + '-removeTopic', data);
});
socket.on('newSynapse', function (data) {
var mapId = data.mapid;
delete data.mapid;
socket.broadcast.emit('maps-' + mapId + '-newSynapse', data);
});
socket.on('removeSynapse', function (data) {
var mapId = data.mapid;
delete data.mapid;
socket.broadcast.emit('maps-' + mapId + '-removeSynapse', data);
});
}); });
} }