got topic and synapse creation working

This commit is contained in:
Connor Turland 2017-02-04 04:13:59 +00:00
parent 04036882ab
commit 74dd20f02e
10 changed files with 189 additions and 456 deletions

View file

@ -0,0 +1,58 @@
// if we've placed a node into an island, we need to NOT place it in any other islands
// Every node should only appear in one island
// the top level array represents islands
// every island has some sort of 'focal' node
/*
var example = [
// the island that contains the focal node
{
id: 21,
parents: [
{
id: 25,
parents: []
},
{
id: 25,
parents: []
}
],
children: [{
id: 26,
children: []
}]
},
// all other islands should not contain children on the top level node
{
id: 21,
// parents may contain children
parents: [
{
id: 100,
parents: [
{
id: 101,
parents: [],
children: [
{
id: 103,
children: []
}
]
}
]
},
{
id: 102,
parents: []
}
]
},
{
id: 21,
parents: []
},
]
*/

View file

@ -1,10 +1,5 @@
import { findIndex, orderBy } from 'lodash'
// an array of synapses
// an array of topics
// a focal node
/*
step 1
generate an object/array that represents the intended layout
@ -13,18 +8,16 @@ generate an object/array that represents the intended layout
step 2
generate x,y coordinates for every topic in the layout object
step 3
set end states for every topic
Step 4
animate
*/
// synapses = [{ topic1_id: 4, topic2_id: 5, direction: 'from-to' }]
// synapses = [{ topic1_id: 4, topic2_id: 5, direction: 'from-to', desc: 'has reply' }]
const isEven = n => n % 2 === 0
const isOdd = n => Math.abs(n % 2) === 1
export const X_GRID_SPACE = 250
export const Y_GRID_SPACE = 200
export const ISLAND_SPACING = 300
export const generateLayoutObject = (topics, synapses, focalTopicId) => {
let layout = [] // will be the final output
@ -102,9 +95,6 @@ export const generateLayoutObject = (topics, synapses, focalTopicId) => {
export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoords) => {
const coords = {}
const X_GRID_SPACE = 250
const Y_GRID_SPACE = 200
const ISLAND_SPACING = 300
const traverseIsland = (island, func, parent, child) => {
func(island, parent, child)
@ -165,8 +155,6 @@ export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoord
coords[topic.id] = pos
}
// lay all of them out as if there were no other ones
layoutObject.forEach((island, index) => {
const tempPosStore = {}
@ -226,67 +214,4 @@ export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoord
export const getLayoutForData = (topics, synapses, focalTopicId, focalCoords) => {
return generateObjectCoordinates(generateLayoutObject(topics, synapses, focalTopicId), focalTopicId, focalCoords)
}
// if we've placed a node into an island, we need to NOT place it in any other islands
// Every node should only appear in one island
// the pseudo-focal node
// the top level array represents islands
// every island has some sort of 'focal' node
/*
var example = [
// the island that contains the focal node
{
id: 21,
parents: [
{
id: 25,
parents: []
},
{
id: 25,
parents: []
}
],
children: [{
id: 26,
children: []
}]
},
// all other islands should not contain children on the top level node
{
id: 21,
// parents may contain children
parents: [
{
id: 100,
parents: [
{
id: 101,
parents: [],
children: [
{
id: 103,
children: []
}
]
}
]
},
{
id: 102,
parents: []
}
]
},
{
id: 21,
parents: []
},
]
*/
}

View file

@ -46,16 +46,13 @@ const Cable = {
var topic1, topic2, node1, node2, synapse, mapping, cancel, mapper
function waitThenRenderSynapse() {
if (synapse && mapping && mapper) {
if (synapse && mapping && mapper && synapse.getTopic1() && synapse.getTopic2()) {
topic1 = synapse.getTopic1()
node1 = topic1.get('node')
topic2 = synapse.getTopic2()
node2 = topic2.get('node')
Synapse.renderSynapse(mapping, synapse, node1, node2, false)
if (Create.newSynapse.focusNode === node1) {
Engine.setFocusNode(node2)
}
Synapse.renderSynapse(mapping, synapse, node1, node2, true)
Engine.runLayout()
} else if (!cancel) {
setTimeout(waitThenRenderSynapse, 10)
}
@ -122,6 +119,7 @@ const Cable = {
}
DataModel.Synapses.remove(synapse)
DataModel.Mappings.remove(mapping)
Engine.runLayout()
}
},
topicAdded: event => {
@ -130,19 +128,19 @@ const Cable = {
// containing only the information we need to determine whether the active mapper
// can view this topic, then if we determine it can, we make a call for the full model
const t = new DataModel.Topic(event.topic)
// refactor the heck outta this, its adding wicked wait time
var topic, mapping, mapper, cancel
function waitThenRenderTopic() {
if (topic && mapping && mapper) {
Topic.renderTopic(mapping, topic, true)
Engine.runLayout()
} else if (!cancel) {
setTimeout(waitThenRenderTopic, 10)
}
}
if (t.authorizeToShow(m) && !DataModel.Topics.get(event.topic.id)) {
// refactor the heck outta this, its adding wicked wait time
var topic, mapping, mapper, cancel
function waitThenRenderTopic() {
if (topic && mapping && mapper) {
Topic.renderTopic(mapping, topic, false)
} else if (!cancel) {
setTimeout(waitThenRenderTopic, 10)
}
}
mapper = DataModel.Mappers.get(event.topic.user_id)
if (mapper === undefined) {
Mapper.get(event.topic.user_id, function(m) {
@ -206,6 +204,7 @@ const Cable = {
Control.hideNode(node.id)
DataModel.Topics.remove(topic)
DataModel.Mappings.remove(mapping)
Engine.runLayout()
}
},
messageCreated: event => {

View file

@ -407,15 +407,6 @@ console.log(codesToSwitchToIds)
if (Visualize.mGraph) Visualize.mGraph.plot()
},
updateForm: function() {
// set the draw synapse start positions
Mouse.synapseStartCoordinates = []
for (let i = Selected.Nodes.length - 1; i >= 0; i -= 1) {
const n = Selected.Nodes[i]
Mouse.synapseStartCoordinates.push({
x: n.pos.getc().x,
y: n.pos.getc().y
})
}
let pixelPos, midpoint = {}
if (Create.newSynapse.beingCreated) {
Mouse.synapseEndCoordinates = {

View file

@ -2,7 +2,7 @@
import { last, sortBy, values } from 'lodash'
import $jit from '../patched/JIT'
import { getLayoutForData } from '../ConvoAlgo'
import { getLayoutForData, X_GRID_SPACE } from '../ConvoAlgo'
import Active from './Active'
import Create from './Create'
@ -26,52 +26,42 @@ const Engine = {
},
runLayout: init => {
Visualize.mGraph.busy = true
const synapses = DataModel.Synapses.map(s => s.attributes)
const topics = DataModel.Topics.map(t => t.attributes)
const focalNodeId = Create.newSynapse.focusNode.getData('topic').id
const focalCoords = init ? { x: 0, y: 0 } : Create.newSynapse.focusNode.pos
const layout = getLayoutForData(topics, synapses, focalNodeId, focalCoords)
Visualize.mGraph.graph.eachNode(n => {
let calculatedCoords = layout[n.id]
if (!calculatedCoords) {
calculatedCoords = {x: 0, y: 0}
}
let calculatedCoords = layout[n.getData('topic').id]
const endPos = new $jit.Complex(calculatedCoords.x, calculatedCoords.y)
n.setPos(endPos, 'end')
})
Visualize.mGraph.animate({
modes: ['linear'],
transition: $jit.Trans.Elastic.easeOut,
duration: 200,
onComplete: () => {}
transition: $jit.Trans.Quart.easeOut,
duration: 500,
onComplete: () => {
Visualize.mGraph.busy = false
Create.newSynapse.updateForm()
Create.newTopic.position()
}
})
},
addNode: node => {
//Engine.runLayout()
},
removeNode: node => {
//Engine.runLayout()
},
findFocusNode: nodes => {
return last(sortBy(values(nodes), n => new Date(n.getData('topic').get('created_at'))))
},
setFocusNode: (node, init) => {
setFocusNode: (node, init, dontRun) => {
if (!Active.Mapper) return
Create.newSynapse.focusNode = node
Mouse.focusNodeCoords = node.pos
Mouse.newNodeCoords = {
x: node.pos.x + 200,
x: node.pos.x + X_GRID_SPACE,
y: node.pos.y
}
Create.newSynapse.updateForm()
Create.newTopic.position()
Engine.runLayout(init)
},
addEdge: edge => {
Engine.runLayout()
},
removeEdge: edge => {
//Engine.runLayout()
if (!dontRun) Engine.runLayout(init)
}
}

View file

@ -687,6 +687,10 @@ const JIT = {
onMouseMoveHandler: function(_node, eventInfo, e) {
const self = JIT
if (Mouse.synapseStartCoordinates.length) {
Visualize.mGraph.plot()
}
if (Visualize.mGraph.busy) return
const node = eventInfo.getNode()
@ -743,113 +747,21 @@ const JIT = {
self.handleSelectionBeforeDragging(node, e)
const pos = eventInfo.getPos()
const EDGE_THICKNESS = 30
const SHIFT = 2 / Visualize.mGraph.canvas.scaleOffsetX
const PERIOD = 5
// self.virtualPointer = pos;
// if it's a left click, or a touch, move the node
if (e.touches || (e.button === 0 && !e.altKey && !e.ctrlKey && (e.buttons === 0 || e.buttons === 1 || e.buttons === undefined))) {
const width = Visualize.mGraph.canvas.getSize().width
const height = Visualize.mGraph.canvas.getSize().height
const xPix = Util.coordsToPixels(Visualize.mGraph, pos).x
const yPix = Util.coordsToPixels(Visualize.mGraph, pos).y
if (self.dragFlag === 0) {
self.mouseDownPix = Util.coordsToPixels(Visualize.mGraph, eventInfo.getPos())
self.dragFlag = 1
}
if (Util.getDistance(Util.coordsToPixels(Visualize.mGraph, pos), self.mouseDownPix) > 2 && !self.dragTolerance) {
self.dragTolerance = 1
}
if (xPix < EDGE_THICKNESS && self.dragTolerance) {
clearInterval(self.dragLeftEdge)
clearInterval(self.dragRightEdge)
clearInterval(self.dragTopEdge)
clearInterval(self.dragBottomEdge)
self.virtualPointer = { x: Util.pixelsToCoords(Visualize.mGraph, { x: EDGE_THICKNESS, y: yPix }).x - SHIFT, y: pos.y }
Visualize.mGraph.canvas.translate(SHIFT, 0)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
self.dragLeftEdge = setInterval(function() {
self.virtualPointer = { x: Util.pixelsToCoords(Visualize.mGraph, { x: EDGE_THICKNESS, y: yPix }).x - SHIFT, y: pos.y }
Visualize.mGraph.canvas.translate(SHIFT, 0)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
}, PERIOD)
}
if (width - xPix < EDGE_THICKNESS && self.dragTolerance) {
clearInterval(self.dragLeftEdge)
clearInterval(self.dragRightEdge)
clearInterval(self.dragTopEdge)
clearInterval(self.dragBottomEdge)
self.virtualPointer = { x: Util.pixelsToCoords(Visualize.mGraph, { x: width - EDGE_THICKNESS, y: yPix }).x + SHIFT, y: pos.y }
Visualize.mGraph.canvas.translate(-SHIFT, 0)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
self.dragRightEdge = setInterval(function() {
self.virtualPointer = { x: Util.pixelsToCoords(Visualize.mGraph, { x: width - EDGE_THICKNESS, y: yPix }).x + SHIFT, y: pos.y }
Visualize.mGraph.canvas.translate(-SHIFT, 0)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
}, PERIOD)
}
if (yPix < EDGE_THICKNESS && self.dragTolerance) {
clearInterval(self.dragLeftEdge)
clearInterval(self.dragRightEdge)
clearInterval(self.dragTopEdge)
clearInterval(self.dragBottomEdge)
self.virtualPointer = { x: pos.x, y: Util.pixelsToCoords(Visualize.mGraph, { x: xPix, y: EDGE_THICKNESS }).y - SHIFT }
Visualize.mGraph.canvas.translate(0, SHIFT)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
self.dragTopEdge = setInterval(function() {
self.virtualPointer = { x: pos.x, y: Util.pixelsToCoords(Visualize.mGraph, { x: xPix, y: EDGE_THICKNESS }).y - SHIFT }
Visualize.mGraph.canvas.translate(0, SHIFT)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
}, PERIOD)
}
if (height - yPix < EDGE_THICKNESS && self.dragTolerance) {
clearInterval(self.dragLeftEdge)
clearInterval(self.dragRightEdge)
clearInterval(self.dragTopEdge)
clearInterval(self.dragBottomEdge)
self.virtualPointer = { x: pos.x, y: Util.pixelsToCoords(Visualize.mGraph, { x: xPix, y: height - EDGE_THICKNESS }).y + SHIFT }
Visualize.mGraph.canvas.translate(0, -SHIFT)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
self.dragBottomEdge = setInterval(function() {
self.virtualPointer = { x: pos.x, y: Util.pixelsToCoords(Visualize.mGraph, { x: xPix, y: height - EDGE_THICKNESS }).y + SHIFT }
Visualize.mGraph.canvas.translate(0, -SHIFT)
self.updateTopicPositions(node, self.virtualPointer)
Visualize.mGraph.plot()
}, PERIOD)
}
if (xPix >= EDGE_THICKNESS && width - xPix >= EDGE_THICKNESS && yPix >= EDGE_THICKNESS && height - yPix >= EDGE_THICKNESS) {
clearInterval(self.dragLeftEdge)
clearInterval(self.dragRightEdge)
clearInterval(self.dragTopEdge)
clearInterval(self.dragBottomEdge)
self.updateTopicPositions(node, pos)
Visualize.mGraph.plot()
}
} else if ((e.button === 2 || (e.button === 0 && e.altKey) || e.buttons === 2) && authorized) {
// if it's a right click or holding down alt, start synapse creation ->third option is for firefox
if ((e.button === 0 || e.buttons === 0) && authorized) {
// start synapse creation ->second option is for firefox
if (JIT.tempInit === false) {
JIT.tempNode = node
JIT.tempInit = true
Create.newSynapse.hide()
// set the draw synapse start positions
Mouse.synapseStartCoordinates = []
for (let i = Selected.Nodes.length - 1; i >= 0; i -= 1) {
const n = Selected.Nodes[i]
Mouse.synapseStartCoordinates.push({
x: n.pos.getc().x,
y: n.pos.getc().y
})
}
Mouse.synapseEndCoordinates = {
x: pos.x,
y: pos.y
@ -859,33 +771,25 @@ const JIT = {
let temp = eventInfo.getNode()
if (temp !== false && temp.id !== node.id && Selected.Nodes.indexOf(temp) === -1) { // this means a Node has been returned
JIT.tempNode2 = temp
Mouse.synapseEndCoordinates = {
x: JIT.tempNode2.pos.getc().x,
y: JIT.tempNode2.pos.getc().y
}
// before making the highlighted one bigger, make sure all the others are regular size
Visualize.mGraph.graph.eachNode(function(n) {
n.setData('dim', 25, 'current')
})
temp.setData('dim', 35, 'current')
Visualize.mGraph.plot()
} else if (!temp) {
JIT.tempNode2 = null
Visualize.mGraph.graph.eachNode(function(n) {
n.setData('dim', 25, 'current')
})
Visualize.mGraph.plot()
Mouse.synapseEndCoordinates = {
x: pos.x,
y: pos.y
}
Visualize.mGraph.graph.eachNode(function(n) {
n.setData('dim', 25, 'current')
})
}
} else if ((e.button === 2 || (e.button === 0 && e.altKey) || e.buttons === 2) && Active.Topic) {
GlobalUI.notifyUser('Cannot create in Topic view.')
} else if ((e.button === 2 || (e.button === 0 && e.altKey) || e.buttons === 2) && !authorized) {
GlobalUI.notifyUser('Cannot edit this map.')
}
}
}, // onDragMoveTopicHandler
@ -905,19 +809,6 @@ const JIT = {
let pixelPos
let mapping
clearInterval(self.dragLeftEdge)
clearInterval(self.dragRightEdge)
clearInterval(self.dragTopEdge)
clearInterval(self.dragBottomEdge)
delete self.dragLeftEdge
delete self.dragRightEdge
delete self.dragTopEdge
delete self.dragBottomEdge
self.dragFlag = 0
self.dragTolerance = 0
if (JIT.tempInit && JIT.tempNode2 === null) {
Mouse.synapseEndCoordinates = null
} else if (JIT.tempInit && JIT.tempNode2 !== null) {
@ -937,35 +828,6 @@ const JIT = {
JIT.tempNode = null
JIT.tempNode2 = null
JIT.tempInit = false
} else if (!JIT.tempInit && node && !node.nodeFrom) {
// this means you dragged an existing node, autosave that to the database
// check whether to save mappings
const checkWhetherToSave = function() {
const map = Active.Map
if (!map) return false
return map.authorizeToEdit(Active.Mapper)
}
if (checkWhetherToSave()) {
mapping = node.getData('mapping')
mapping.save({
xloc: node.getPos().x,
yloc: node.getPos().y
})
// also save any other selected nodes that also got dragged along
const l = Selected.Nodes.length
for (var i = l - 1; i >= 0; i -= 1) {
const n = Selected.Nodes[i]
if (n !== node) {
mapping = n.getData('mapping')
mapping.save({
xloc: n.getPos().x,
yloc: n.getPos().y
})
}
}
}
}
}, // onDragEndTopicHandler
canvasClickHandler: function(canvasLoc, e) {
@ -1257,43 +1119,19 @@ const JIT = {
// wait a certain length of time, then check again, then run this code
setTimeout(function() {
if (!JIT.nodeWasDoubleClicked()) {
var nodeAlreadySelected = node.selected
if (e.button === 1 && !e.ctrlKey) {
var len = Selected.Nodes.length
if (e.button !== 1) {
if (!e.shiftKey) {
Control.deselectAllNodes()
Control.deselectAllEdges()
}
for (let i = 0; i < len; i += 1) {
let n = Selected.Nodes[i]
let result = Util.openLink(DataModel.Topics.get(n.id).attributes.link)
if (nodeAlreadySelected) {
Control.deselectNode(node)
} else {
Control.selectNode(node, e)
}
// trigger animation to final styles
Visualize.mGraph.fx.animate({
modes: ['edge-property:lineWidth:color:alpha'],
duration: 500
})
Visualize.mGraph.plot()
} else {
if (!e.ctrlKey) {
var len = Selected.Nodes.length
for (let i = 0; i < len; i += 1) {
let n = Selected.Nodes[i]
let result = Util.openLink(DataModel.Topics.get(n.id).attributes.link)
if (!result) { // if link failed to open
break
}
}
if (!node.selected) {
Util.openLink(DataModel.Topics.get(node.id).attributes.link)
if (!result) { // if link failed to open
break
}
}
if (!node.selected) Util.openLink(DataModel.Topics.get(node.id).attributes.link)
}
}
}, Mouse.DOUBLE_CLICK_TOLERANCE)

View file

@ -12,7 +12,7 @@ const Mouse = {
synapseEndCoordinates: null,
lastNodeClick: 0,
lastCanvasClick: 0,
DOUBLE_CLICK_TOLERANCE: 300
DOUBLE_CLICK_TOLERANCE: 501
}
export default Mouse

View file

@ -29,83 +29,52 @@ const Synapse = {
} else callback(DataModel.Synapses.get(id))
},
renderSynapse: function(mapping, synapse, node1, node2, createNewInDB, alreadyAdded) {
var edgeOnViz
var newedge
if (!alreadyAdded) {
newedge = synapse.createEdge(mapping)
Visualize.mGraph.graph.addAdjacence(node1, node2, newedge.data)
}
edgeOnViz = Visualize.mGraph.graph.getAdjacence(node1.id, node2.id)
if (!alreadyAdded) {
Engine.addEdge(edgeOnViz)
}
renderSynapse: function(mapping, synapse, node1, node2, fromRemote) {
const newedge = synapse.createEdge(mapping)
Visualize.mGraph.graph.addAdjacence(node1, node2, newedge.data)
const edgeOnViz = Visualize.mGraph.graph.getAdjacence(node1.id, node2.id)
synapse.set('edge', edgeOnViz)
synapse.updateEdge() // links the synapse and the mapping to the edge
//Control.selectEdge(edgeOnViz)
var synapseSuccessCallback = function(synapseModel, response) {
if (Active.Map) {
mapping.save({ mappable_id: synapseModel.id })
}
}
if (createNewInDB) {
if (synapse.isNew()) {
synapse.save(null, {
success: synapseSuccessCallback
})
} else if (!synapse.isNew() && Active.Map) {
mapping.save(null)
}
if (!fromRemote && synapse.isNew()) {
synapse.save(null, {
success: synapseModel => Active.Map && mapping.save({ mappable_id: synapseModel.id })
})
} else if (!fromRemote && !synapse.isNew() && Active.Map) {
mapping.save()
}
},
createSynapseLocally: function(alreadyAdded, topic1id, topic2id) {
createSynapseLocally: function(topic1id, topic2id, manual) {
var self = Synapse
let topic1
let topic2
let node1
let node2
let synapse
let mapping
$(document).trigger(Map.events.editedByActiveMapper)
// for each node in this array we will create a synapse going to the position2 node.
var synapsesToCreate = []
if (alreadyAdded) {
topic2 = DataModel.Topics.get(topic2id)
node2 = topic2.get('node')
topic1 = DataModel.Topics.get(topic1id)
synapsesToCreate[0] = topic1.get('node')
}
else {
topic2 = DataModel.Topics.get(Create.newSynapse.topic2id)
node2 = topic2.get('node')
if (Selected.Nodes.length === 0) {
topic1 = DataModel.Topics.get(Create.newSynapse.topic1id)
synapsesToCreate[0] = topic1.get('node')
} else {
synapsesToCreate = Selected.Nodes
}
const synapsesToCreate = []
const topic2 = DataModel.Topics.get(topic2id)
const node2 = topic2.get('node')
if (Selected.Nodes.length === 0) {
synapsesToCreate.push(DataModel.Topics.get(topic1id).get('node'))
} else {
synapsesToCreate.concat(Selected.Nodes)
}
synapsesToCreate.forEach(node1 => {
topic1 = node1.getData('topic')
synapse = new DataModel.Synapse({
const topic1 = node1.getData('topic')
const synapse = new DataModel.Synapse({
desc: Create.newSynapse.description || '',
topic1_id: topic1.isNew() ? topic1.cid : topic1.id,
topic2_id: topic2.isNew() ? topic2.cid : topic2.id
topic1_id: topic1.id,
topic2_id: topic2.id
})
DataModel.Synapses.add(synapse)
mapping = new DataModel.Mapping({
const mapping = new DataModel.Mapping({
mappable_type: 'Synapse',
mappable_id: synapse.cid
})
DataModel.Mappings.add(mapping)
// this function also includes the creation of the synapse in the database
self.renderSynapse(mapping, synapse, node1, node2, true, alreadyAdded)
self.renderSynapse(mapping, synapse, node1, node2)
}) // for each in synapsesToCreate
Create.newSynapse.hide()
if (manual) {
Engine.runLayout()
Create.newSynapse.hide()
}
},
getSynapseFromAutocomplete: function(id) {
var self = Synapse
@ -121,7 +90,8 @@ const Synapse = {
const topic2 = DataModel.Topics.get(Create.newSynapse.topic2id)
const node2 = topic2.get('node')
Create.newSynapse.hide()
self.renderSynapse(mapping, synapse, node1, node2, true)
self.renderSynapse(mapping, synapse, node1, node2)
Engine.runLayout()
})
}
}

View file

@ -168,99 +168,66 @@ const Topic = {
})
},
renderTopic: function(mapping, topic, createNewInDB) {
var nodeOnViz
var newnode = topic.createNode()
const createSynapse = !!Create.newSynapse.focusNode && createNewInDB
renderTopic: function(mapping, topic, fromRemote) {
let nodeOnViz
const newnode = topic.createNode()
const createSynapse = !!Create.newSynapse.focusNode && !fromRemote
const connectToId = createSynapse ? Create.newSynapse.focusNode.getData('topic').id : null
if (!$.isEmptyObject(Visualize.mGraph.graph.nodes)) {
// this will also add the new node
if (createSynapse) Visualize.mGraph.graph.addAdjacence(Create.newSynapse.focusNode, newnode)
else Visualize.mGraph.graph.addNode(newnode)
nodeOnViz = Visualize.mGraph.graph.getNode(newnode.id)
Engine.addNode(nodeOnViz)
if (createSynapse) Engine.addEdge(Visualize.mGraph.graph.getAdjacence(Create.newSynapse.focusNode.id, nodeOnViz.id))
topic.set('node', nodeOnViz, {silent: true})
topic.updateNode() // links the topic and the mapping to the node
if (createNewInDB) Engine.setFocusNode(nodeOnViz) // means this user created it
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')
Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500
})
Visualize.mGraph.graph.addNode(newnode)
} else {
Engine.run()
Visualize.mGraph.loadJSON(newnode)
nodeOnViz = Visualize.mGraph.graph.getNode(newnode.id)
Engine.addNode(nodeOnViz)
topic.set('node', nodeOnViz, {silent: true})
topic.updateNode() // links the topic and the mapping to the node
Engine.setFocusNode(nodeOnViz)
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')
Visualize.mGraph.fx.plotNode(nodeOnViz, Visualize.mGraph.canvas)
Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 500
}
nodeOnViz = 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')
Visualize.mGraph.fx.plotNode(nodeOnViz, Visualize.mGraph.canvas)
Visualize.mGraph.fx.animate({
modes: ['node-property:dim'],
duration: 200
})
if (!fromRemote && topic.isNew()) {
topic.save(null, {
success: topicModel => {
Active.Map && mapping.save({ mappable_id: topicModel.id })
createSynapse && Synapse.createSynapseLocally(connectToId, topicModel.id)
}
})
}
var topicSuccessCallback = function(topicModel, response) {
if (Active.Map) {
mapping.save({ mappable_id: topicModel.id })
}
createSynapse && Synapse.createSynapseLocally(true, connectToId, topicModel.id)
}
if (createNewInDB) {
if (topic.isNew()) {
topic.save(null, {
success: topicSuccessCallback
})
} else if (!topic.isNew() && Active.Map) {
mapping.save(null)
}
} else if (!fromRemote && !topic.isNew()) {
Active.Map && mapping.save()
createSynapse && Synapse.createSynapseLocally(connectToId, topic.id)
}
},
createTopicLocally: function() {
var self = Topic
if (Create.newTopic.name === '') {
GlobalUI.notifyUser('Please enter a topic title...')
return
}
$(document).trigger(Map.events.editedByActiveMapper)
var metacode = DataModel.Metacodes.get(Create.newTopic.metacode)
var topic = new DataModel.Topic({
name: Create.newTopic.name,
metacode_id: metacode.id,
defer_to_map_id: Active.Map.id
})
DataModel.Topics.add(topic)
var mapping = new DataModel.Mapping({
xloc: Mouse.newNodeCoords.x,
xloc: Mouse.newNodeCoords.x,
yloc: Mouse.newNodeCoords.y,
mappable_id: topic.cid,
mappable_type: 'Topic'
})
DataModel.Mappings.add(mapping)
// these can't happen until the value is retrieved, which happens in the line above
// these can't happen until the new topic values are retrieved
Create.newTopic.reset()
self.renderTopic(mapping, topic, true) // this function also includes the creation of the topic in the database
self.renderTopic(mapping, topic)
Engine.setFocusNode(topic.get('node'), false, true)
},
getTopicFromAutocomplete: function(id) {
var self = Topic
@ -274,14 +241,13 @@ const Topic = {
mappable_id: topic.id
})
DataModel.Mappings.add(mapping)
self.renderTopic(mapping, topic, true)
self.renderTopic(mapping, topic)
Engine.setFocusNode(topic.get('node'), false, true)
})
},
getMapFromAutocomplete: function(data) {
var self = Topic
$(document).trigger(Map.events.editedByActiveMapper)
var metacode = DataModel.Metacodes.findWhere({ name: 'Metamap' })
var topic = new DataModel.Topic({
name: data.name,
@ -290,7 +256,6 @@ const Topic = {
link: window.location.origin + '/maps/' + data.id
})
DataModel.Topics.add(topic)
var mapping = new DataModel.Mapping({
xloc: Mouse.newNodeCoords.x,
yloc: Mouse.newNodeCoords.y,
@ -298,17 +263,13 @@ const Topic = {
mappable_type: 'Topic'
})
DataModel.Mappings.add(mapping)
// these can't happen until the value is retrieved, which happens in the line above
Create.newTopic.reset()
self.renderTopic(mapping, topic, true) // this function also includes the creation of the topic in the database
self.renderTopic(mapping, topic)
Engine.setFocusNode(topic.get('node'), false, true)
},
getTopicFromSearch: function(event, id) {
var self = Topic
$(document).trigger(Map.events.editedByActiveMapper)
self.get(id, (topic) => {
var nextCoords = AutoLayout.getNextCoord({ mappings: DataModel.Mappings })
var mapping = new DataModel.Mapping({
@ -318,10 +279,10 @@ const Topic = {
mappable_id: topic.id
})
DataModel.Mappings.add(mapping)
self.renderTopic(mapping, topic, true)
self.renderTopic(mapping, topic)
Engine.runLayout()
GlobalUI.notifyUser('Topic was added to your map')
})
event.stopPropagation()
event.preventDefault()
return false

View file

@ -2564,6 +2564,7 @@ Extras.Classes.Navigation = new Class({
x: eventInfo.getPos().x,
y: eventInfo.getPos().y
}
Metamaps.Visualize.mGraph.plot()
//console.log('mouse move');
return;
}