Merge pull request #548 from metamaps/feature/refactor-javascript

split out all javascript files
This commit is contained in:
Devin Howard 2016-04-20 11:24:20 +08:00
commit e569a0376d
18 changed files with 4307 additions and 4298 deletions

View file

@ -25,6 +25,15 @@
//= require ./src/views/room
//= require ./src/JIT
//= require ./src/Metamaps
//= require ./src/Metamaps.Control
//= require ./src/Metamaps.Filter
//= require ./src/Metamaps.Listeners
//= require ./src/Metamaps.Organize
//= require ./src/Metamaps.Topic
//= require ./src/Metamaps.Synapse
//= require ./src/Metamaps.Map
//= require ./src/Metamaps.Account
//= require ./src/Metamaps.Mapper
//= require ./src/Metamaps.Admin
//= require ./src/Metamaps.Import
//= require ./src/Metamaps.JIT

View file

@ -0,0 +1,121 @@
/* global Metamaps, $ */
/*
* Metamaps.Account.js.erb
*
* Dependencies: none!
*/
Metamaps.Account = {
listenersInitialized: false,
init: function () {
var self = Metamaps.Account
},
initListeners: function () {
var self = Metamaps.Account
$('#user_image').change(self.showImagePreview)
self.listenersInitialized = true
},
toggleChangePicture: function () {
var self = Metamaps.Account
$('.userImageMenu').toggle()
if (!self.listenersInitialized) self.initListeners()
},
openChangePicture: function () {
var self = Metamaps.Account
$('.userImageMenu').show()
if (!self.listenersInitialized) self.initListeners()
},
closeChangePicture: function () {
var self = Metamaps.Account
$('.userImageMenu').hide()
},
showLoading: function () {
var self = Metamaps.Account
var loader = new CanvasLoader('accountPageLoading')
loader.setColor('#4FC059'); // default is '#000000'
loader.setDiameter(28) // default is 40
loader.setDensity(41) // default is 40
loader.setRange(0.9); // default is 1.3
loader.show() // Hidden by default
$('#accountPageLoading').show()
},
showImagePreview: function () {
var self = Metamaps.Account
var file = $('#user_image')[0].files[0]
var reader = new FileReader()
reader.onload = function (e) {
var $canvas = $('<canvas>').attr({
width: 84,
height: 84
})
var context = $canvas[0].getContext('2d')
var imageObj = new Image()
imageObj.onload = function () {
$('.userImageDiv canvas').remove()
$('.userImageDiv img').hide()
var imgWidth = imageObj.width
var imgHeight = imageObj.height
var dimensionToMatch = imgWidth > imgHeight ? imgHeight : imgWidth
// draw cropped image
var nonZero = Math.abs(imgHeight - imgWidth) / 2
var sourceX = dimensionToMatch === imgWidth ? 0 : nonZero
var sourceY = dimensionToMatch === imgHeight ? 0 : nonZero
var sourceWidth = dimensionToMatch
var sourceHeight = dimensionToMatch
var destX = 0
var destY = 0
var destWidth = 84
var destHeight = 84
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight)
$('.userImageDiv').prepend($canvas)
}
imageObj.src = reader.result
}
if (file) {
reader.readAsDataURL(file)
$('.userImageMenu').hide()
$('#remove_image').val('0')
}
},
removePicture: function () {
var self = Metamaps.Account
$('.userImageDiv canvas').remove()
$('.userImageDiv img').attr('src', '<%= asset_path('user.png') %>').show()
$('.userImageMenu').hide()
var input = $('#user_image')
input.replaceWith(input.val('').clone(true))
$('#remove_image').val('1')
},
changeName: function () {
$('.accountName').hide()
$('.changeName').show()
},
showPass: function () {
$('.toHide').show()
$('.changePass').hide()
},
hidePass: function () {
$('.toHide').hide()
$('.changePass').show()
$('#current_password').val('')
$('#user_password').val('')
$('#user_password_confirmation').val('')
}
}

View file

