Making a SVG Text draggable using d3.js - jquery-ui

I want to make a text in a d3 visualisation draggable for use in an editor. I started to play with on e of the examples (http://bl.ocks.org/mbostock/4063550). When i add a dragbeheavier to the text element, i can tell from the ChromeDevTools that somthing gets dragged but there is no visual representation af that drag. I also tried to do it using JQuery UI what didn't worked either. What do i miss and is it even possible to do so?

You can use drag.behaviour to add drag events to elements.
1) Create a function to handle the drag event (of type d3.event):
function dragmove(d) {
d3.select(this)
.style("top", ((d3.event.sourceEvent.pageY) - this.offsetHeight/2)+"px")
.style("left", ((d3.event.sourceEvent.pageX) - this.offsetWidth/2)+"px")
}
2) Create drag behavior using the above function as handler:
var drag = d3.behavior.drag()
.on("drag", dragmove);
3) Bind it to an element or a set of elements using .call on a d3 selection:
d3.select("body").append("div")
.attr("id", "draggable")
.text("Drag me bro!")
.call(drag)
Try it: http://jsfiddle.net/HvkgN/2/
Here's the same example, adapted for an svg text element:
function dragmove(d) {
d3.select(this)
.attr("y", d3.event.y)
.attr("x", d3.event.x)
}
var drag = d3.behavior.drag()
.on("drag", dragmove);
d3.select("body").append("svg")
.attr("height", 300)
.attr("width", 300)
.append("text")
.attr("x", 150)
.attr("y", 150)
.attr("id", "draggable")
.text("Drag me bro!")
.call(drag)

A better-looking way to add dragging to an SVG element is to use a translate transform that moves the draggable element around. Couple this with a drag event handler that uses d3.event.dx and d3.event.dy to monitor the mouse's movement.
var transX = 0;
var transY = 0;
var theElement = d3.select('svg#xyz text.blahblah').attr('transform', "translate(" + transX + ", " + transY + ")");
var repositionElement = function(data) {
transX += d3.event.dx;
transY += d3.event.dy;
theElement.attr('transform', "translate(" + transX + ", " + transY + ")");
};
var addDragging = function (element) {
element.call(d3.behavior.drag().on('drag', repositionElement));
};
addDragging(theElement);
Also, unlike changing x/y directly, this technique can be used to make an entire <g> group draggable, so when the user clicks and drags any part of the group, the whole group moves!

Related

Detect the scrolling to bottom of the page using Dart

I could detect scroll reaches to bottom by using Javascript
$(window).on("scroll", function() {
var scrollHeight = $(document).height();
var scrollPosition = $(window).height() + $(window).scrollTop();
if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
// when scroll to bottom of the page
}
});
But I cannot find document.height in Dart.
How can I get height of document and compare with window.scrollY?
I think, although I always had trouble understanding the various heights, that document.body.clientHeight should work (i.e. I have used it once)
_updateScrollInfo([_]) {
if (window.innerHeight + window.scrollY >= document.body.clientHeight) {
print("at bottom");
}
}
window.onScroll.listen(_updateScrollInfo);
DartPad example: https://dartpad.dartlang.org/6fcfb715e4090a1aafe4

jQuery ui-sortable open original place holder on drag outside of list

I have a sortable vertical single column list. What I need:
1) Open original placeholder where the element was on start when user drags an element outside of the list. I need it to prevent drop outside of list. Is it possible?
2) Is it possible to add or change tolerance option? I need to setup reordering (for vertical list) when top border of dragging element overlaps bottom border of list elements. I managed get this while dragginf upward but when you dragginf down sorting work on mouse overlap.
$('#sortable').sortable({
sort: function (event, ui) {
var list = $(this),
w = ui.helper.outerWidth(),
h = ui.helper.outerHeight();
list.children().each(function () {
if ($(this).hasClass('ui-sortable-helper') || $(this).hasClass('ui-sortable-placeholder')) {
return true;
}
var currElementHeight = $(this).outerHeight(),
overlap = $(this).position().top + currElementHeight - ui.position.top,
placeBefore = ui.position.top > $(this).position().top;
if (overlap > 0 && overlap < currElementHeight) {
if (placeBefore)
$('.ui-sortable-placeholder', list).insertBefore($(this));
else
$('.ui-sortable-placeholder', list).insertAfter($(this));
return false;
}
if ($(this).position().left + $(this).outerWidth() < ui.position.left) {
console.log('out');
//ui.item.parent().sortable('cancel');
}
});
},
});
Here is my experiments on jsfiddle

