break Map into three files

This commit is contained in:
Devin Howard 2016-09-22 23:51:13 +08:00
parent 120c2c0b67
commit 59b471ac62
4 changed files with 425 additions and 417 deletions

View file

@ -0,0 +1,27 @@
const 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')
})
}
}
export default CheatSheet

View file

@ -1,405 +1,19 @@
/* global Metamaps, $ */ /* global Metamaps, $ */
import Active from './Active' import Active from './Active'
import AutoLayout from './AutoLayout' import GlobalUI from '../GlobalUI'
import Create from './Create' import Router from '../Router'
import Filter from './Filter'
import GlobalUI from './GlobalUI'
import JIT from './JIT'
import Realtime from './Realtime'
import Selected from './Selected'
import SynapseCard from './SynapseCard'
import TopicCard from './TopicCard'
import Visualize from './Visualize'
/* /*
* Metamaps.Map.js.erb * Metamaps.Collaborators
* * Metamaps.Erb
* Dependencies: * Metamaps.Mappers
* - Metamaps.Backbone * Metamaps.Maps
* - Metamaps.Erb * Metamaps.Synapses
* - Metamaps.Loading * Metamaps.Topics
* - Metamaps.Mappers
* - Metamaps.Mappings
* - Metamaps.Maps
* - Metamaps.Messages
* - Metamaps.Router
* - Metamaps.Synapses
* - Metamaps.Topics
*
* Major sub-modules:
* - Metamaps.Map.CheatSheet
* - Metamaps.Map.InfoBox
*/ */
window.Metamaps = window.Metamaps || {} const InfoBox = {
Metamaps.Map = {
events: {
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
},
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
})
$('.starMap').click(function () {
if ($(this).is('.starred')) self.unstar()
else self.star()
})
$('.sidebarFork').click(function () {
self.fork()
})
GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
self.updateStar()
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) {
Active.Map = new bb.Map(data.map)
Metamaps.Mappers = new bb.MapperCollection(data.mappers)
Metamaps.Collaborators = new bb.MapperCollection(data.collaborators)
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.Stars = data.stars
Metamaps.Backbone.attachCollectionEvents()
var map = Active.Map
var mapper = 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')
}
Metamaps.Map.updateStar()
// set filter mapper H3 text
$('#filter_by_mapper h3').html('MAPPERS')
// build and render the visualization
Visualize.type = 'ForceDirected'
JIT.prepareVizData()
// update filters
Filter.reset()
// reset selected arrays
Selected.reset()
// set the proper mapinfobox content
Metamaps.Map.InfoBox.load()
// these three update the actual filter box with the right list items
Filter.checkMetacodes()
Filter.checkSynapses()
Filter.checkMappers()
Realtime.startActiveMap()
Metamaps.Loading.hide()
// for mobile
$('#header_content').html(map.get('name'))
}
$.ajax({
url: '/maps/' + id + '/contains.json',
success: start
})
},
end: function () {
if (Active.Map) {
$('.wrapper').removeClass('canEditMap commonsMap')
AutoLayout.resetSpiral()
$('.rightclickmenu').remove()
TopicCard.hideCard()
SynapseCard.hideCard()
Create.newTopic.hide(true) // true means force (and override pinned)
Create.newSynapse.hide()
Filter.close()
Metamaps.Map.InfoBox.close()
Realtime.endActiveMap()
}
},
updateStar: function () {
if (!Active.Mapper || !Metamaps.Stars) return
// update the star/unstar icon
if (Metamaps.Stars.find(function (s) { return s.user_id === Active.Mapper.id })) {
$('.starMap').addClass('starred')
$('.starMap .tooltipsAbove').html('Unstar')
} else {
$('.starMap').removeClass('starred')
$('.starMap .tooltipsAbove').html('Star')
}
},
star: function () {
var self = Metamaps.Map
if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/star')
Metamaps.Stars.push({ user_id: Active.Mapper.id, map_id: Active.Map.id })
Metamaps.Maps.Starred.add(Active.Map)
GlobalUI.notifyUser('Map is now starred')
self.updateStar()
},
unstar: function () {
var self = Metamaps.Map
if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/unstar')
Metamaps.Stars = Metamaps.Stars.filter(function (s) { return s.user_id != Active.Mapper.id })
Metamaps.Maps.Starred.remove(Active.Map)
self.updateStar()
},
fork: function () {
GlobalUI.openLightbox('forkmap')
var nodes_data = '',
synapses_data = ''
var nodes_array = []
var synapses_array = []
// collect the unfiltered topics
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 = 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)
GlobalUI.CreateMap.topicsToMap = nodes_data
GlobalUI.CreateMap.synapsesToMap = synapses_data
},
leavePrivateMap: function () {
var map = Active.Map
Metamaps.Maps.Active.remove(map)
Metamaps.Maps.Featured.remove(map)
Metamaps.Router.home()
GlobalUI.notifyUser('Sorry! That map has been changed to Private.')
},
cantEditNow: function () {
Realtime.turnOff(true); // true is for 'silence'
GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.')
Active.Map.trigger('changeByOther')
},
canEditNow: function () {
var confirmString = "You've been granted permission to edit this map. "
confirmString += 'Do you want to reload and enable realtime collaboration?'
var c = confirm(confirmString)
if (c) {
Metamaps.Router.maps(Active.Map.id)
}
},
editedByActiveMapper: function () {
if (Active.Mapper) {
Metamaps.Mappers.add(Active.Mapper)
}
},
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 = 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
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 = 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>"
GlobalUI.notifyUser(downloadMessage)
$.ajax({
type: 'POST',
dataType: 'json',
url: '/maps/' + 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, isOpen: false,
changing: false, changing: false,
selectingPermission: false, selectingPermission: false,
@ -407,7 +21,7 @@ Metamaps.Map.InfoBox = {
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>', 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>', 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 () { init: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
$('.mapInfoIcon').click(self.toggleBox) $('.mapInfoIcon').click(self.toggleBox)
$('.mapInfoBox').click(function (event) { $('.mapInfoBox').click(function (event) {
@ -426,7 +40,7 @@ Metamaps.Map.InfoBox = {
} }
}, },
toggleBox: function (event) { toggleBox: function (event) {
var self = Metamaps.Map.InfoBox var self = InfoBox
if (self.isOpen) self.close() if (self.isOpen) self.close()
else self.open() else self.open()
@ -434,7 +48,7 @@ Metamaps.Map.InfoBox = {
event.stopPropagation() event.stopPropagation()
}, },
open: function () { open: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
$('.mapInfoIcon div').addClass('hide') $('.mapInfoIcon div').addClass('hide')
if (!self.isOpen && !self.changing) { if (!self.isOpen && !self.changing) {
self.changing = true self.changing = true
@ -445,7 +59,7 @@ Metamaps.Map.InfoBox = {
} }
}, },
close: function () { close: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
$('.mapInfoIcon div').removeClass('hide') $('.mapInfoIcon div').removeClass('hide')
if (!self.changing) { if (!self.changing) {
@ -459,7 +73,7 @@ Metamaps.Map.InfoBox = {
} }
}, },
load: function () { load: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
var map = Active.Map var map = Active.Map
@ -494,7 +108,7 @@ Metamaps.Map.InfoBox = {
self.attachEventListeners() self.attachEventListeners()
}, },
attachEventListeners: function () { attachEventListeners: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
$('.mapInfoBox.canEdit .best_in_place').best_in_place() $('.mapInfoBox.canEdit .best_in_place').best_in_place()
@ -547,7 +161,7 @@ Metamaps.Map.InfoBox = {
$('.mapContributors .tip').unbind().click(function (event) { $('.mapContributors .tip').unbind().click(function (event) {
event.stopPropagation() event.stopPropagation()
}) })
$('.mapContributors .tip li a').click(Metamaps.Router.intercept) $('.mapContributors .tip li a').click(Router.intercept)
$('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function () { $('.mapInfoBox').unbind('.hideTip').bind('click.hideTip', function () {
$('.mapContributors .tip').hide() $('.mapContributors .tip').hide()
@ -556,7 +170,7 @@ Metamaps.Map.InfoBox = {
self.addTypeahead() self.addTypeahead()
}, },
addTypeahead: function () { addTypeahead: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
if (!Active.Map) return if (!Active.Map) return
@ -603,14 +217,14 @@ Metamaps.Map.InfoBox = {
} }
}, },
removeCollaborator: function (collaboratorId) { removeCollaborator: function (collaboratorId) {
var self = Metamaps.Map.InfoBox var self = InfoBox
Metamaps.Collaborators.remove(Metamaps.Collaborators.get(collaboratorId)) Metamaps.Collaborators.remove(Metamaps.Collaborators.get(collaboratorId))
var mapperIds = Metamaps.Collaborators.models.map(function (mapper) { return mapper.id }) var mapperIds = Metamaps.Collaborators.models.map(function (mapper) { return mapper.id })
$.post('/maps/' + Active.Map.id + '/access', { access: mapperIds }) $.post('/maps/' + Active.Map.id + '/access', { access: mapperIds })
self.updateNumbers() self.updateNumbers()
}, },
addCollaborator: function (newCollaboratorId) { addCollaborator: function (newCollaboratorId) {
var self = Metamaps.Map.InfoBox var self = InfoBox
if (Metamaps.Collaborators.get(newCollaboratorId)) { if (Metamaps.Collaborators.get(newCollaboratorId)) {
GlobalUI.notifyUser('That user already has access') GlobalUI.notifyUser('That user already has access')
@ -629,7 +243,7 @@ Metamaps.Map.InfoBox = {
$.getJSON('/users/' + newCollaboratorId + '.json', callback) $.getJSON('/users/' + newCollaboratorId + '.json', callback)
}, },
handleResultClick: function (event, item) { handleResultClick: function (event, item) {
var self = Metamaps.Map.InfoBox var self = InfoBox
self.addCollaborator(item.id) self.addCollaborator(item.id)
$('.collaboratorSearchField').typeahead('val', '') $('.collaboratorSearchField').typeahead('val', '')
@ -641,7 +255,7 @@ Metamaps.Map.InfoBox = {
$('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm) $('.mapInfoBox .mapPermission').removeClass('commons public private').addClass(perm)
}, },
createContributorList: function () { createContributorList: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
var relevantPeople = Active.Map.get('permission') === 'commons' ? Metamaps.Mappers : Metamaps.Collaborators var relevantPeople = Active.Map.get('permission') === 'commons' ? Metamaps.Mappers : Metamaps.Collaborators
var activeMapperIsCreator = Active.Mapper && Active.Mapper.id === Active.Map.get('user_id') var activeMapperIsCreator = Active.Mapper && Active.Mapper.id === Active.Map.get('user_id')
var string = '' var string = ''
@ -666,7 +280,7 @@ Metamaps.Map.InfoBox = {
updateNumbers: function () { updateNumbers: function () {
if (!Active.Map) return if (!Active.Map) return
var self = Metamaps.Map.InfoBox var self = InfoBox
var mapper = Active.Mapper var mapper = Active.Mapper
var relevantPeople = Active.Map.get('permission') === 'commons' ? Metamaps.Mappers : Metamaps.Collaborators var relevantPeople = Active.Map.get('permission') === 'commons' ? Metamaps.Mappers : Metamaps.Collaborators
@ -689,10 +303,10 @@ Metamaps.Map.InfoBox = {
$('.mapTopics').text(Metamaps.Topics.length) $('.mapTopics').text(Metamaps.Topics.length)
$('.mapSynapses').text(Metamaps.Synapses.length) $('.mapSynapses').text(Metamaps.Synapses.length)
$('.mapEditedAt').html('<span>Last edited: </span>' + Metamaps.Util.nowDateFormatted()) $('.mapEditedAt').html('<span>Last edited: </span>' + Util.nowDateFormatted())
}, },
onPermissionClick: function (event) { onPermissionClick: function (event) {
var self = Metamaps.Map.InfoBox var self = InfoBox
if (!self.selectingPermission) { if (!self.selectingPermission) {
self.selectingPermission = true self.selectingPermission = true
@ -709,14 +323,14 @@ Metamaps.Map.InfoBox = {
} }
}, },
hidePermissionSelect: function () { hidePermissionSelect: function () {
var self = Metamaps.Map.InfoBox var self = InfoBox
self.selectingPermission = false self.selectingPermission = false
$('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow $('.mapPermission').removeClass('minimize') // this line flips the pull up arrow to a drop down arrow
$('.mapPermission .permissionSelect').remove() $('.mapPermission .permissionSelect').remove()
}, },
selectPermission: function (event) { selectPermission: function (event) {
var self = Metamaps.Map.InfoBox var self = InfoBox
self.selectingPermission = false self.selectingPermission = false
var permission = $(this).attr('class') var permission = $(this).attr('class')
@ -740,19 +354,19 @@ Metamaps.Map.InfoBox = {
var authorized = map.authorizePermissionChange(mapper) var authorized = map.authorizePermissionChange(mapper)
if (doIt && authorized) { if (doIt && authorized) {
Metamaps.Map.InfoBox.close() InfoBox.close()
Metamaps.Maps.Active.remove(map) Metamaps.Maps.Active.remove(map)
Metamaps.Maps.Featured.remove(map) Metamaps.Maps.Featured.remove(map)
Metamaps.Maps.Mine.remove(map) Metamaps.Maps.Mine.remove(map)
Metamaps.Maps.Shared.remove(map) Metamaps.Maps.Shared.remove(map)
map.destroy() map.destroy()
Metamaps.Router.home() Router.home()
GlobalUI.notifyUser('Map eliminated!') GlobalUI.notifyUser('Map eliminated!')
} }
else if (!authorized) { 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?") 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 }
export default Metamaps.Map export default InfoBox

View file

@ -0,0 +1,365 @@
/* global Metamaps, $ */
import Active from './Active'
import AutoLayout from './AutoLayout'
import Create from './Create'
import Filter from './Filter'
import GlobalUI from './GlobalUI'
import JIT from './JIT'
import Realtime from './Realtime'
import Router from './Router'
import Selected from './Selected'
import SynapseCard from './SynapseCard'
import TopicCard from './TopicCard'
import Visualize from './Visualize'
import CheatSheet from './CheatSheet'
import InfoBox from './InfoBox'
/*
* Metamaps.Map.js.erb
*
* Dependencies:
* - Metamaps.Backbone
* - Metamaps.Erb
* - Metamaps.Loading
* - Metamaps.Mappers
* - Metamaps.Mappings
* - Metamaps.Maps
* - Metamaps.Messages
* - Metamaps.Synapses
* - Metamaps.Topics
*/
const Map = {
events: {
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
},
init: function () {
var self = 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
})
$('.starMap').click(function () {
if ($(this).is('.starred')) self.unstar()
else self.star()
})
$('.sidebarFork').click(function () {
self.fork()
})
GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
self.updateStar()
self.InfoBox.init()
CheatSheet.init()
$(document).on(Map.events.editedByActiveMapper, self.editedByActiveMapper)
},
launch: function (id) {
var bb = Metamaps.Backbone
var start = function (data) {
Active.Map = new bb.Map(data.map)
Metamaps.Mappers = new bb.MapperCollection(data.mappers)
Metamaps.Collaborators = new bb.MapperCollection(data.collaborators)
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.Stars = data.stars
Metamaps.Backbone.attachCollectionEvents()
var map = Active.Map
var mapper = 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')
}
Map.updateStar()
// set filter mapper H3 text
$('#filter_by_mapper h3').html('MAPPERS')
// build and render the visualization
Visualize.type = 'ForceDirected'
JIT.prepareVizData()
// update filters
Filter.reset()
// reset selected arrays
Selected.reset()
// set the proper mapinfobox content
Map.InfoBox.load()
// these three update the actual filter box with the right list items
Filter.checkMetacodes()
Filter.checkSynapses()
Filter.checkMappers()
Realtime.startActiveMap()
Metamaps.Loading.hide()
// for mobile
$('#header_content').html(map.get('name'))
}
$.ajax({
url: '/maps/' + id + '/contains.json',
success: start
})
},
end: function () {
if (Active.Map) {
$('.wrapper').removeClass('canEditMap commonsMap')
AutoLayout.resetSpiral()
$('.rightclickmenu').remove()
TopicCard.hideCard()
SynapseCard.hideCard()
Create.newTopic.hide(true) // true means force (and override pinned)
Create.newSynapse.hide()
Filter.close()
Map.InfoBox.close()
Realtime.endActiveMap()
}
},
updateStar: function () {
if (!Active.Mapper || !Metamaps.Stars) return
// update the star/unstar icon
if (Metamaps.Stars.find(function (s) { return s.user_id === Active.Mapper.id })) {
$('.starMap').addClass('starred')
$('.starMap .tooltipsAbove').html('Unstar')
} else {
$('.starMap').removeClass('starred')
$('.starMap .tooltipsAbove').html('Star')
}
},
star: function () {
var self = Map
if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/star')
Metamaps.Stars.push({ user_id: Active.Mapper.id, map_id: Active.Map.id })
Metamaps.Maps.Starred.add(Active.Map)
GlobalUI.notifyUser('Map is now starred')
self.updateStar()
},
unstar: function () {
var self = Map
if (!Active.Map) return
$.post('/maps/' + Active.Map.id + '/unstar')
Metamaps.Stars = Metamaps.Stars.filter(function (s) { return s.user_id != Active.Mapper.id })
Metamaps.Maps.Starred.remove(Active.Map)
self.updateStar()
},
fork: function () {
GlobalUI.openLightbox('forkmap')
var nodes_data = '',
synapses_data = ''
var nodes_array = []
var synapses_array = []
// collect the unfiltered topics
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 = 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)
GlobalUI.CreateMap.topicsToMap = nodes_data
GlobalUI.CreateMap.synapsesToMap = synapses_data
},
leavePrivateMap: function () {
var map = Active.Map
Metamaps.Maps.Active.remove(map)
Metamaps.Maps.Featured.remove(map)
Router.home()
GlobalUI.notifyUser('Sorry! That map has been changed to Private.')
},
cantEditNow: function () {
Realtime.turnOff(true); // true is for 'silence'
GlobalUI.notifyUser('Map was changed to Public. Editing is disabled.')
Active.Map.trigger('changeByOther')
},
canEditNow: function () {
var confirmString = "You've been granted permission to edit this map. "
confirmString += 'Do you want to reload and enable realtime collaboration?'
var c = confirm(confirmString)
if (c) {
Router.maps(Active.Map.id)
}
},
editedByActiveMapper: function () {
if (Active.Mapper) {
Metamaps.Mappers.add(Active.Mapper)
}
},
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 = 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
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 = 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>"
GlobalUI.notifyUser(downloadMessage)
$.ajax({
type: 'POST',
dataType: 'json',
url: '/maps/' + 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')
}
})
}
}
export CheatSheet, InfoBox
export default Map

View file

@ -13,7 +13,7 @@ import GlobalUI from './GlobalUI'
import Import from './Import' import Import from './Import'
import JIT from './JIT' import JIT from './JIT'
import Listeners from './Listeners' import Listeners from './Listeners'
import Map from './Map' import Map, { CheatSheet, InfoBox } from './Map'
import Mapper from './Mapper' import Mapper from './Mapper'
import Mobile from './Mobile' import Mobile from './Mobile'
import Mouse from './Mouse' import Mouse from './Mouse'
@ -46,6 +46,8 @@ Metamaps.Import = Import
Metamaps.JIT = JIT Metamaps.JIT = JIT
Metamaps.Listeners = Listeners Metamaps.Listeners = Listeners
Metamaps.Map = Map Metamaps.Map = Map
Metamaps.Map.CheatSheet = CheatSheet
Metamaps.Map.InfoBox = InfoBox
Metamaps.Maps = {} Metamaps.Maps = {}
Metamaps.Mapper = Mapper Metamaps.Mapper = Mapper
Metamaps.Mobile = Mobile Metamaps.Mobile = Mobile