@ -0,0 +1,437 @@
/* global Metamaps, $ */
/*
* Metamaps.Control.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Control
* - Metamaps.Filter
* - Metamaps.GlobalUI
* - Metamaps.JIT
* - Metamaps.Mappings
* - Metamaps.Metacodes
* - Metamaps.Mouse
* - Metamaps.Selected
* - Metamaps.Settings
* - Metamaps.Synapses
* - Metamaps.Topics
* - Metamaps.Visualize
*/
Metamaps.Control = {
init: function () {},
selectNode: function (node, e) {
var filtered = node.getData('alpha') === 0
if (filtered || Metamaps.Selected.Nodes.indexOf(node) != -1) return
node.selected = true
node.setData('dim', 30, 'current')
Metamaps.Selected.Nodes.push(node)
},
deselectAllNodes: function () {
var l = Metamaps.Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
var node = Metamaps.Selected.Nodes[i]
Metamaps.Control.deselectNode(node)
}
Metamaps.Visualize.mGraph.plot()
},
deselectNode: function (node) {
delete node.selected
node.setData('dim', 25, 'current')
// remove the node
Metamaps.Selected.Nodes.splice(
Metamaps.Selected.Nodes.indexOf(node), 1)
},
deleteSelected: function () {
if (!Metamaps.Active.Map) return
var n = Metamaps.Selected.Nodes.length
var e = Metamaps.Selected.Edges.length
var ntext = n == 1 ? '1 topic' : n + ' topics'
var etext = e == 1 ? '1 synapse' : e + ' synapses'
var text = 'You have ' + ntext + ' and ' + etext + ' selected. '
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
var r = confirm(text + 'Are you sure you want to permanently delete them all? This will remove them from all maps they appear on.')
if (r == true) {
Metamaps.Control.deleteSelectedEdges()
Metamaps.Control.deleteSelectedNodes()
}
},
deleteSelectedNodes: function () { // refers to deleting topics permanently
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
var l = Metamaps.Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
var node = Metamaps.Selected.Nodes[i]
Metamaps.Control.deleteNode(node.id)
}
},
deleteNode: function (nodeid) { // refers to deleting topics permanently
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid)
var topic = node.getData('topic')
var permToDelete = Metamaps.Active.Mapper.id === topic.get('user_id') || Metamaps.Active.Mapper.get('admin')
if (permToDelete) {
var mappableid = topic.id
var mapping = node.getData('mapping')
topic.destroy()
Metamaps.Mappings.remove(mapping)
$(document).trigger(Metamaps.JIT.events.deleteTopic, [{
mappableid: mappableid
}])
Metamaps.Control.hideNode(nodeid)
} else {
Metamaps.GlobalUI.notifyUser('Only topics you created can be deleted')
}
},
removeSelectedNodes: function () { // refers to removing topics permanently from a map
if (!Metamaps.Active.Map) return
var l = Metamaps.Selected.Nodes.length,
i,
node,
authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
for (i = l - 1; i >= 0; i -= 1) {
node = Metamaps.Selected.Nodes[i]
Metamaps.Control.removeNode(node.id)
}
},
removeNode: function (nodeid) { // refers to removing topics permanently from a map
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
var topic = node.getData('topic')
var mappableid = topic.id
var mapping = node.getData('mapping')
mapping.destroy()
Metamaps.Topics.remove(topic)
$(document).trigger(Metamaps.JIT.events.removeTopic, [{
mappableid: mappableid
}])
Metamaps.Control.hideNode(nodeid)
},
hideSelectedNodes: function () {
var l = Metamaps.Selected.Nodes.length,
i,
node
for (i = l - 1; i >= 0; i -= 1) {
node = Metamaps.Selected.Nodes[i]
Metamaps.Control.hideNode(node.id)
}
},
hideNode: function (nodeid) {
var node = Metamaps.Visualize.mGraph.graph.getNode(nodeid)
var graph = Metamaps.Visualize.mGraph
Metamaps.Control.deselectNode(node)
node.setData('alpha', 0, 'end')
node.eachAdjacency(function (adj) {
adj.setData('alpha', 0, 'end')
})
Metamaps.Visualize.mGraph.fx.animate({
modes: ['node-property:alpha',
'edge-property:alpha'
],
duration: 500
})
setTimeout(function () {
if (nodeid == Metamaps.Visualize.mGraph.root) { // && Metamaps.Visualize.type === "RGraph"
var newroot = _.find(graph.graph.nodes, function (n) { return n.id !== nodeid; })
graph.root = newroot ? newroot.id : null
}
Metamaps.Visualize.mGraph.graph.removeNode(nodeid)
}, 500)
Metamaps.Filter.checkMetacodes()
Metamaps.Filter.checkMappers()
},
selectEdge: function (edge) {
var filtered = edge.getData('alpha') === 0; // don't select if the edge is filtered
if (filtered || Metamaps.Selected.Edges.indexOf(edge) != -1) return
var width = Metamaps.Mouse.edgeHoveringOver === edge ? 4 : 2
edge.setDataset('current', {
showDesc: true,
lineWidth: width,
color: Metamaps.Settings.colors.synapses.selected
})
Metamaps.Visualize.mGraph.plot()
Metamaps.Selected.Edges.push(edge)
},
deselectAllEdges: function () {
var l = Metamaps.Selected.Edges.length
for (var i = l - 1; i >= 0; i -= 1) {
var edge = Metamaps.Selected.Edges[i]
Metamaps.Control.deselectEdge(edge)
}
Metamaps.Visualize.mGraph.plot()
},
deselectEdge: function (edge) {
edge.setData('showDesc', false, 'current')
edge.setDataset('current', {
lineWidth: 2,
color: Metamaps.Settings.colors.synapses.normal
})
if (Metamaps.Mouse.edgeHoveringOver == edge) {
edge.setDataset('current', {
showDesc: true,
lineWidth: 4
})
}
Metamaps.Visualize.mGraph.plot()
// remove the edge
Metamaps.Selected.Edges.splice(
Metamaps.Selected.Edges.indexOf(edge), 1)
},
deleteSelectedEdges: function () { // refers to deleting topics permanently
var edge,
l = Metamaps.Selected.Edges.length
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
for (var i = l - 1; i >= 0; i -= 1) {
edge = Metamaps.Selected.Edges[i]
Metamaps.Control.deleteEdge(edge)
}
},
deleteEdge: function (edge) {
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
var synapse = edge.getData('synapses')[index]
var mapping = edge.getData('mappings')[index]
var permToDelete = Metamaps.Active.Mapper.id === synapse.get('user_id') || Metamaps.Active.Mapper.get('admin')
if (permToDelete) {
if (edge.getData('synapses').length - 1 === 0) {
Metamaps.Control.hideEdge(edge)
}
var mappableid = synapse.id
synapse.destroy()
// the server will destroy the mapping, we just need to remove it here
Metamaps.Mappings.remove(mapping)
edge.getData('mappings').splice(index, 1)
edge.getData('synapses').splice(index, 1)
if (edge.getData('displayIndex')) {
delete edge.data.$displayIndex
}
$(document).trigger(Metamaps.JIT.events.deleteSynapse, [{
mappableid: mappableid
}])
} else {
Metamaps.GlobalUI.notifyUser('Only synapses you created can be deleted')
}
},
removeSelectedEdges: function () {
var l = Metamaps.Selected.Edges.length,
i,
edge
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
for (i = l - 1; i >= 0; i -= 1) {
edge = Metamaps.Selected.Edges[i]
Metamaps.Control.removeEdge(edge)
}
Metamaps.Selected.Edges = [ ]
},
removeEdge: function (edge) {
if (!Metamaps.Active.Map) return
var authorized = Metamaps.Active.Map.authorizeToEdit(Metamaps.Active.Mapper)
if (!authorized) {
Metamaps.GlobalUI.notifyUser('Cannot edit Public map.')
return
}
if (edge.getData('mappings').length - 1 === 0) {
Metamaps.Control.hideEdge(edge)
}
var index = edge.getData('displayIndex') ? edge.getData('displayIndex') : 0
var synapse = edge.getData('synapses')[index]
var mapping = edge.getData('mappings')[index]
var mappableid = synapse.id
mapping.destroy()
Metamaps.Synapses.remove(synapse)
edge.getData('mappings').splice(index, 1)
edge.getData('synapses').splice(index, 1)
if (edge.getData('displayIndex')) {
delete edge.data.$displayIndex
}
$(document).trigger(Metamaps.JIT.events.removeSynapse, [{
mappableid: mappableid
}])
},
hideSelectedEdges: function () {
var edge,
l = Metamaps.Selected.Edges.length,
i
for (i = l - 1; i >= 0; i -= 1) {
edge = Metamaps.Selected.Edges[i]
Metamaps.Control.hideEdge(edge)
}
Metamaps.Selected.Edges = [ ]
},
hideEdge: function (edge) {
var from = edge.nodeFrom.id
var to = edge.nodeTo.id
edge.setData('alpha', 0, 'end')
Metamaps.Control.deselectEdge(edge)
Metamaps.Visualize.mGraph.fx.animate({
modes: ['edge-property:alpha'],
duration: 500
})
setTimeout(function () {
Metamaps.Visualize.mGraph.graph.removeAdjacence(from, to)
}, 500)
Metamaps.Filter.checkSynapses()
Metamaps.Filter.checkMappers()
},
updateSelectedPermissions: function (permission) {
var edge, synapse, node, topic
Metamaps.GlobalUI.notifyUser('Working...')
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
var nCount = 0,
sCount = 0
// change the permission of the selected synapses, if logged in user is the original creator
var l = Metamaps.Selected.Edges.length
for (var i = l - 1; i >= 0; i -= 1) {
edge = Metamaps.Selected.Edges[i]
synapse = edge.getData('synapses')[0]
if (synapse.authorizePermissionChange(Metamaps.Active.Mapper)) {
synapse.save({
permission: permission
})
sCount++
}
}
// change the permission of the selected topics, if logged in user is the original creator
var l = Metamaps.Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
node = Metamaps.Selected.Nodes[i]
topic = node.getData('topic')
if (topic.authorizePermissionChange(Metamaps.Active.Mapper)) {
topic.save({
permission: permission
})
nCount++
}
}
var nString = nCount == 1 ? (nCount.toString() + ' topic and ') : (nCount.toString() + ' topics and ')
var sString = sCount == 1 ? (sCount.toString() + ' synapse') : (sCount.toString() + ' synapses')
var message = nString + sString + ' you created updated to ' + permission
Metamaps.GlobalUI.notifyUser(message)
},
updateSelectedMetacodes: function (metacode_id) {
var node, topic
Metamaps.GlobalUI.notifyUser('Working...')
var metacode = Metamaps.Metacodes.get(metacode_id)
// variables to keep track of how many nodes and synapses you had the ability to change the permission of
var nCount = 0
// change the permission of the selected topics, if logged in user is the original creator
var l = Metamaps.Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
node = Metamaps.Selected.Nodes[i]
topic = node.getData('topic')
if (topic.authorizeToEdit(Metamaps.Active.Mapper)) {
topic.save({
'metacode_id': metacode_id
})
nCount++
}
}
var nString = nCount == 1 ? (nCount.toString() + ' topic') : (nCount.toString() + ' topics')
var message = nString + ' you can edit updated to ' + metacode.get('name')
Metamaps.GlobalUI.notifyUser(message)
Metamaps.Visualize.mGraph.plot()
},
}; // end Metamaps.Control

View file

