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' import { findIndex, orderBy } from 'lodash'
// an array of synapses
// an array of topics
// a focal node
/* /*
step 1 step 1
generate an object/array that represents the intended layout generate an object/array that represents the intended layout
@ -13,18 +8,16 @@ generate an object/array that represents the intended layout
step 2 step 2
generate x,y coordinates for every topic in the layout object 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 isEven = n => n % 2 === 0
const isOdd = n => Math.abs(n % 2) === 1 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) => { export const generateLayoutObject = (topics, synapses, focalTopicId) => {
let layout = [] // will be the final output let layout = [] // will be the final output
@ -102,9 +95,6 @@ export const generateLayoutObject = (topics, synapses, focalTopicId) => {
export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoords) => { export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoords) => {
const coords = {} const coords = {}
const X_GRID_SPACE = 250
const Y_GRID_SPACE = 200
const ISLAND_SPACING = 300
const traverseIsland = (island, func, parent, child) => { const traverseIsland = (island, func, parent, child) => {
func(island, parent, child) func(island, parent, child)
@ -165,8 +155,6 @@ export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoord
coords[topic.id] = pos coords[topic.id] = pos
} }
// lay all of them out as if there were no other ones // lay all of them out as if there were no other ones
layoutObject.forEach((island, index) => { layoutObject.forEach((island, index) => {
const tempPosStore = {} const tempPosStore = {}
@ -226,67 +214,4 @@ export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoord
export const getLayoutForData = (topics, synapses, focalTopicId, focalCoords) => { export const getLayoutForData = (topics, synapses, focalTopicId, focalCoords) => {
return generateObjectCoordinates(generateLayoutObject(topics, synapses, focalTopicId), 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 var topic1, topic2, node1, node2, synapse, mapping, cancel, mapper
function waitThenRenderSynapse() { function waitThenRenderSynapse() {
if (synapse && mapping && mapper) { if (synapse && mapping && mapper && synapse.getTopic1() && synapse.getTopic2()) {
topic1 = synapse.getTopic1() topic1 = synapse.getTopic1()
node1 = topic1.get('node') node1 = topic1.get('node')
topic2 = synapse.getTopic2() topic2 = synapse.getTopic2()
node2 = topic2.get('node') node2 = topic2.get('node')
Synapse.renderSynapse(mapping, synapse, node1, node2, true)
Synapse.renderSynapse(mapping, synapse, node1, node2, false) Engine.runLayout()
if (Create.newSynapse.focusNode === node1) {
Engine.setFocusNode(node2)
}
} else if (!cancel) { } else if (!cancel) {
setTimeout(waitThenRenderSynapse, 10) setTimeout(waitThenRenderSynapse, 10)
} }
@ -122,6 +119,7 @@ const Cable = {
} }
DataModel.Synapses.remove(synapse) DataModel.Synapses.remove(synapse)
DataModel.Mappings.remove(mapping) DataModel.Mappings.remove(mapping)
Engine.runLayout()
} }
}, },
topicAdded: event => { topicAdded: event => {
@ -130,19 +128,19 @@ const Cable = {
// containing only the information we need to determine whether the active mapper // 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 // 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) 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)) { 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) mapper = DataModel.Mappers.get(event.topic.user_id)
if (mapper === undefined) { if (mapper === undefined) {
Mapper.get(event.topic.user_id, function(m) { Mapper.get(event.topic.user_id, function(m) {
@ -206,6 +204,7 @@ const Cable = {
Control.hideNode(node.id) Control.hideNode(node.id)
DataModel.Topics.remove(topic) DataModel.Topics.remove(topic)
DataModel.Mappings.remove(mapping) DataModel.Mappings.remove(mapping)
Engine.runLayout()
} }
}, },
messageCreated: event => { messageCreated: event => {

View file

@ -407,15 +407,6 @@ console.log(codesToSwitchToIds)
if (Visualize.mGraph) Visualize.mGraph.plot() if (Visualize.mGraph) Visualize.mGraph.plot()
}, },
updateForm: function() { 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 = {} let pixelPos, midpoint = {}
if (Create.newSynapse.beingCreated) { if (Create.newSynapse.beingCreated) {
Mouse.synapseEndCoordinates = { Mouse.synapseEndCoordinates = {

View file

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

View file

@ -687,6 +687,10 @@ const JIT = {
onMouseMoveHandler: function(_node, eventInfo, e) { onMouseMoveHandler: function(_node, eventInfo, e) {
const self = JIT const self = JIT
if (Mouse.synapseStartCoordinates.length) {
Visualize.mGraph.plot()
}
if (Visualize.mGraph.busy) return if (Visualize.mGraph.busy) return
const node = eventInfo.getNode() const node = eventInfo.getNode()
@ -743,113 +747,21 @@ const JIT = {
self.handleSelectionBeforeDragging(node, e) self.handleSelectionBeforeDragging(node, e)
const pos = eventInfo.getPos() const pos = eventInfo.getPos()
const EDGE_THICKNESS = 30 if ((e.button === 0 || e.buttons === 0) && authorized) {
const SHIFT = 2 / Visualize.mGraph.canvas.scaleOffsetX // start synapse creation ->second option is for firefox
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 (JIT.tempInit === false) { if (JIT.tempInit === false) {
JIT.tempNode = node JIT.tempNode = node
JIT.tempInit = true JIT.tempInit = true
Create.newSynapse.hide() 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 = { Mouse.synapseEndCoordinates = {
x: pos.x, x: pos.x,
y: pos.y y: pos.y
@ -859,33 +771,25 @@ const JIT = {
let temp = eventInfo.getNode() let temp = eventInfo.getNode()
if (temp !== false && temp.id !== node.id && Selected.Nodes.indexOf(temp) === -1) { // this means a Node has been returned if (temp !== false && temp.id !== node.id && Selected.Nodes.indexOf(temp) === -1) { // this means a Node has been returned
JIT.tempNode2 = temp JIT.tempNode2 = temp
Mouse.synapseEndCoordinates = { Mouse.synapseEndCoordinates = {
x: JIT.tempNode2.pos.getc().x, x: JIT.tempNode2.pos.getc().x,
y: JIT.tempNode2.pos.getc().y y: JIT.tempNode2.pos.getc().y
} }
// before making the highlighted one bigger, make sure all the others are regular size // before making the highlighted one bigger, make sure all the others are regular size
Visualize.mGraph.graph.eachNode(function(n) { Visualize.mGraph.graph.eachNode(function(n) {
n.setData('dim', 25, 'current') n.setData('dim', 25, 'current')
}) })
temp.setData('dim', 35, 'current') temp.setData('dim', 35, 'current')
Visualize.mGraph.plot()
} else if (!temp) { } else if (!temp) {
JIT.tempNode2 = null JIT.tempNode2 = null
Visualize.mGraph.graph.eachNode(function(n) {
n.setData('dim', 25, 'current')
})
Visualize.mGraph.plot()
Mouse.synapseEndCoordinates = { Mouse.synapseEndCoordinates = {
x: pos.x, x: pos.x,
y: pos.y 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 }, // onDragMoveTopicHandler
@ -905,19 +809,6 @@ const JIT = {
let pixelPos let pixelPos
let mapping 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) { if (JIT.tempInit && JIT.tempNode2 === null) {
Mouse.synapseEndCoordinates = null Mouse.synapseEndCoordinates = null
} else if (JIT.tempInit && JIT.tempNode2 !== null) { } else if (JIT.tempInit && JIT.tempNode2 !== null) {
@ -937,35 +828,6 @@ const JIT = {
JIT.tempNode = null JIT.tempNode = null
JIT.tempNode2 = null JIT.tempNode2 = null
JIT.tempInit = false 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 }, // onDragEndTopicHandler
canvasClickHandler: function(canvasLoc, e) { canvasClickHandler: function(canvasLoc, e) {
@ -1257,43 +1119,19 @@ const JIT = {
// wait a certain length of time, then check again, then run this code // wait a certain length of time, then check again, then run this code
setTimeout(function() { setTimeout(function() {
if (!JIT.nodeWasDoubleClicked()) { if (!JIT.nodeWasDoubleClicked()) {
var nodeAlreadySelected = node.selected if (e.button === 1 && !e.ctrlKey) {
var len = Selected.Nodes.length
if (e.button !== 1) { for (let i = 0; i < len; i += 1) {
if (!e.shiftKey) { let n = Selected.Nodes[i]
Control.deselectAllNodes() let result = Util.openLink(DataModel.Topics.get(n.id).attributes.link)
Control.deselectAllEdges()
}
if (nodeAlreadySelected) { if (!result) { // if link failed to open
Control.deselectNode(node) break
} 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 (!node.selected) Util.openLink(DataModel.Topics.get(node.id).attributes.link)
} }
} }
}, Mouse.DOUBLE_CLICK_TOLERANCE) }, Mouse.DOUBLE_CLICK_TOLERANCE)

View file

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

View file

@ -29,83 +29,52 @@ const Synapse = {
} else callback(DataModel.Synapses.get(id)) } else callback(DataModel.Synapses.get(id))
}, },
renderSynapse: function(mapping, synapse, node1, node2, createNewInDB, alreadyAdded) { renderSynapse: function(mapping, synapse, node1, node2, fromRemote) {
var edgeOnViz const newedge = synapse.createEdge(mapping)
var newedge Visualize.mGraph.graph.addAdjacence(node1, node2, newedge.data)
const edgeOnViz = Visualize.mGraph.graph.getAdjacence(node1.id, node2.id)
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)
}
synapse.set('edge', edgeOnViz) synapse.set('edge', edgeOnViz)
synapse.updateEdge() // links the synapse and the mapping to the edge synapse.updateEdge() // links the synapse and the mapping to the edge
if (!fromRemote && synapse.isNew()) {
//Control.selectEdge(edgeOnViz) synapse.save(null, {
success: synapseModel => Active.Map && mapping.save({ mappable_id: synapseModel.id })
var synapseSuccessCallback = function(synapseModel, response) { })
if (Active.Map) { } else if (!fromRemote && !synapse.isNew() && Active.Map) {
mapping.save({ mappable_id: synapseModel.id }) mapping.save()
}
}
if (createNewInDB) {
if (synapse.isNew()) {
synapse.save(null, {
success: synapseSuccessCallback
})
} else if (!synapse.isNew() && Active.Map) {
mapping.save(null)
}
} }
}, },
createSynapseLocally: function(alreadyAdded, topic1id, topic2id) { createSynapseLocally: function(topic1id, topic2id, manual) {
var self = Synapse var self = Synapse
let topic1
let topic2
let node1
let node2
let synapse
let mapping
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
// for each node in this array we will create a synapse going to the position2 node. // for each node in this array we will create a synapse going to the position2 node.
var synapsesToCreate = [] const synapsesToCreate = []
if (alreadyAdded) { const topic2 = DataModel.Topics.get(topic2id)
topic2 = DataModel.Topics.get(topic2id) const node2 = topic2.get('node')
node2 = topic2.get('node') if (Selected.Nodes.length === 0) {
topic1 = DataModel.Topics.get(topic1id) synapsesToCreate.push(DataModel.Topics.get(topic1id).get('node'))
synapsesToCreate[0] = topic1.get('node') } else {
} synapsesToCreate.concat(Selected.Nodes)
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
}
} }
synapsesToCreate.forEach(node1 => { synapsesToCreate.forEach(node1 => {
topic1 = node1.getData('topic') const topic1 = node1.getData('topic')
synapse = new DataModel.Synapse({ const synapse = new DataModel.Synapse({
desc: Create.newSynapse.description || '', desc: Create.newSynapse.description || '',
topic1_id: topic1.isNew() ? topic1.cid : topic1.id, topic1_id: topic1.id,
topic2_id: topic2.isNew() ? topic2.cid : topic2.id topic2_id: topic2.id
}) })
DataModel.Synapses.add(synapse) DataModel.Synapses.add(synapse)
mapping = new DataModel.Mapping({ const mapping = new DataModel.Mapping({
mappable_type: 'Synapse', mappable_type: 'Synapse',
mappable_id: synapse.cid mappable_id: synapse.cid
}) })
DataModel.Mappings.add(mapping) DataModel.Mappings.add(mapping)
// this function also includes the creation of the synapse in the database // 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 }) // for each in synapsesToCreate
Create.newSynapse.hide() if (manual) {
Engine.runLayout()
Create.newSynapse.hide()
}
}, },
getSynapseFromAutocomplete: function(id) { getSynapseFromAutocomplete: function(id) {
var self = Synapse var self = Synapse
@ -121,7 +90,8 @@ const Synapse = {
const topic2 = DataModel.Topics.get(Create.newSynapse.topic2id) const topic2 = DataModel.Topics.get(Create.newSynapse.topic2id)
const node2 = topic2.get('node') const node2 = topic2.get('node')
Create.newSynapse.hide() 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) { renderTopic: function(mapping, topic, fromRemote) {
var nodeOnViz let nodeOnViz
var newnode = topic.createNode() const newnode = topic.createNode()
const createSynapse = !!Create.newSynapse.focusNode && createNewInDB const createSynapse = !!Create.newSynapse.focusNode && !fromRemote
const connectToId = createSynapse ? Create.newSynapse.focusNode.getData('topic').id : null const connectToId = createSynapse ? Create.newSynapse.focusNode.getData('topic').id : null
if (!$.isEmptyObject(Visualize.mGraph.graph.nodes)) { if (!$.isEmptyObject(Visualize.mGraph.graph.nodes)) {
// this will also add the new node Visualize.mGraph.graph.addNode(newnode)
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
})
} else { } else {
Engine.run()
Visualize.mGraph.loadJSON(newnode) Visualize.mGraph.loadJSON(newnode)
nodeOnViz = Visualize.mGraph.graph.getNode(newnode.id) }
Engine.addNode(nodeOnViz) nodeOnViz = Visualize.mGraph.graph.getNode(newnode.id)
topic.set('node', nodeOnViz, {silent: true}) topic.set('node', nodeOnViz, {silent: true})
topic.updateNode() // links the topic and the mapping to the node topic.updateNode() // links the topic and the mapping to the node
Engine.setFocusNode(nodeOnViz) nodeOnViz.setData('dim', 1, 'start')
nodeOnViz.setData('dim', 1, 'start') nodeOnViz.setData('dim', 25, 'end')
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')), 'current') nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'start')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'start') nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'end')
nodeOnViz.setPos(new $jit.Complex(mapping.get('xloc'), mapping.get('yloc')), 'end') Visualize.mGraph.fx.plotNode(nodeOnViz, Visualize.mGraph.canvas)
Visualize.mGraph.fx.plotNode(nodeOnViz, Visualize.mGraph.canvas) Visualize.mGraph.fx.animate({
Visualize.mGraph.fx.animate({ modes: ['node-property:dim'],
modes: ['node-property:dim'], duration: 200
duration: 500 })
if (!fromRemote && topic.isNew()) {
topic.save(null, {
success: topicModel => {
Active.Map && mapping.save({ mappable_id: topicModel.id })
createSynapse && Synapse.createSynapseLocally(connectToId, topicModel.id)
}
}) })
} } else if (!fromRemote && !topic.isNew()) {
Active.Map && mapping.save()
var topicSuccessCallback = function(topicModel, response) { createSynapse && Synapse.createSynapseLocally(connectToId, topic.id)
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)
}
} }
}, },
createTopicLocally: function() { createTopicLocally: function() {
var self = Topic var self = Topic
if (Create.newTopic.name === '') { if (Create.newTopic.name === '') {
GlobalUI.notifyUser('Please enter a topic title...') GlobalUI.notifyUser('Please enter a topic title...')
return return
} }
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
var metacode = DataModel.Metacodes.get(Create.newTopic.metacode) var metacode = DataModel.Metacodes.get(Create.newTopic.metacode)
var topic = new DataModel.Topic({ var topic = new DataModel.Topic({
name: Create.newTopic.name, name: Create.newTopic.name,
metacode_id: metacode.id, metacode_id: metacode.id,
defer_to_map_id: Active.Map.id defer_to_map_id: Active.Map.id
}) })
DataModel.Topics.add(topic) DataModel.Topics.add(topic)
var mapping = new DataModel.Mapping({ var mapping = new DataModel.Mapping({
xloc: Mouse.newNodeCoords.x, xloc: Mouse.newNodeCoords.x,
yloc: Mouse.newNodeCoords.y, yloc: Mouse.newNodeCoords.y,
mappable_id: topic.cid, mappable_id: topic.cid,
mappable_type: 'Topic' mappable_type: 'Topic'
}) })
DataModel.Mappings.add(mapping) DataModel.Mappings.add(mapping)
// these can't happen until the new topic values are retrieved
// these can't happen until the value is retrieved, which happens in the line above
Create.newTopic.reset() Create.newTopic.reset()
self.renderTopic(mapping, topic)
self.renderTopic(mapping, topic, true) // this function also includes the creation of the topic in the database Engine.setFocusNode(topic.get('node'), false, true)
}, },
getTopicFromAutocomplete: function(id) { getTopicFromAutocomplete: function(id) {
var self = Topic var self = Topic
@ -274,14 +241,13 @@ const Topic = {
mappable_id: topic.id mappable_id: topic.id
}) })
DataModel.Mappings.add(mapping) DataModel.Mappings.add(mapping)
self.renderTopic(mapping, topic, true) self.renderTopic(mapping, topic)
Engine.setFocusNode(topic.get('node'), false, true)
}) })
}, },
getMapFromAutocomplete: function(data) { getMapFromAutocomplete: function(data) {
var self = Topic var self = Topic
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
var metacode = DataModel.Metacodes.findWhere({ name: 'Metamap' }) var metacode = DataModel.Metacodes.findWhere({ name: 'Metamap' })
var topic = new DataModel.Topic({ var topic = new DataModel.Topic({
name: data.name, name: data.name,
@ -290,7 +256,6 @@ const Topic = {
link: window.location.origin + '/maps/' + data.id link: window.location.origin + '/maps/' + data.id
}) })
DataModel.Topics.add(topic) DataModel.Topics.add(topic)
var mapping = new DataModel.Mapping({ var mapping = new DataModel.Mapping({
xloc: Mouse.newNodeCoords.x, xloc: Mouse.newNodeCoords.x,
yloc: Mouse.newNodeCoords.y, yloc: Mouse.newNodeCoords.y,
@ -298,17 +263,13 @@ const Topic = {
mappable_type: 'Topic' mappable_type: 'Topic'
}) })
DataModel.Mappings.add(mapping) DataModel.Mappings.add(mapping)
// these can't happen until the value is retrieved, which happens in the line above
Create.newTopic.reset() Create.newTopic.reset()
self.renderTopic(mapping, topic)
self.renderTopic(mapping, topic, true) // this function also includes the creation of the topic in the database Engine.setFocusNode(topic.get('node'), false, true)
}, },
getTopicFromSearch: function(event, id) { getTopicFromSearch: function(event, id) {
var self = Topic var self = Topic
$(document).trigger(Map.events.editedByActiveMapper) $(document).trigger(Map.events.editedByActiveMapper)
self.get(id, (topic) => { self.get(id, (topic) => {
var nextCoords = AutoLayout.getNextCoord({ mappings: DataModel.Mappings }) var nextCoords = AutoLayout.getNextCoord({ mappings: DataModel.Mappings })
var mapping = new DataModel.Mapping({ var mapping = new DataModel.Mapping({
@ -318,10 +279,10 @@ const Topic = {
mappable_id: topic.id mappable_id: topic.id
}) })
DataModel.Mappings.add(mapping) DataModel.Mappings.add(mapping)
self.renderTopic(mapping, topic, true) self.renderTopic(mapping, topic)
Engine.runLayout()
GlobalUI.notifyUser('Topic was added to your map') GlobalUI.notifyUser('Topic was added to your map')
}) })
event.stopPropagation() event.stopPropagation()
event.preventDefault() event.preventDefault()
return false return false

View file

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