3D rotation using Jquery .draggable() on 3D css element

I'm trying to figure out how to enable visitors to drag to rotate a 3D div using .draggable(). Currently the div rotates but also moves vertically and horizontally making the process touchy and unpredictable. I would like the origin of the div to stay fixed, and the "dragging" to only affect the rotation, so users can "spin" the div around to see the other sides.
here is link to the codepen: http://codepen.io/armandhammer8/pen/IiBga
$('.anime').draggable({
drag: function(event, ui){
var rotateCSS = 'rotate(' + ui.position.left + 'deg)';
$(this).css({
'transform': rotateCSS,
'-moz-transform': rotateCSS,
'-webkit-transform': rotateCSS
});
Thanks in advance!
The div element is a little house:
I want to be able to spin it around
The built in functionality of draggable is giving you the problems.
It's not so hard to get the functionality by yourself and stop using draggable.
Javascript:
var offset = 0, startX;
var elem = document.getElementById("element");
$('.draggable').on('mousedown', function (e) {
startX = e.pageX - offset;
})
.on('mouseup', function() {
startX = null;
})
.on('mousemove', function (e) {
if(startX) {
offset = e.pageX - startX;
elem.style['-webkit-transform'] = 'rotateY(' + offset + 'deg)';
}
});
demo

jQuery UI display modal dialog only over a div?

I would like to display a modal dialog over the entire page, but over a certain div in the DOM. Is this possible? Examples in the docs only show how to display a dialog over the entire page.
Check out the "position" option. Use it like this:
$(".selector").dialog({ position: [350,100] }); // places dialog at x:350, y:100
Then you can line up the x,y to sit above your target div.
You can use jQuery's .offset() to find the div's position and then do what John said
Fit inside Div:
var bg_div = $("#background_div");
var pos = bg_div.offset();
var margin = 10;
$(".selector").dialog({
position: [pos.left+margin,pos.top+margin],
width: bg_div.outerWidth() - margin*2,
height: bg_div.outerHeight() - margin*2
});
Center over Div:
var bg_div = $("#background_div");
var pos = bg_div.offset();
var x = pos.left + (bg_div.outerWidth()/2);
var y = pos.top + (bg_div.outerHeight()/2);
$(".selector").dialog({position: [x,y]});

ExtJS Quicktip constrains problem

I've got a column renderer defined that creates a HTML fragment which contains the ext.qtip attributes to create a quicktip. All works fine, the image renders in the grid cell, when i hover over the image a tooltip with the larger image is shown ... all nice but the quicktip on the bottom row expands beyond the constraints of the panel, is there any way to make it stay inside the panel boundaries?
var thumbRenderer = function(value, meta, record){
var thumbPath = Config.baseUrl + 'images/thumb/' + record.get('filename');
var previewPath = Config.baseUrl + 'images/big/' + record.get('filename');
return String.format('<img src="{0}" ext:qwidth="312" ext:qtip="<img style=\'margin: 2px 0;width:300px;\' src=\'{1}\' />" width="60" class="pic" />', thumbPath, previewPath);
}
You may want to look at the showAt method:
tip.showAt([x,y]);
Where x and y are the respective x and y co-ordinate positions.
EDIT: You can also use the showBy() method on a QuickTip instance:
http://dev.sencha.com/deploy/dev/docs/source/Tip.html#method-Ext.Tip-showBy

Resources