@ -4,10 +4,10 @@
* Dependencies: none!
*/
Metamaps.Debug = function() {
Metamaps.Debug = function () {
console.debug(Metamaps)
console.debug(`Metamaps Version: ${Metamaps.VERSION}`)
}
Metamaps.debug = function() {
Metamaps.debug = function () {
Metamaps.Debug()
}

View file

@ -0,0 +1,466 @@
/* global Metamaps, $ */
/*
* Metamaps.Filter.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Control
* - Metamaps.Creators
* - Metamaps.GlobalUI
* - Metamaps.Mappers
* - Metamaps.Metacodes
* - Metamaps.Settings
* - Metamaps.Synapses
* - Metamaps.Topics
* - Metamaps.Visualize
*/
Metamaps.Filter = {
filters: {
name: '',
metacodes: [],
mappers: [],
synapses: []
},
visible: {
metacodes: [],
mappers: [],
synapses: []
},
isOpen: false,
changing: false,
init: function () {
var self = Metamaps.Filter
$('.sidebarFilterIcon').click(self.toggleBox)
$('.sidebarFilterBox .showAllMetacodes').click(self.filterNoMetacodes)
$('.sidebarFilterBox .showAllSynapses').click(self.filterNoSynapses)
$('.sidebarFilterBox .showAllMappers').click(self.filterNoMappers)
$('.sidebarFilterBox .hideAllMetacodes').click(self.filterAllMetacodes)
$('.sidebarFilterBox .hideAllSynapses').click(self.filterAllSynapses)
$('.sidebarFilterBox .hideAllMappers').click(self.filterAllMappers)
self.bindLiClicks()
self.getFilterData()
},
toggleBox: function (event) {
var self = Metamaps.Filter
if (self.isOpen) self.close()
else self.open()
event.stopPropagation()
},
open: function () {
var self = Metamaps.Filter
Metamaps.GlobalUI.Account.close()
$('.sidebarFilterIcon div').addClass('hide')
if (!self.isOpen && !self.changing) {
self.changing = true
var height = $(document).height() - 108
$('.sidebarFilterBox').css('max-height', height + 'px').fadeIn(200, function () {
self.changing = false
self.isOpen = true
})
}
},
close: function () {
var self = Metamaps.Filter
$('.sidebarFilterIcon div').removeClass('hide')
if (!self.changing) {
self.changing = true
$('.sidebarFilterBox').fadeOut(200, function () {
self.changing = false
self.isOpen = false
})
}
},
reset: function () {
var self = Metamaps.Filter
self.filters.metacodes = []
self.filters.mappers = []
self.filters.synapses = []
self.visible.metacodes = []
self.visible.mappers = []
self.visible.synapses = []
$('#filter_by_metacode ul').empty()
$('#filter_by_mapper ul').empty()
$('#filter_by_synapse ul').empty()
$('.filterBox .showAll').addClass('active')
},
/*
Most of this data essentially depends on the ruby function which are happening for filter inside view filterBox
But what these function do is load this data into three accessible array within java : metacodes, mappers and synapses
*/
getFilterData: function () {
var self = Metamaps.Filter
var metacode, mapper, synapse
$('#filter_by_metacode li').each(function () {
metacode = $(this).attr('data-id')
self.filters.metacodes.push(metacode)
self.visible.metacodes.push(metacode)
})
$('#filter_by_mapper li').each(function () {
mapper = ($(this).attr('data-id'))
self.filters.mappers.push(mapper)
self.visible.mappers.push(mapper)
})
$('#filter_by_synapse li').each(function () {
synapse = ($(this).attr('data-id'))
self.filters.synapses.push(synapse)
self.visible.synapses.push(synapse)
})
},
bindLiClicks: function () {
var self = Metamaps.Filter
$('#filter_by_metacode ul li').unbind().click(self.toggleMetacode)
$('#filter_by_mapper ul li').unbind().click(self.toggleMapper)
$('#filter_by_synapse ul li').unbind().click(self.toggleSynapse)
},
// an abstraction function for checkMetacodes, checkMappers, checkSynapses to reduce
// code redundancy
/*
@param
*/
updateFilters: function (collection, propertyToCheck, correlatedModel, filtersToUse, listToModify) {
var self = Metamaps.Filter
var newList = []
var removed = []
var added = []
// 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)
if (prop !== null) {
prop = prop.toString()
if (newList.indexOf(prop) === -1) {
newList.push(prop)
}
}
})
Metamaps[collection[1]].each(function (model) {
var prop = model.get(propertyToCheck)
if (prop !== null) {
prop = prop.toString()
if (newList.indexOf(prop) === -1) {
newList.push(prop)
}
}
})
} else if (typeof collection === 'string') {
Metamaps[collection].each(function (model) {
var prop = model.get(propertyToCheck)
if (prop !== null) {
prop = prop.toString()
if (newList.indexOf(prop) === -1) {
newList.push(prop)
}
}
})
}
removed = _.difference(self.filters[filtersToUse], newList)
added = _.difference(newList, self.filters[filtersToUse])
// remove the list items for things no longer present on the map
_.each(removed, function (identifier) {
$('#filter_by_' + listToModify + ' li[data-id="' + identifier + '"]').fadeOut('fast', function () {
$(this).remove()
})
index = self.visible[filtersToUse].indexOf(identifier)
self.visible[filtersToUse].splice(index, 1)
})
var model, li, jQueryLi
function sortAlpha (a, b) {
return a.childNodes[1].innerHTML.toLowerCase() > b.childNodes[1].innerHTML.toLowerCase() ? 1 : -1
}
// for each new filter to be added, create a list item for it and fade it in
_.each(added, function (identifier) {
model = Metamaps[correlatedModel].get(identifier) ||
Metamaps[correlatedModel].find(function (model) {
return model.get(propertyToCheck) === identifier
})
li = model.prepareLiForFilter()
jQueryLi = $(li).hide()
$('li', '#filter_by_' + listToModify + ' ul').add(jQueryLi.fadeIn('fast'))
.sort(sortAlpha).appendTo('#filter_by_' + listToModify + ' ul')
self.visible[filtersToUse].push(identifier)
})
// update the list of filters with the new list we just generated
self.filters[filtersToUse] = newList
// make sure clicks on list items still trigger the right events
self.bindLiClicks()
},
checkMetacodes: function () {
var self = Metamaps.Filter
self.updateFilters('Topics', 'metacode_id', 'Metacodes', 'metacodes', 'metacode')
},
checkMappers: function () {
var self = Metamaps.Filter
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
self.updateFilters('Synapses', 'desc', 'Synapses', 'synapses', 'synapse')
},
filterAllMetacodes: function (e) {
var self = Metamaps.Filter
$('#filter_by_metacode ul li').addClass('toggledOff')
$('.showAllMetacodes').removeClass('active')
$('.hideAllMetacodes').addClass('active')
self.visible.metacodes = []
self.passFilters()
},
filterNoMetacodes: function (e) {
var self = Metamaps.Filter
$('#filter_by_metacode ul li').removeClass('toggledOff')
$('.showAllMetacodes').addClass('active')
$('.hideAllMetacodes').removeClass('active')
self.visible.metacodes = self.filters.metacodes.slice()
self.passFilters()
},
filterAllMappers: function (e) {
var self = Metamaps.Filter
$('#filter_by_mapper ul li').addClass('toggledOff')
$('.showAllMappers').removeClass('active')
$('.hideAllMappers').addClass('active')
self.visible.mappers = []
self.passFilters()
},
filterNoMappers: function (e) {
var self = Metamaps.Filter
$('#filter_by_mapper ul li').removeClass('toggledOff')
$('.showAllMappers').addClass('active')
$('.hideAllMappers').removeClass('active')
self.visible.mappers = self.filters.mappers.slice()
self.passFilters()
},
filterAllSynapses: function (e) {
var self = Metamaps.Filter
$('#filter_by_synapse ul li').addClass('toggledOff')
$('.showAllSynapses').removeClass('active')
$('.hideAllSynapses').addClass('active')
self.visible.synapses = []
self.passFilters()
},
filterNoSynapses: function (e) {
var self = Metamaps.Filter
$('#filter_by_synapse ul li').removeClass('toggledOff')
$('.showAllSynapses').addClass('active')
$('.hideAllSynapses').removeClass('active')
self.visible.synapses = self.filters.synapses.slice()
self.passFilters()
},
// an abstraction function for toggleMetacode, toggleMapper, toggleSynapse
// to reduce code redundancy
// gets called in the context of a list item in a filter box
toggleLi: function (whichToFilter) {
var self = Metamaps.Filter, index
var id = $(this).attr('data-id')
if (self.visible[whichToFilter].indexOf(id) == -1) {
self.visible[whichToFilter].push(id)
$(this).removeClass('toggledOff')
} else {
index = self.visible[whichToFilter].indexOf(id)
self.visible[whichToFilter].splice(index, 1)
$(this).addClass('toggledOff')
}
self.passFilters()
},
toggleMetacode: function () {
var self = Metamaps.Filter
self.toggleLi.call(this, 'metacodes')
if (self.visible.metacodes.length === self.filters.metacodes.length) {
$('.showAllMetacodes').addClass('active')
$('.hideAllMetacodes').removeClass('active')
}
else if (self.visible.metacodes.length === 0) {
$('.showAllMetacodes').removeClass('active')
$('.hideAllMetacodes').addClass('active')
} else {
$('.showAllMetacodes').removeClass('active')
$('.hideAllMetacodes').removeClass('active')
}
},
toggleMapper: function () {
var self = Metamaps.Filter
self.toggleLi.call(this, 'mappers')
if (self.visible.mappers.length === self.filters.mappers.length) {
$('.showAllMappers').addClass('active')
$('.hideAllMappers').removeClass('active')
}
else if (self.visible.mappers.length === 0) {
$('.showAllMappers').removeClass('active')
$('.hideAllMappers').addClass('active')
} else {
$('.showAllMappers').removeClass('active')
$('.hideAllMappers').removeClass('active')
}
},
toggleSynapse: function () {
var self = Metamaps.Filter
self.toggleLi.call(this, 'synapses')
if (self.visible.synapses.length === self.filters.synapses.length) {
$('.showAllSynapses').addClass('active')
$('.hideAllSynapses').removeClass('active')
}
else if (self.visible.synapses.length === 0) {
$('.showAllSynapses').removeClass('active')
$('.hideAllSynapses').addClass('active')
} else {
$('.showAllSynapses').removeClass('active')
$('.hideAllSynapses').removeClass('active')
}
},
passFilters: function () {
var self = Metamaps.Filter
var visible = self.visible
var passesMetacode, passesMapper, passesSynapse
var onMap
if (Metamaps.Active.Map) {
onMap = true
}
else if (Metamaps.Active.Topic) {
onMap = false
}
var opacityForFilter = onMap ? 0 : 0.4
Metamaps.Topics.each(function (topic) {
var n = topic.get('node')
var metacode_id = topic.get('metacode_id').toString()
if (visible.metacodes.indexOf(metacode_id) == -1) passesMetacode = false
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) {
n.setData('alpha', 1, 'end')
}
else console.log(topic)
} else {
if (n) {
Metamaps.Control.deselectNode(n, true)
n.setData('alpha', opacityForFilter, 'end')
n.eachAdjacency(function (e) {
Metamaps.Control.deselectEdge(e, true)
})
}
else console.log(topic)
}
})
// flag all the edges back to 'untouched'
Metamaps.Synapses.each(function (synapse) {
var e = synapse.get('edge')
e.setData('touched', false)
})
Metamaps.Synapses.each(function (synapse) {
var e = synapse.get('edge')
var desc
var user_id = synapse.get('user_id').toString()
if (e && !e.getData('touched')) {
var synapses = e.getData('synapses')
// if any of the synapses represent by the edge are still unfiltered
// leave the edge visible
passesSynapse = false
for (var i = 0; i < synapses.length; i++) {
desc = synapses[i].get('desc')
if (visible.synapses.indexOf(desc) > -1) passesSynapse = true
}
// if the synapse description being displayed is now being
// filtered, set the displayIndex to the first unfiltered synapse if there is one
var displayIndex = e.getData('displayIndex') ? e.getData('displayIndex') : 0
var displayedSynapse = synapses[displayIndex]
desc = displayedSynapse.get('desc')
if (passesSynapse && visible.synapses.indexOf(desc) == -1) {
// iterate and find an unfiltered one
for (var i = 0; i < synapses.length; i++) {
desc = synapses[i].get('desc')
if (visible.synapses.indexOf(desc) > -1) {
e.setData('displayIndex', i)
break
}
}
}
if (onMap) {
// 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) {
e.setData('alpha', 1, 'end')
e.setData('color', color, 'end')
} else {
Metamaps.Control.deselectEdge(e, true)
e.setData('alpha', opacityForFilter, 'end')
}
e.setData('touched', true)
}
else if (!e) console.log(synapse)
})
// run the animation
Metamaps.Visualize.mGraph.fx.animate({
modes: ['node-property:alpha',
'edge-property:alpha'],
duration: 200
})
}
}; // end Metamaps.Filter

View file

@ -229,7 +229,7 @@ Metamaps.Import = {
importSynapses: function (parsedSynapses) {
var self = Metamaps.Import
parsedSynapses.forEach(function(synapse) {
parsedSynapses.forEach(function (synapse) {
// only createSynapseWithParameters once both topics are persisted
var topic1 = Metamaps.Topics.get(self.cidMappings[synapse.topic1])
var topic2 = Metamaps.Topics.get(self.cidMappings[synapse.topic2])

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
/* global Metamaps, $ */
/*
* Metamaps.Listeners.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Control
* - Metamaps.JIT
* - Metamaps.Visualize
*/
Metamaps.Listeners = {
init: function () {
$(document).on('keydown', function (e) {
if (!(Metamaps.Active.Map || Metamaps.Active.Topic)) return
switch (e.which) {
case 13: // if enter key is pressed
Metamaps.JIT.enterKeyHandler()
e.preventDefault()
break
case 27: // if esc key is pressed
Metamaps.JIT.escKeyHandler()
break
case 65: // if a or A is pressed
if (e.ctrlKey) {
Metamaps.Control.deselectAllNodes()
Metamaps.Control.deselectAllEdges()
e.preventDefault()
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
Metamaps.Control.selectNode(n, e)
})
Metamaps.Visualize.mGraph.plot()
}
break
case 69: // if e or E is pressed
if (e.ctrlKey) {
e.preventDefault()
if (Metamaps.Active.Map) {
Metamaps.JIT.zoomExtents(null, Metamaps.Visualize.mGraph.canvas)
}
}
break
case 77: // if m or M is pressed
if (e.ctrlKey) {
e.preventDefault()
Metamaps.Control.removeSelectedNodes()
Metamaps.Control.removeSelectedEdges()
}
break
case 68: // if d or D is pressed
if (e.ctrlKey) {
e.preventDefault()
Metamaps.Control.deleteSelected()
}
break
case 72: // if h or H is pressed
if (e.ctrlKey) {
e.preventDefault()
Metamaps.Control.hideSelectedNodes()
Metamaps.Control.hideSelectedEdges()
}
break
default:
break; // alert(e.which)
}
})
$(window).resize(function () {
if (Metamaps.Visualize && Metamaps.Visualize.mGraph) Metamaps.Visualize.mGraph.canvas.resize($(window).width(), $(window).height())
if ((Metamaps.Active.Map || Metamaps.Active.Topic) && Metamaps.Famous && Metamaps.Famous.maps.surf) Metamaps.Famous.maps.reposition()
if (Metamaps.Active.Map && Metamaps.Realtime.inConversation) Metamaps.Realtime.positionVideos()
})
}
}; // end Metamaps.Listeners

View file

@ -0,0 +1,667 @@
/* global Metamaps, $ */
/*
* Metamaps.Map.js.erb
*
* Dependencies:
* Metamaps.Create
* Metamaps.Filter
* Metamaps.JIT
* Metamaps.Loading
* Metamaps.Maps
* Metamaps.Realtime
* Metamaps.Router
* Metamaps.Selected
* Metamaps.SynapseCard
* Metamaps.TopicCard
* Metamaps.Visualize
* - Metamaps.Active
* - Metamaps.Backbone
* - Metamaps.GlobalUI
* - Metamaps.Mappers
* - Metamaps.Mappings
* - Metamaps.Messages
* - Metamaps.Synapses
* - Metamaps.Topics
*
* Major sub-modules:
* - Metamaps.Map.CheatSheet
* - Metamaps.Map.InfoBox
*/
Metamaps.Map = {
events: {
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
},
nextX: 0,
nextY: 0,
sideLength: 1,
turnCount: 0,
nextXshift: 1,
nextYshift: 0,
timeToTurn: 0,
init: function () {
var self = Metamaps.Map
// prevent right clicks on the main canvas, so as to not get in the way of our right clicks
$('#center-container').bind('contextmenu', function (e) {
return false
})
$('.sidebarFork').click(function () {
self.fork()
})
Metamaps.GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
self.InfoBox.init()
self.CheatSheet.init()
$(document).on(Metamaps.Map.events.editedByActiveMapper, self.editedByActiveMapper)
},
launch: function (id) {
var bb = Metamaps.Backbone
var start = function (data) {
Metamaps.Active.Map = new bb.Map(data.map)
Metamaps.Mappers = new bb.MapperCollection(data.mappers)
Metamaps.Topics = new bb.TopicCollection(data.topics)
Metamaps.Synapses = new bb.SynapseCollection(data.synapses)
Metamaps.Mappings = new bb.MappingCollection(data.mappings)
Metamaps.Messages = data.messages
Metamaps.Backbone.attachCollectionEvents()
var map = Metamaps.Active.Map
var mapper = Metamaps.Active.Mapper
// add class to .wrapper for specifying whether you can edit the map
if (map.authorizeToEdit(mapper)) {
$('.wrapper').addClass('canEditMap')
}
// add class to .wrapper for specifying if the map can
// be collaborated on
if (map.get('permission') === 'commons') {
$('.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()
// update filters
Metamaps.Filter.reset()
// reset selected arrays
Metamaps.Selected.reset()
// set the proper mapinfobox content
Metamaps.Map.InfoBox.load()
// these three update the actual filter box with the right list items
Metamaps.Filter.checkMetacodes()
Metamaps.Filter.checkSynapses()
Metamaps.Filter.checkMappers()
Metamaps.Realtime.startActiveMap()
Metamaps.Loading.hide()
}
$.ajax({
url: '/maps/' + id + '/contains.json',
success: start
})
},
end: function () {
if (Metamaps.Active.Map) {
$('.wrapper').removeClass('canEditMap commonsMap')
Metamaps.Map.resetSpiral()
$('.rightclickmenu').remove()
Metamaps.TopicCard.hideCard()
Metamaps.SynapseCard.hideCard()
Metamaps.Create.newTopic.hide()
Metamaps.Create.newSynapse.hide()
Metamaps.Filter.close()
Metamaps.Map.InfoBox.close()
Metamaps.Realtime.endActiveMap()
}
},
fork: function () {
Metamaps.GlobalUI.openLightbox('forkmap')
var nodes_data = '',
synapses_data = ''
var nodes_array = []
var synapses_array = []
// collect the unfiltered topics
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
// 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 + ','
}
})
// collect the unfiltered synapses
Metamaps.Synapses.each(function (synapse) {
var desc = synapse.get('desc')
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()
nodes_data = nodes_data.slice(0, -1)
Metamaps.GlobalUI.CreateMap.topicsToMap = nodes_data
Metamaps.GlobalUI.CreateMap.synapsesToMap = synapses_data
},
leavePrivateMap: function () {
var map = Metamaps.Active.Map
Metamaps.Maps.Active.remove(map)
Metamaps.Maps.Featured.remove(map)
Metamaps.Router.home()
Metamaps.GlobalUI.notifyUser('Sorry! That map has been changed to Private.')
},
commonsToPublic: function () {
Metamaps.Realtime.turnOff(true); // true is for 'silence'
Metamaps.GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.')
Metamaps.Active.Map.trigger('changeByOther')
},
publicToCommons: function () {
var confirmString = 'This map permission has been changed to Commons! '
confirmString += 'Do you want to reload and enable realtime collaboration?'
var c = confirm(confirmString)
if (c) {
Metamaps.Router.maps(Metamaps.Active.Map.id)
}
},
editedByActiveMapper: function () {
if (Metamaps.Active.Mapper) {
Metamaps.Mappers.add(Metamaps.Active.Mapper)
}
},
getNextCoord: function () {
var self = Metamaps.Map
var nextX = self.nextX
var nextY = self.nextY
var DISTANCE_BETWEEN = 120
self.nextX = self.nextX + DISTANCE_BETWEEN * self.nextXshift
self.nextY = self.nextY + DISTANCE_BETWEEN * self.nextYshift
self.timeToTurn += 1
// if true, it's time to turn
if (self.timeToTurn === self.sideLength) {
self.turnCount += 1
// if true, it's time to increase side length
if (self.turnCount % 2 === 0) {
self.sideLength += 1
}
self.timeToTurn = 0
// going right? turn down
if (self.nextXshift == 1 && self.nextYshift == 0) {
self.nextXshift = 0
self.nextYshift = 1
}
// going down? turn left
else if (self.nextXshift == 0 && self.nextYshift == 1) {
self.nextXshift = -1
self.nextYshift = 0
}
// going left? turn up
else if (self.nextXshift == -1 && self.nextYshift == 0) {
self.nextXshift = 0
self.nextYshift = -1
}
// going up? turn right
else if (self.nextXshift == 0 && self.nextYshift == -1) {
self.nextXshift = 1
self.nextYshift = 0
}
}
return {
x: nextX,
y: nextY
}
},
resetSpiral: function () {
Metamaps.Map.nextX = 0
Metamaps.Map.nextY = 0
Metamaps.Map.nextXshift = 1
Metamaps.Map.nextYshift = 0
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()
}
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')
}
})
}
}
/*
*
* CHEATSHEET
*
*/
Metamaps.Map.CheatSheet = {
init: function () {
// tab the cheatsheet
$('#cheatSheet').tabs()
$('#quickReference').tabs().addClass('ui-tabs-vertical ui-helper-clearfix')
$('#quickReference .ui-tabs-nav li').removeClass('ui-corner-top').addClass('ui-corner-left')
// id = the id of a vimeo video
var switchVideo = function (element, id) {
$('.tutorialItem').removeClass('active')
$(element).addClass('active')
$('#tutorialVideo').attr('src', '//player.vimeo.com/video/' + id)
}
$('#gettingStarted').click(function () {
// switchVideo(this,'88334167')
})
$('#upYourSkillz').click(function () {
// switchVideo(this,'100118167')
})
$('#advancedMapping').click(function () {
// switchVideo(this,'88334167')
})
}
}; // end Metamaps.Map.CheatSheet
/*
*
* INFOBOX
*
*/
Metamaps.Map.InfoBox = {
isOpen: false,
changing: false,
selectingPermission: false,
changePermissionText: "<div class='tooltips'>As the creator, you can change the permission of this map, but the permissions of the topics and synapses on it must be changed independently.</div>",
nameHTML: '<span class="best_in_place best_in_place_name" id="best_in_place_map_{{id}}_name" data-url="/maps/{{id}}" data-object="map" data-attribute="name" data-type="textarea" data-activator="#mapInfoName">{{name}}</span>',
descHTML: '<span class="best_in_place best_in_place_desc" id="best_in_place_map_{{id}}_desc" data-url="/maps/{{id}}" data-object="map" data-attribute="desc" data-nil="Click to add description..." data-type="textarea" data-activator="#mapInfoDesc">{{desc}}</span>',
init: function () {
var self = Metamaps.Map.InfoBox
$('.mapInfoIcon').click(self.toggleBox)
$('.mapInfoBox').click(function (event) {
event.stopPropagation()
})
$('body').click(self.close)
self.attachEventListeners()
self.generateBoxHTML = Hogan.compile($('#mapInfoBoxTemplate').html())
},
toggleBox: function (event) {
var self = Metamaps.Map.InfoBox
if (self.isOpen) self.close()
else self.open()
event.stopPropagation()
},
open: function () {
var self = Metamaps.Map.InfoBox
$('.mapInfoIcon div').addClass('hide')
if (!self.isOpen && !self.changing) {
self.changing = true
$('.mapInfoBox').fadeIn(200, function () {
self.changing = false
self.isOpen = true
})
}
},
close: function () {
var self = Metamaps.Map.InfoBox
$('.mapInfoIcon div').removeClass('hide')
if (!self.changing) {
self.changing = true
$('.mapInfoBox').fadeOut(200, function () {
self.changing = false
self.isOpen = false
self.hidePermissionSelect()
$('.mapContributors .tip').hide()
})
}
},
load: function () {
var self = Metamaps.Map.InfoBox
var map = Metamaps.Active.Map
var obj = map.pick('permission', 'contributor_count', 'topic_count', 'synapse_count')
var isCreator = map.authorizePermissionChange(Metamaps.Active.Mapper)
var canEdit = map.authorizeToEdit(Metamaps.Active.Mapper)
var shareable = map.get('permission') !== 'private'
obj['name'] = canEdit ? Hogan.compile(self.nameHTML).render({id: map.id, name: map.get('name')}) : map.get('name')
obj['desc'] = canEdit ? Hogan.compile(self.descHTML).render({id: map.id, desc: map.get('desc')}) : map.get('desc')
obj['map_creator_tip'] = isCreator ? self.changePermissionText : ''
obj['contributors_class'] = Metamaps.Mappers.length > 1 ? 'multiple' : ''
obj['contributors_class'] += Metamaps.Mappers.length === 2 ? ' mTwo' : ''
obj['contributor_image'] = Metamaps.Mappers.length > 0 ? Metamaps.Mappers.models[0].get('image') : "<%= asset_path('user.png') %>"
obj['contributor_list'] = self.createContributorList()
obj['user_name'] = isCreator ? 'You' : map.get('user_name')
obj['created_at'] = map.get('created_at_clean')
obj['updated_at'] = map.get('updated_at_clean')
var classes = isCreator ? 'yourMap' : ''
classes += canEdit ? ' canEdit' : ''
classes += shareable ? ' shareable' : ''
$('.mapInfoBox').removeClass('shareable yourMap canEdit')
.addClass(classes)
.html(self.generateBoxHTML.render(obj))
self.attachEventListeners()
},
attachEventListeners: function () {
var self = Metamaps.Map.InfoBox
$('.mapInfoBox.canEdit .best_in_place').best_in_place()
// because anyone who can edit the map can change the map title
var bipName = $('.mapInfoBox .best_in_place_name')
bipName.unbind('best_in_place:activate').bind('best_in_place:activate', function () {
var $el = bipName.find('textarea')
var el = $el[0]
$el.attr('maxlength', '140')
$('.mapInfoName').append('<div class="nameCounter forMap"></div>')
var callback = function (data) {
$('.nameCounter.forMap').html(data.all + '/140')
}
Countable.live(el, callback)
})
bipName.unbind('best_in_place:deactivate').bind('best_in_place:deactivate', function () {
$('.nameCounter.forMap').remove()
})
$('.mapInfoName .best_in_place_name').unbind('ajax:success').bind('ajax:success', function () {
var name = $(this).html()
Metamaps.Active.Map.set('name', name)
Metamaps.Active.Map.trigger('saved')
})
$('.mapInfoDesc .best_in_place_desc').unbind('ajax:success').bind('ajax:success', function () {
var desc = $(this).html()
Metamaps.Active.Map.set('desc', desc)
Metamaps.Active.Map.trigger('saved')
})
$('.yourMap .mapPermission').unbind().click(self.onPermissionClick)
// .yourMap in the unbind/bind is just a namespace for the events
// not a reference to the class .yourMap on the .mapInfoBox
$('.mapInfoBox.yourMap').unbind('.yourMap').bind('click.yourMap', self.hidePermissionSelect)
$('.yourMap .mapInfoDelete').unbind().click(self.deleteActiveMap)
$('.mapContributors span, #mapContribs').unbind().click(function (event) {
$('.mapContributors .tip').toggle()
event.stopPropagation()
})
$('.mapContributors .tip').unbind().click(function (event) {
event.stopPropagation()
})
$('.mapContributors .tip li a').click(Metamaps.Router.intercept)
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function () {
$('.mapContributors .tip').hide()
})
},
updateNameDescPerm: function (name, desc, perm) {
$('.mapInfoName .best_in_place_name').html(name)
$('.mapInfoDesc .best_in_place_desc').html(desc)
$('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm)
},
createContributorList: function () {
var self = Metamaps.Map.InfoBox
var string = ''
string += '<ul>'
Metamaps.Mappers.each(function (m) {
string += '<li><a href="/explore/mapper/' + m.get('id') + '">' + '<img class="rtUserImage" width="25" height="25" src="' + m.get('image') + '" />' + m.get('name') + '</a></li>'
})
string += '</ul>'
return string
},
updateNumbers: function () {
var self = Metamaps.Map.InfoBox
var mapper = Metamaps.Active.Mapper
var contributors_class = ''
if (Metamaps.Mappers.length === 2) contributors_class = 'multiple mTwo'
else if (Metamaps.Mappers.length > 2) contributors_class = 'multiple'
var contributors_image = "<%= asset_path('user.png') %>"
if (Metamaps.Mappers.length > 0) {
// get the first contributor and use their image
contributors_image = Metamaps.Mappers.models[0].get('image')
}
$('.mapContributors img').attr('src', contributors_image).removeClass('multiple mTwo').addClass(contributors_class)
$('.mapContributors span').text(Metamaps.Mappers.length)
$('.mapContributors .tip').html(self.createContributorList())
$('.mapTopics').text(Metamaps.Topics.length)
$('.mapSynapses').text(Metamaps.Synapses.length)
$('.mapEditedAt').html('<span>Last edited: </span>' + Metamaps.Util.nowDateFormatted())
},
onPermissionClick: function (event) {
var self = Metamaps.Map.InfoBox
if (!self.selectingPermission) {
self.selectingPermission = true
$(this).addClass('minimize') // this line flips the drop down arrow to a pull up arrow
if ($(this).hasClass('commons')) {
$(this).append('<ul class="permissionSelect"><li class="public"></li><li class="private"></li></ul>')
} else if ($(this).hasClass('public')) {
$(this).append('<ul class="permissionSelect"><li class="commons"></li><li class="private"></li></ul>')
} else if ($(this).hasClass('private')) {
$(this).append('<ul class="permissionSelect"><li class="commons"></li><li class="public"></li></ul>')
}
$('.mapPermission .permissionSelect li').click(self.selectPermission)
event.stopPropagation()
}
},
hidePermissionSelect: function () {
var self = Metamaps.Map.InfoBox
self.selectingPermission = false
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
$('.mapPermission .permissionSelect').remove()
},
selectPermission: function (event) {
var self = Metamaps.Map.InfoBox
self.selectingPermission = false
var permission = $(this).attr('class')
var permBefore = Metamaps.Active.Map.get('permission')
Metamaps.Active.Map.save({
permission: permission
})
Metamaps.Active.Map.updateMapWrapper()
if (permBefore !== 'commons' && permission === 'commons') {
Metamaps.Realtime.setupSocket()
Metamaps.Realtime.turnOn()
}
else if (permBefore === 'commons' && permission === 'public') {
Metamaps.Realtime.turnOff(true); // true is to 'silence'
// the notification that would otherwise be sent
}
shareable = permission === 'private' ? '' : 'shareable'
$('.mapPermission').removeClass('commons public private minimize').addClass(permission)
$('.mapPermission .permissionSelect').remove()
$('.mapInfoBox').removeClass('shareable').addClass(shareable)
event.stopPropagation()
},
deleteActiveMap: function () {
var confirmString = 'Are you sure you want to delete this map? '
confirmString += 'This action is irreversible. It will not delete the topics and synapses on the map.'
var doIt = confirm(confirmString)
var map = Metamaps.Active.Map
var mapper = Metamaps.Active.Mapper
var authorized = map.authorizePermissionChange(mapper)
if (doIt && authorized) {
Metamaps.Map.InfoBox.close()
Metamaps.Maps.Active.remove(map)
Metamaps.Maps.Featured.remove(map)
Metamaps.Maps.Mine.remove(map)
map.destroy()
Metamaps.Router.home()
Metamaps.GlobalUI.notifyUser('Map eliminated!')
}
else if (!authorized) {
alert("Hey now. We can't just go around willy nilly deleting other people's maps now can we? Run off and find something constructive to do, eh?")
}
}
}; // end Metamaps.Map.InfoBox

View file

@ -0,0 +1,20 @@
/* global Metamaps, $ */
/*
* Metamaps.Mapper.js.erb
*
* Dependencies: none!
*/
Metamaps.Mapper = {
// this function is to retrieve a mapper JSON object from the database
// @param id = the id of the mapper to retrieve
get: function (id, callback) {
return $.ajax({
url: '/users/' + id + '.json',
success: function (data) {
callback(new Metamaps.Backbone.Mapper(data))
}
})
}
}; // end Metamaps.Mapper

View file

@ -0,0 +1,117 @@
/* global Metamaps, $ */
/*
* Metamaps.Organize.js.erb
*
* Dependencies:
* - Metamaps.Visualize
*/
Metamaps.Organize = {
init: function () {},
arrange: function (layout, centerNode) {
// first option for layout to implement is 'grid', will do an evenly spaced grid with its center at the 0,0 origin
if (layout == 'grid') {
var numNodes = _.size(Metamaps.Visualize.mGraph.graph.nodes); // this will always be an integer, the # of nodes on your graph visualization
var numColumns = Math.floor(Math.sqrt(numNodes)) // the number of columns to make an even grid
var GRIDSPACE = 400
var row = 0
var column = 0
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
if (column == numColumns) {
column = 0
row += 1
}
var newPos = new $jit.Complex()
newPos.x = column * GRIDSPACE
newPos.y = row * GRIDSPACE
n.setPos(newPos, 'end')
column += 1
})
Metamaps.Visualize.mGraph.animate(Metamaps.JIT.ForceDirected.animateSavedLayout)
} else if (layout == 'grid_full') {
// this will always be an integer, the # of nodes on your graph visualization
var numNodes = _.size(Metamaps.Visualize.mGraph.graph.nodes)
// var numColumns = Math.floor(Math.sqrt(numNodes)) // the number of columns to make an even grid
// var GRIDSPACE = 400
var height = Metamaps.Visualize.mGraph.canvas.getSize(0).height
var width = Metamaps.Visualize.mGraph.canvas.getSize(0).width
var totalArea = height * width
var cellArea = totalArea / numNodes
var ratio = height / width
var cellWidth = sqrt(cellArea / ratio)
var cellHeight = cellArea / cellWidth
var row = floor(height / cellHeight)
var column = floor(width / cellWidth)
var totalCells = row * column
if (totalCells)
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
if (column == numColumns) {
column = 0
row += 1
}
var newPos = new $jit.Complex()
newPos.x = column * GRIDSPACE
newPos.y = row * GRIDSPACE
n.setPos(newPos, 'end')
column += 1
})
Metamaps.Visualize.mGraph.animate(Metamaps.JIT.ForceDirected.animateSavedLayout)
} else if (layout == 'radial') {
var centerX = centerNode.getPos().x
var centerY = centerNode.getPos().y
centerNode.setPos(centerNode.getPos(), 'end')
console.log(centerNode.adjacencies)
var lineLength = 200
var usedNodes = {}
usedNodes[centerNode.id] = centerNode
var radial = function (node, level, degree) {
if (level == 1) {
var numLinksTemp = _.size(node.adjacencies)
var angleTemp = 2 * Math.PI / numLinksTemp
} else {
angleTemp = 2 * Math.PI / 20
}
node.eachAdjacency(function (a) {
var isSecondLevelNode = (centerNode.adjacencies[a.nodeTo.id] != undefined && level > 1)
if (usedNodes[a.nodeTo.id] == undefined && !isSecondLevelNode) {
var newPos = new $jit.Complex()
newPos.x = level * lineLength * Math.sin(degree) + centerX
newPos.y = level * lineLength * Math.cos(degree) + centerY
a.nodeTo.setPos(newPos, 'end')
usedNodes[a.nodeTo.id] = a.nodeTo
radial(a.nodeTo, level + 1, degree)
degree += angleTemp
}
})
}
radial(centerNode, 1, 0)
Metamaps.Visualize.mGraph.animate(Metamaps.JIT.ForceDirected.animateSavedLayout)
} else if (layout == 'center_viewport') {
var lowX = 0,
lowY = 0,
highX = 0,
highY = 0
var oldOriginX = Metamaps.Visualize.mGraph.canvas.translateOffsetX
var oldOriginY = Metamaps.Visualize.mGraph.canvas.translateOffsetY
Metamaps.Visualize.mGraph.graph.eachNode(function (n) {
if (n.id === 1) {
lowX = n.getPos().x
lowY = n.getPos().y
highX = n.getPos().x
highY = n.getPos().y
}
if (n.getPos().x < lowX) lowX = n.getPos().x
if (n.getPos().y < lowY) lowY = n.getPos().y
if (n.getPos().x > highX) highX = n.getPos().x
if (n.getPos().y > highY) highY = n.getPos().y
})
console.log(lowX, lowY, highX, highY)
var newOriginX = (lowX + highX) / 2
var newOriginY = (lowY + highY) / 2
} else alert('please call function with a valid layout dammit!')
}
}; // end Metamaps.Organize

