got topic and synapse creation working
This commit is contained in:
parent
04036882ab
commit
74dd20f02e
10 changed files with 189 additions and 456 deletions
58
frontend/src/ConvoAlgo/exampleObject.js
Normal file
58
frontend/src/ConvoAlgo/exampleObject.js
Normal 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: []
|
||||
},
|
||||
]
|
||||
*/
|
|
@ -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: []
|
||||
},
|
||||
]
|
||||
*/
|
||||
}
|
|
@ -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 => {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -12,7 +12,7 @@ const Mouse = {
|
|||
synapseEndCoordinates: null,
|
||||
lastNodeClick: 0,
|
||||
lastCanvasClick: 0,
|
||||
DOUBLE_CLICK_TOLERANCE: 300
|
||||
DOUBLE_CLICK_TOLERANCE: 501
|
||||
}
|
||||
|
||||
export default Mouse
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue