added ability to use touch to drag nodes, pan, and zoom. fixed label glitch for the most part
This commit is contained in:
parent
86895836a0
commit
1f7588f1ce
9 changed files with 192 additions and 22 deletions
4
Gemfile
4
Gemfile
|
@ -13,8 +13,8 @@ gem 'formtastic'
|
||||||
gem 'json'
|
gem 'json'
|
||||||
gem 'rails3-jquery-autocomplete'
|
gem 'rails3-jquery-autocomplete'
|
||||||
gem 'best_in_place'
|
gem 'best_in_place'
|
||||||
gem 'therubyracer' #optional
|
#gem 'therubyracer' #optional
|
||||||
gem 'rb-readline'
|
#gem 'rb-readline'
|
||||||
|
|
||||||
# Gems used only for assets and not required
|
# Gems used only for assets and not required
|
||||||
# in production environments by default.
|
# in production environments by default.
|
||||||
|
|
|
@ -60,7 +60,6 @@ GEM
|
||||||
railties (>= 3.1.0, < 5.0)
|
railties (>= 3.1.0, < 5.0)
|
||||||
thor (~> 0.14)
|
thor (~> 0.14)
|
||||||
json (1.7.6)
|
json (1.7.6)
|
||||||
libv8 (3.11.8.13)
|
|
||||||
mail (2.4.4)
|
mail (2.4.4)
|
||||||
i18n (>= 0.4.0)
|
i18n (>= 0.4.0)
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
|
@ -95,10 +94,8 @@ GEM
|
||||||
rdoc (~> 3.4)
|
rdoc (~> 3.4)
|
||||||
thor (>= 0.14.6, < 2.0)
|
thor (>= 0.14.6, < 2.0)
|
||||||
rake (10.0.3)
|
rake (10.0.3)
|
||||||
rb-readline (0.4.2)
|
|
||||||
rdoc (3.12)
|
rdoc (3.12)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
ref (1.0.2)
|
|
||||||
sass (3.2.1)
|
sass (3.2.1)
|
||||||
sass-rails (3.2.5)
|
sass-rails (3.2.5)
|
||||||
railties (~> 3.2.0)
|
railties (~> 3.2.0)
|
||||||
|
@ -109,9 +106,6 @@ GEM
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
therubyracer (0.11.4)
|
|
||||||
libv8 (~> 3.11.8.12)
|
|
||||||
ref
|
|
||||||
thor (0.16.0)
|
thor (0.16.0)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
treetop (1.4.12)
|
treetop (1.4.12)
|
||||||
|
@ -139,7 +133,5 @@ DEPENDENCIES
|
||||||
pg
|
pg
|
||||||
rails (= 3.2.11)
|
rails (= 3.2.11)
|
||||||
rails3-jquery-autocomplete
|
rails3-jquery-autocomplete
|
||||||
rb-readline
|
|
||||||
sass-rails (~> 3.2.3)
|
sass-rails (~> 3.2.3)
|
||||||
therubyracer
|
|
||||||
uglifier (>= 1.0.3)
|
uglifier (>= 1.0.3)
|
||||||
|
|
46
Gemfile~
Normal file
46
Gemfile~
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'rails', '3.2.11'
|
||||||
|
|
||||||
|
# Bundle edge Rails instead:
|
||||||
|
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
||||||
|
|
||||||
|
gem 'pg'
|
||||||
|
gem 'authlogic'
|
||||||
|
gem 'cancan'
|
||||||
|
gem 'formula'
|
||||||
|
gem 'formtastic'
|
||||||
|
gem 'json'
|
||||||
|
gem 'rails3-jquery-autocomplete'
|
||||||
|
gem 'best_in_place'
|
||||||
|
#gem 'therubyracer' #optional
|
||||||
|
gem 'rb-readline'
|
||||||
|
|
||||||
|
# Gems used only for assets and not required
|
||||||
|
# in production environments by default.
|
||||||
|
group :assets do
|
||||||
|
gem 'sass-rails', '~> 3.2.3'
|
||||||
|
gem 'coffee-rails', '~> 3.2.1'
|
||||||
|
|
||||||
|
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||||
|
# gem 'therubyracer'
|
||||||
|
|
||||||
|
gem 'uglifier', '>= 1.0.3'
|
||||||
|
end
|
||||||
|
|
||||||
|
gem 'jquery-rails', '2.1.2'
|
||||||
|
|
||||||
|
# To use ActiveModel has_secure_password
|
||||||
|
# gem 'bcrypt-ruby', '~> 3.0.0'
|
||||||
|
|
||||||
|
# To use Jbuilder templates for JSON
|
||||||
|
gem 'jbuilder'
|
||||||
|
|
||||||
|
# Use unicorn as the web server
|
||||||
|
# gem 'unicorn'
|
||||||
|
|
||||||
|
# Deploy with Capistrano
|
||||||
|
# gem 'capistrano'
|
||||||
|
|
||||||
|
# To use debugger
|
||||||
|
# gem 'ruby-debug19', :require => 'ruby-debug'
|
|
@ -160,8 +160,8 @@ function onDragMoveTopicHandler(node, eventInfo, e) {
|
||||||
$('#new_synapse').fadeOut('fast');
|
$('#new_synapse').fadeOut('fast');
|
||||||
$('#new_topic').fadeOut('fast');
|
$('#new_topic').fadeOut('fast');
|
||||||
var pos = eventInfo.getPos();
|
var pos = eventInfo.getPos();
|
||||||
// if it's a left click, move the node
|
// if it's a left click, or a touch, move the node
|
||||||
if (e.button == 0 && !e.altKey && (e.buttons == 0 || e.buttons == 1 || e.buttons == undefined)) {
|
if ( e.touches || (e.button == 0 && !e.altKey && (e.buttons == 0 || e.buttons == 1 || e.buttons == undefined))) {
|
||||||
//if the node dragged isn't already selected, select it
|
//if the node dragged isn't already selected, select it
|
||||||
var whatToDo = handleSelectionBeforeDragging(node, e);
|
var whatToDo = handleSelectionBeforeDragging(node, e);
|
||||||
if (whatToDo == 'only-drag-this-one') {
|
if (whatToDo == 'only-drag-this-one') {
|
||||||
|
@ -235,3 +235,63 @@ function onDragMoveTopicHandler(node, eventInfo, e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastDist = 0;
|
||||||
|
|
||||||
|
function getDistance(p1, p2) {
|
||||||
|
return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function touchPanZoomHandler(eventInfo, e) {
|
||||||
|
if (e.touches.length == 1) {
|
||||||
|
var thispos = touchPos,
|
||||||
|
currentPos = eventInfo.getPos(),
|
||||||
|
canvas = Mconsole.canvas,
|
||||||
|
ox = canvas.translateOffsetX,
|
||||||
|
oy = canvas.translateOffsetY,
|
||||||
|
sx = canvas.scaleOffsetX,
|
||||||
|
sy = canvas.scaleOffsetY;
|
||||||
|
currentPos.x *= sx;
|
||||||
|
currentPos.y *= sy;
|
||||||
|
currentPos.x += ox;
|
||||||
|
currentPos.y += oy;
|
||||||
|
//var x = currentPos.x - thispos.x,
|
||||||
|
// y = currentPos.y - thispos.y;
|
||||||
|
var x = currentPos.x - thispos.x,
|
||||||
|
y = currentPos.y - thispos.y;
|
||||||
|
touchPos = currentPos;
|
||||||
|
Mconsole.canvas.translate(x * 1/sx, y * 1/sy);
|
||||||
|
}
|
||||||
|
else if (e.touches.length == 2) {
|
||||||
|
var touch1 = e.touches[0];
|
||||||
|
var touch2 = e.touches[1];
|
||||||
|
|
||||||
|
var dist = getDistance({
|
||||||
|
x: touch1.clientX,
|
||||||
|
y: touch1.clientY
|
||||||
|
}, {
|
||||||
|
x: touch2.clientX,
|
||||||
|
y: touch2.clientY
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!lastDist) {
|
||||||
|
lastDist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
var scale = dist / lastDist;
|
||||||
|
|
||||||
|
console.log(scale);
|
||||||
|
|
||||||
|
if (8 >= Mconsole.canvas.scaleOffsetX*scale && Mconsole.canvas.scaleOffsetX*scale >= 1) {
|
||||||
|
Mconsole.canvas.scale(scale, scale);
|
||||||
|
}
|
||||||
|
if (Mconsole.canvas.scaleOffsetX < 0.5) {
|
||||||
|
Mconsole.canvas.viz.labels.hideLabels(true);
|
||||||
|
}
|
||||||
|
else if (Mconsole.canvas.scaleOffsetX > 0.5) {
|
||||||
|
Mconsole.canvas.viz.labels.hideLabels(false);
|
||||||
|
}
|
||||||
|
lastDist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -67,16 +67,52 @@ function graphSettings(type, embed) {
|
||||||
onDragCancelHandler(node, eventInfo, e, false);
|
onDragCancelHandler(node, eventInfo, e, false);
|
||||||
},
|
},
|
||||||
//Implement the same handler for touchscreens
|
//Implement the same handler for touchscreens
|
||||||
|
onTouchStart: function (node, eventInfo, e) {
|
||||||
|
//$jit.util.event.stop(e); //stop default touchmove event
|
||||||
|
//Mconsole.events.onMouseDown(e, null, eventInfo);
|
||||||
|
Mconsole.events.touched = true;
|
||||||
|
touchPos = eventInfo.getPos();
|
||||||
|
var canvas = Mconsole.canvas,
|
||||||
|
ox = canvas.translateOffsetX;
|
||||||
|
oy = canvas.translateOffsetY,
|
||||||
|
sx = canvas.scaleOffsetX,
|
||||||
|
sy = canvas.scaleOffsetY;
|
||||||
|
touchPos.x *= sx;
|
||||||
|
touchPos.y *= sy;
|
||||||
|
touchPos.x += ox;
|
||||||
|
touchPos.y += oy;
|
||||||
|
|
||||||
|
touchDragNode = node;
|
||||||
|
},
|
||||||
|
//Implement the same handler for touchscreens
|
||||||
onTouchMove: function (node, eventInfo, e) {
|
onTouchMove: function (node, eventInfo, e) {
|
||||||
$jit.util.event.stop(e); //stop default touchmove event
|
if (touchDragNode) onDragMoveTopicHandler(touchDragNode, eventInfo, e);
|
||||||
this.onDragMove(node, eventInfo, e);
|
else {
|
||||||
|
touchPanZoomHandler(eventInfo, e);
|
||||||
|
$('#topic_' + MetamapsModel.showcardInUse + '_label').hide();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//Implement the same handler for touchscreens
|
||||||
|
onTouchEnd: function (node, eventInfo, e) {
|
||||||
|
//clicking on a node, or clicking on blank part of canvas?
|
||||||
|
if (node.nodeFrom) {
|
||||||
|
selectEdgeOnClickHandler(node, e);
|
||||||
|
} else if (node && !node.nodeFrom) {
|
||||||
|
selectNodeOnClickHandler(node, e);
|
||||||
|
} else {
|
||||||
|
canvasDoubleClickHandler(eventInfo.getPos(), e);
|
||||||
|
}//if
|
||||||
|
},
|
||||||
|
//Implement the same handler for touchscreens
|
||||||
|
onTouchCancel: function (node, eventInfo, e) {
|
||||||
|
|
||||||
},
|
},
|
||||||
//Add also a click handler to nodes
|
//Add also a click handler to nodes
|
||||||
onClick: function (node, eventInfo, e) {
|
onClick: function (node, eventInfo, e) {
|
||||||
if (e.target.id != "infovis-canvas") return false;
|
if (e.target.id != "infovis-canvas") return false;
|
||||||
|
|
||||||
//topic and synapse editing cards
|
//topic and synapse editing cards
|
||||||
hideCards();
|
if (!Mconsole.events.moved) hideCards();
|
||||||
|
|
||||||
//clicking on a node, or clicking on blank part of canvas?
|
//clicking on a node, or clicking on blank part of canvas?
|
||||||
if (node.nodeFrom) {
|
if (node.nodeFrom) {
|
||||||
|
@ -84,6 +120,8 @@ function graphSettings(type, embed) {
|
||||||
} else if (node && !node.nodeFrom) {
|
} else if (node && !node.nodeFrom) {
|
||||||
selectNodeOnClickHandler(node, e);
|
selectNodeOnClickHandler(node, e);
|
||||||
} else {
|
} else {
|
||||||
|
//topic and synapse editing cards
|
||||||
|
if (!Mconsole.events.moved) hideCards();
|
||||||
canvasDoubleClickHandler(eventInfo.getPos(), e);
|
canvasDoubleClickHandler(eventInfo.getPos(), e);
|
||||||
}//if
|
}//if
|
||||||
}
|
}
|
||||||
|
|
|
@ -2591,6 +2591,7 @@ Extras.Classes.Navigation = new Class({
|
||||||
$.event.stop($.event.get(e, win));
|
$.event.stop($.event.get(e, win));
|
||||||
var val = this.config.zooming / 1000,
|
var val = this.config.zooming / 1000,
|
||||||
ans = 1 + scroll * val;
|
ans = 1 + scroll * val;
|
||||||
|
// START METAMAPS CODE
|
||||||
if (ans > 1) {
|
if (ans > 1) {
|
||||||
if (5 >= this.canvas.scaleOffsetX) {
|
if (5 >= this.canvas.scaleOffsetX) {
|
||||||
this.canvas.scale(ans, ans);
|
this.canvas.scale(ans, ans);
|
||||||
|
@ -2607,6 +2608,8 @@ Extras.Classes.Navigation = new Class({
|
||||||
else if (this.canvas.scaleOffsetX > 0.5) {
|
else if (this.canvas.scaleOffsetX > 0.5) {
|
||||||
this.canvas.viz.labels.hideLabels(false);
|
this.canvas.viz.labels.hideLabels(false);
|
||||||
}
|
}
|
||||||
|
// END METAMAPS CODE
|
||||||
|
// ORIGINAL CODE this.canvas.scale(ans, ans);
|
||||||
},
|
},
|
||||||
|
|
||||||
onMouseDown: function(e, win, eventInfo) {
|
onMouseDown: function(e, win, eventInfo) {
|
||||||
|
|
|
@ -118,6 +118,25 @@ function initialize(type, loadLater, embed){
|
||||||
else if ( type == "arranged" || type == "chaotic") {
|
else if ( type == "arranged" || type == "chaotic") {
|
||||||
Mconsole.animate(chooseAnimate);
|
Mconsole.animate(chooseAnimate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent touch events on the canvas from default behaviour
|
||||||
|
$("#infovis-canvas").bind('touchstart', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
Mconsole.events.touched = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// prevent touch events on the canvas from default behaviour
|
||||||
|
$("#infovis-canvas").bind('touchmove', function(event) {
|
||||||
|
//touchPanZoomHandler(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
// prevent touch events on the canvas from default behaviour
|
||||||
|
$("#infovis-canvas").bind('touchend touchcancel', function(event) {
|
||||||
|
lastDist = 0;
|
||||||
|
if (!Mconsole.events.touchMoved && !touchDragNode) hideCurrentCard();
|
||||||
|
Mconsole.events.touched = Mconsole.events.touchMoved = false;
|
||||||
|
touchDragNode = false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
// end
|
// end
|
||||||
}// if not loadLater
|
}// if not loadLater
|
||||||
|
|
|
@ -290,15 +290,13 @@ function bindCallbacks(showCard, nameContainer, node) {
|
||||||
|
|
||||||
// add some events to the label
|
// add some events to the label
|
||||||
$(nameContainer).find('.label').click(function(e){
|
$(nameContainer).find('.label').click(function(e){
|
||||||
$('.name').css('display','block');
|
hideCurrentCard();
|
||||||
$('.name.topic_' + node.id).css('display','none');
|
|
||||||
$('.showcard.topic_' + node.id).fadeIn('fast');
|
$('.showcard.topic_' + node.id).fadeIn('fast');
|
||||||
$('.showcard.topic_' + node.id).find('.scroll').mCustomScrollbar("update");
|
$('.showcard.topic_' + node.id).find('.scroll').mCustomScrollbar("update");
|
||||||
node.setData('dim', 1, 'current');
|
node.setData('dim', 1, 'current');
|
||||||
|
|
||||||
hideCurrentCard();
|
|
||||||
MetamapsModel.showcardInUse = node.id;
|
MetamapsModel.showcardInUse = node.id;
|
||||||
Mconsole.plot();
|
Mconsole.plot();
|
||||||
|
$('#topic_' + node.id + '_label').hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
nameContainer.onmouseover = function(){
|
nameContainer.onmouseover = function(){
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
// other options are 'graph'
|
// other options are 'graph'
|
||||||
var viewMode = "list";
|
var viewMode = "list";
|
||||||
|
|
||||||
var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false;
|
var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false, touchPos, touchDragNode;
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
@ -69,12 +69,26 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null,
|
||||||
height: '0px'
|
height: '0px'
|
||||||
}, 300, function() {
|
}, 300, function() {
|
||||||
sliding1 = false;
|
sliding1 = false;
|
||||||
|
menuIsOpen = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},800);
|
},800);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var menuIsOpen = false;
|
||||||
|
$("#mainTitle a").bind('touchend', function(evt) {
|
||||||
|
if (!menuIsOpen) {
|
||||||
|
menuIsOpen = true;
|
||||||
|
var listLength = $('.logo .menu li').length * 28;
|
||||||
|
$('.footer .menu').animate({
|
||||||
|
height: listLength + 'px'
|
||||||
|
}, 300);
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropogation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
addHoverForSettings();
|
addHoverForSettings();
|
||||||
|
|
||||||
//bind best_in_place ajax callbacks
|
//bind best_in_place ajax callbacks
|
||||||
|
@ -99,7 +113,7 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null,
|
||||||
saveLayoutAll();
|
saveLayoutAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
}); // end document.ready
|
||||||
|
|
||||||
function addHoverForSettings() {
|
function addHoverForSettings() {
|
||||||
// controls the sliding hover of the settings for cards
|
// controls the sliding hover of the settings for cards
|
||||||
|
|
Loading…
Add table
Reference in a new issue