View file

@ -0,0 +1,169 @@
/* global Metamaps, $ */
/*
* Metamaps.Synapse.js.erb
*
* Dependencies:
* - Metamaps.Backbone
* - Metamaps.Control
* - Metamaps.Create
* - Metamaps.JIT
* - Metamaps.Map
* - Metamaps.Mappings
* - Metamaps.Selected
* - Metamaps.Settings
* - Metamaps.Synapses
* - Metamaps.Topics
* - Metamaps.Visualize
*/
Metamaps.Synapse = {
// this function is to retrieve a synapse JSON object from the database
// @param id = the id of the synapse to retrieve
get: function (id, callback) {
// if the desired topic is not yet in the local topic repository, fetch it
if (Metamaps.Synapses.get(id) == undefined) {
if (!callback) {
var e = $.ajax({
url: '/synapses/' + id + '.json',
async: false
})
Metamaps.Synapses.add($.parseJSON(e.responseText))
return Metamaps.Synapses.get(id)
} else {
return $.ajax({
url: '/synapses/' + id + '.json',
success: function (data) {
Metamaps.Synapses.add(data)
callback(Metamaps.Synapses.get(id))
}
})
}
} else {
if (!callback) {
return Metamaps.Synapses.get(id)
} else {
return callback(Metamaps.Synapses.get(id))
}
}
},
/*
*
*
*/
renderSynapse: function (mapping, synapse, node1, node2, createNewInDB) {
var self = Metamaps.Synapse
var edgeOnViz
var newedge = synapse.createEdge(mapping)
Metamaps.Visualize.mGraph.graph.addAdjacence(node1, node2, newedge.data)
edgeOnViz = Metamaps.Visualize.mGraph.graph.getAdjacence(node1.id, node2.id)
synapse.set('edge', edgeOnViz)
synapse.updateEdge() // links the synapse and the mapping to the edge
Metamaps.Control.selectEdge(edgeOnViz)
var mappingSuccessCallback = function (mappingModel, response) {
var newSynapseData = {
mappingid: mappingModel.id,
mappableid: mappingModel.get('mappable_id')
}
$(document).trigger(Metamaps.JIT.events.newSynapse, [newSynapseData])
}
var synapseSuccessCallback = function (synapseModel, response) {
if (Metamaps.Active.Map) {
mapping.save({ mappable_id: synapseModel.id }, {
success: mappingSuccessCallback
})
}
}
if (!Metamaps.Settings.sandbox && createNewInDB) {
if (synapse.isNew()) {
synapse.save(null, {
success: synapseSuccessCallback,
error: function (model, response) {
console.log('error saving synapse to database')
}
})
} else if (!synapse.isNew() && Metamaps.Active.Map) {
mapping.save(null, {
success: mappingSuccessCallback
})
}
}
},
createSynapseLocally: function () {
var self = Metamaps.Synapse,
topic1,
topic2,
node1,
node2,
synapse,
mapping
$(document).trigger(Metamaps.Map.events.editedByActiveMapper)
// for each node in this array we will create a synapse going to the position2 node.
var synapsesToCreate = []
topic2 = Metamaps.Topics.get(Metamaps.Create.newSynapse.topic2id)
node2 = topic2.get('node')
var len = Metamaps.Selected.Nodes.length
if (len == 0) {
topic1 = Metamaps.Topics.get(Metamaps.Create.newSynapse.topic1id)
synapsesToCreate[0] = topic1.get('node')
} else if (len > 0) {
synapsesToCreate = Metamaps.Selected.Nodes
}
for (var i = 0; i < synapsesToCreate.length; i++) {
node1 = synapsesToCreate[i]
topic1 = node1.getData('topic')
synapse = new Metamaps.Backbone.Synapse({
desc: Metamaps.Create.newSynapse.description,
node1_id: topic1.isNew() ? topic1.cid : topic1.id,
node2_id: topic2.isNew() ? topic2.cid : topic2.id,
})
Metamaps.Synapses.add(synapse)
mapping = new Metamaps.Backbone.Mapping({
mappable_type: 'Synapse',
mappable_id: synapse.cid,
})
Metamaps.Mappings.add(mapping)
// this function also includes the creation of the synapse in the database
self.renderSynapse(mapping, synapse, node1, node2, true)
} // for each in synapsesToCreate
Metamaps.Create.newSynapse.hide()
},
getSynapseFromAutocomplete: function (id) {
var self = Metamaps.Synapse,
topic1,
topic2,
node1,
node2
var synapse = self.get(id)
var mapping = new Metamaps.Backbone.Mapping({
mappable_type: 'Synapse',
mappable_id: synapse.id,
})
Metamaps.Mappings.add(mapping)
topic1 = Metamaps.Topics.get(Metamaps.Create.newSynapse.topic1id)
node1 = topic1.get('node')
topic2 = Metamaps.Topics.get(Metamaps.Create.newSynapse.topic2id)
node2 = topic2.get('node')
Metamaps.Create.newSynapse.hide()
self.renderSynapse(mapping, synapse, node1, node2, true)
}
}; // end Metamaps.Synapse

View file

@ -0,0 +1,362 @@
/* global Metamaps, $ */
/*
* Metamaps.Topic.js.erb
*
* Dependencies:
* - Metamaps.Active
* - Metamaps.Backbone
* - Metamaps.Backbone
* - Metamaps.Create
* - Metamaps.Creators
* - Metamaps.Famous
* - Metamaps.Filter
* - Metamaps.GlobalUI
* - Metamaps.JIT
* - Metamaps.Mappings
* - Metamaps.Selected
* - Metamaps.Settings
* - Metamaps.SynapseCard
* - Metamaps.Synapses
* - Metamaps.TopicCard
* - Metamaps.Topics
* - Metamaps.Util
* - Metamaps.Visualize
* - Metamaps.tempInit
* - Metamaps.tempNode
* - Metamaps.tempNode2
*/
Metamaps.Topic = {
// this function is to retrieve a topic JSON object from the database
// @param id = the id of the topic to retrieve
get: function (id, callback) {
// if the desired topic is not yet in the local topic repository, fetch it
if (Metamaps.Topics.get(id) == undefined) {
// console.log("Ajax call!")
if (!callback) {
var e = $.ajax({
url: '/topics/' + id + '.json',
async: false
})
Metamaps.Topics.add($.parseJSON(e.responseText))
return Metamaps.Topics.get(id)
} else {
return $.ajax({
url: '/topics/' + id + '.json',
success: function (data) {
Metamaps.Topics.add(data)
callback(Metamaps.Topics.get(id))
}
})
}
} else {
if (!callback) {
return Metamaps.Topics.get(id)
} else {
return callback(Metamaps.Topics.get(id))
}
}
},
launch: function (id) {
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()
// update filters
Metamaps.Filter.reset()
// reset selected arrays
Metamaps.Selected.reset()
// these three update the actual filter box with the right list items
Metamaps.Filter.checkMetacodes()
Metamaps.Filter.checkSynapses()
Metamaps.Filter.checkMappers()
}
$.ajax({
url: '/topics/' + id + '/network.json',
success: start
})
},
end: function () {
if (Metamaps.Active.Topic) {
$('.rightclickmenu').remove()
Metamaps.TopicCard.hideCard()
Metamaps.SynapseCard.hideCard()
Metamaps.Filter.close()
}
},
centerOn: function (nodeid) {
if (!Metamaps.Visualize.mGraph.busy) {
Metamaps.Visualize.mGraph.onClick(nodeid, {
hideLabels: false,
duration: 1000,
onComplete: function () {}
})
}
},
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 () {}
})
},
/*
*
*
*/
renderTopic: function (mapping, topic, createNewInDB, permitCreateSynapseAfter) {
var self = Metamaps.Topic
var nodeOnViz, tempPos
var newnode = topic.createNode()
var midpoint = {}, pixelPos
if (!$.isEmptyObject(Metamaps.Visualize.mGraph.graph.nodes)) {
Metamaps.Visualize.mGraph.graph.addNode(newnode)
nodeOnViz = Metamaps.Visualize.mGraph.graph.getNode(newnode.id)
topic.set('node', nodeOnViz, {silent: true})
topic.updateNode() // links the topic and the mapping to the node
nodeOnViz.setData('dim', 1, 'start')
nodeOnViz.setData('dim', 25, 'end')
if (Metamaps.Visualize.type === 'RGraph') {
tempPos = new $jit.Complex(mapping.get('xloc'), mapping.get('yloc'))
tempPos = tempPos.toPolar()
nodeOnViz.setPos(tempPos, 'current')
nodeOnViz.setPos(tempPos, 'start')
nodeOnViz.setPos(tempPos, 'end')
} else if (Metamaps.Visualize.type === 'ForceDirected') {
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'current')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'start')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'end')
}
if (Metamaps.Create.newTopic.addSynapse && permitCreateSynapseAfter) {
Metamaps.Create.newSynapse.topic1id = Metamaps.tempNode.getData('topic').id
// position the form
midpoint.x = Metamaps.tempNode.pos.getc().x + (nodeOnViz.pos.getc().x - Metamaps.tempNode.pos.getc().x) / 2
midpoint.y = Metamaps.tempNode.pos.getc().y + (nodeOnViz.pos.getc().y - Metamaps.tempNode.pos.getc().y) / 2
pixelPos = Metamaps.Util.coordsToPixels(midpoint)
$('#new_synapse').css('left', pixelPos.x + 'px')
$('#new_synapse').css('top', pixelPos.y + 'px')
// show the form
Metamaps.Create.newSynapse.open()
Metamaps.Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500,
onComplete: function () {
Metamaps.tempNode = null
Metamaps.tempNode2 = null
Metamaps.tempInit = false
}
})
} else {
Metamaps.Visualize.mGraph.fx.plotNode(nodeOnViz, Metamaps.Visualize.mGraph.canvas)
Metamaps.Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500,
onComplete: function () {}
})
}
} else {
Metamaps.Visualize.mGraph.loadJSON(newnode)
nodeOnViz = Metamaps.Visualize.mGraph.graph.getNode(newnode.id)
topic.set('node', nodeOnViz, {silent: true})
topic.updateNode() // links the topic and the mapping to the node
nodeOnViz.setData('dim', 1, 'start')
nodeOnViz.setData('dim', 25, 'end')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'current')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'start')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'end')
Metamaps.Visualize.mGraph.fx.plotNode(nodeOnViz, Metamaps.Visualize.mGraph.canvas)
Metamaps.Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500,
onComplete: function () {}
})
}
var mappingSuccessCallback = function (mappingModel, response) {
var newTopicData = {
mappingid: mappingModel.id,
mappableid: mappingModel.get('mappable_id')
}
$(document).trigger(Metamaps.JIT.events.newTopic, [newTopicData])
}
var topicSuccessCallback = function (topicModel, response) {
if (Metamaps.Active.Map) {
mapping.save({ mappable_id: topicModel.id }, {
success: mappingSuccessCallback,
error: function (model, response) {
console.log('error saving mapping to database')
}
})
}
if (Metamaps.Create.newTopic.addSynapse) {
Metamaps.Create.newSynapse.topic2id = topicModel.id
}
}
if (!Metamaps.Settings.sandbox && createNewInDB) {
if (topic.isNew()) {
topic.save(null, {
success: topicSuccessCallback,
error: function (model, response) {
console.log('error saving topic to database')
}
})
} else if (!topic.isNew() && Metamaps.Active.Map) {
mapping.save(null, {
success: mappingSuccessCallback
})
}
}
},
createTopicLocally: function () {
var self = Metamaps.Topic
if (Metamaps.Create.newTopic.name === '') {
Metamaps.GlobalUI.notifyUser('Please enter a topic title...')
return
}
// hide the 'double-click to add a topic' message
Metamaps.Famous.viz.hideInstructions()
$(document).trigger(Metamaps.Map.events.editedByActiveMapper)
var metacode = Metamaps.Metacodes.get(Metamaps.Create.newTopic.metacode)
var topic = new Metamaps.Backbone.Topic({
name: Metamaps.Create.newTopic.name,
metacode_id: metacode.id
})
Metamaps.Topics.add(topic)
var mapping = new Metamaps.Backbone.Mapping({
xloc: Metamaps.Create.newTopic.x,
yloc: Metamaps.Create.newTopic.y,
mappable_id: topic.cid,
mappable_type: 'Topic',
})
Metamaps.Mappings.add(mapping)
// these can't happen until the value is retrieved, which happens in the line above
Metamaps.Create.newTopic.hide()
self.renderTopic(mapping, topic, true, true) // this function also includes the creation of the topic in the database
},
getTopicFromAutocomplete: function (id) {
var self = Metamaps.Topic
$(document).trigger(Metamaps.Map.events.editedByActiveMapper)
Metamaps.Create.newTopic.hide()
var topic = self.get(id)
var mapping = new Metamaps.Backbone.Mapping({
xloc: Metamaps.Create.newTopic.x,
yloc: Metamaps.Create.newTopic.y,
mappable_type: 'Topic',
mappable_id: topic.id,
})
Metamaps.Mappings.add(mapping)
self.renderTopic(mapping, topic, true, true)
},
getTopicFromSearch: function (event, id) {
var self = Metamaps.Topic
$(document).trigger(Metamaps.Map.events.editedByActiveMapper)
var topic = self.get(id)
var nextCoords = Metamaps.Map.getNextCoord()
var mapping = new Metamaps.Backbone.Mapping({
xloc: nextCoords.x,
yloc: nextCoords.y,
mappable_type: 'Topic',
mappable_id: topic.id,
})
Metamaps.Mappings.add(mapping)
self.renderTopic(mapping, topic, true, true)
Metamaps.GlobalUI.notifyUser('Topic was added to your map!')
event.stopPropagation()
event.preventDefault()
return false
}
}; // end Metamaps.Topic

File diff suppressed because it is too large Load diff