Element no longer draggable after adding parameter to d3 drag behavior - javascript

The following code creates a circle and makes it draggable:
HTML:
<svg width='400' height='400'>
<rect width='100%' height='100%'></rect>
<circle transform='translate(259.5,197)' r='10'></circle>
</svg>
JS:
var drag = d3.behavior.drag().on('drag', dragMove)
d3.select('svg').append('circle').attr('transform', 'translate(' + '100px' + ',' + '100px' + ')').attr('r', '5').call(drag)
function dragMove(test) {
var x = d3.event.x
var y = d3.event.y
console.log(test)
d3.select(this).attr('transform', 'translate(' + '200px' + ',' + '200px' + ')')
}
It works. But when I add an argument to dragMove:
'drag', function() { dragMove('test') }
The dragging functionality stops working (console.log(test) outputs 'test', though)
Why is this happening and how to fix it?
https://jsfiddle.net/alexcheninfo/d8doyc9r/4/

It should be this way:
var drag = d3.behavior.drag().on('drag', function(d) {
dragMove(this);//pass the this
})
function dragMove(me) {
var x = d3.event.x
var y = d3.event.y
//operate on me
d3.select(me).attr('transform', 'translate(' + x + ',' + y + ')')
}
working code here
Hope this helps!

Related

Horizontal Autoscroll on mouse drag is not working in D3 tree for firefox

I am creating D3 tree. With the dragging of tree node the auto scroll is not working in Firefox. The auto-scroll with dragging tree node is working in Firefox. It is working fine in Chrome.
HTML code
<div class="row">
<div class="tree-container" id="treeId"></div>
</div>
D3.js code
var nodeEnter = node.enter().append("g").call(dragListener).attr(
"class", "node").attr("transform", function(d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
}).on("mouseenter", nodeMouseEnter).on("mouseleave", nodeMouseLeave)
.on('click', click).attr('id', function(d) {
return d.nodeId;
});
$('.tree-container').css('overflow', 'auto');
Bootstrap.css
svg:not(:root) {
overflow: visible;
}
var svg_scroll = d3.select("svg").node(),
$parent = $('.tree-container'),
$parent_document_height=$(document),
w = $parent.width(),
h = $parent_document_height.height(),
sL = $parent.scrollLeft(),
sT = $parent_document_height.scrollTop();
var coordinates = d3.mouse(svg_scroll),
x = coordinates[0],
y = coordinates[1];
if (x > w + sL) {
$parent.scrollLeft(x - w);
} else if (x < sL) {
$parent.scrollLeft(x);
}
if (y > sT) {
$parent_document_height.scrollTop(y);
} else if (y < sT) {
$parent_document_height.scrollTop(y);
}
d3.select(this).attr({
x: x - 50,
y: y - 25
});

how to make dom manipulation more clear

Have some code like:
var el = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
var c = this.chart;
el.setAttribute('x', c.x + c.padding + 'px');
el.setAttribute('y', c.y + c.padding + i * (b.height + b.margin) + 'px');
el.setAttribute('width', model.value * c.scale + 'px');
el.setAttribute('height', b.height + 'px');
el.classList.add('bar');
this.svg.appendChild(el);
Any options to make it look not as ugly? There is a chance that can be more attributes...
Time to use a function? Something like:
function setAttributes(el, attrs) {
for(var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
And call it as:
setAttributes(elem, {"src": "http://example.com/something.jpeg", "height": "100%", ...});

Check if URL exists within a function in D3.js

I am a beginner with D3.js I am stuck with a problem for last few days. below is the code snippet
function zoomed() {
var tiles = tile
.scale(zoom.scale())
.translate(zoom.translate())
();
projection
.scale(zoom.scale() / 2 / Math.PI)
.translate(zoom.translate());
var image = layer
.style(prefix + "transform", matrix3d(tiles.scale, tiles.translate))
.selectAll(".tile")
.data(tiles, function(d) { return d; });
image.exit()
.remove();
image.enter().append("img")
.attr("class", "tile")
.attr("src", function(d) { return "http://111.118.179.198/Data/63699_1600x1200-wallpaper-cb1362414617.jpg_" + 8 + "_" + d[0] + "_" + d[1] + ".png"; })
.style("left", function(d) {return (d[0] << 8) + "px"; })
.style("top", function(d) { return (d[1] << 8) + "px"; });
}
my requirement is before I set the src attribute to img I need to check whether the url is an existing one, if it is a valid existing url then proper value will get set to src otherwise src will be empty.
This would easier to do with jQuery:
var url = "some_url";
$.ajax(url,
{
statusCode: {
200: function() {
image.attr("src," url);
},
404: function() {
image.attr("src", otherURL);
}
}
}

How to resize a div based on mouse location?

I'm trying to make a div that expands left, right, up, and down depending on where the mouse is. But when I move the mouse, the div just pops up and doesn't do anything. What is wrong in what I'm doing?
(function() {
document.onmousemove = function(e) {
draw(e);
};
function draw(e) {
var method = [
e.pageX ? e.pageX : e.clientX,
e.pageY ? e.pageY : e.clientY
];
var X = method[0],
Y = method[1];
var html = '<div class="box" style="padding-top:' + Y + ';padding-bottom:' + Y + ';padding-left:' + X + ';padding-right:' + X + '"></div>'
;
document.body.innerHTML = html;
}
})();​
You forgot the unit px:
(function() {
document.onmousemove = function(e) {
draw(e);
};
function draw(e) {
var method = [
e.pageX ? e.pageX : e.clientX,
e.pageY ? e.pageY : e.clientY
];
var X = method[0],
Y = method[1];
var html = '<div class="box" style="background-color:red;padding-top:' + Y + 'px;padding-bottom:' + Y + 'px;padding-left:' + X + 'px;padding-right:' + X + 'px"></div>'
;
document.body.innerHTML = html;
}
})();​
(I've also added a red background in order to make the DIV visible)
jsFiddle: http://jsfiddle.net/8LUwp/
X and Y are numbers. CSS lengths require units. Add some px.
CSS length attributes (padding, margin, height, width etc.) require units - px, em etc. So just having:
padding-top:10
is invalid. Instead you need to add units:
padding-top:10px
So in your case the line setting the html should read:
var html = '<div class="box" style="padding-top:' + Y + 'px;padding-bottom:' + Y + 'px;padding-left:' + X + 'px;padding-right:' + X + 'px"></div>';
You were missing px suffix with the x and Y
(function() {
document.onmousemove = function(e) {
draw(e);
};
function draw(e) {
var method = [
e.pageX ? e.pageX : e.clientX,
e.pageY ? e.pageY : e.clientY
];
var X = method[0],
Y = method[1];
var html = '<div class="box" style="padding-top:' + Y +"px" + ';padding-bottom:' + Y +"px" + ';padding-left:' + X +"px" + ';padding-right:' + X +"px" + '"></div>'
;
document.body.innerHTML = html;
}
})();​

Use jQuery set .css RIGHT if #foo + offset left is greater than page width

Ok, so I am trying to use jQuery to get the innerWidth() of an element #preview. I want to create a conditional that says IF x offset LEFT + #preview width is greater than page width, give it style right: z where z = #preview width + xOffset.
I apologize my code below is a mess and the syntax for .css ("right", (rightFloat + xOffset) + "px") (line 125) is off, but that's part of my problem.
<script>
$(document).ready(function(){
//append "gallery" class to all items with "popup" class
imagePreview();
$(".popup").addClass("gallery");
});
//The overlay or pop-up effect
this.imagePreview = function() { /* CONFIG */
xOffset = 40;
yOffset = 40;
// these 2 variable determine popup's distance from the cursor
// you might want to adjust to get the right result
/* END CONFIG */
$("a.preview").click(function(e) {
return false;
});
$("a.preview").hover(function(e) {
this.t = this.title;
this.title = "";
var c = (this.t != "") ? "<br/>" + this.t : "";
var rightFloat = e.pageX + ("#preview").innerWidth;
$("body").append("<p id='preview'><img src='" + this.href + "' alt='Image preview' />" + c + "</p>");
$("#preview").hide().css("top", (e.pageY - yOffset) + "px").css("left", (e.pageX + xOffset) + "px").fadeIn("2000");
while ((left + 400) > window.innerWidth) {.css("right", (rightFloat + xOffset) + "px")
}
}, function() {
this.title = this.t;
$("#preview").remove();
});
$("a.preview").mousemove(function(e) {
var top = e.pageY - yOffset;
var left = e.pageX + xOffset;
var rightFloat = e.pageX + ("#preview").innerWidth;
//flips the image if it gets too close to the right side
while ((left + 400) > window.innerWidth) {.css("right", +(rightFlaot + xOffset) + "px")
}
$("#preview").css("top", top + "px").css("left", left + "px");
});
};
</script>
Try using http://api.jquery.com/offset/
if($('#preview').offset().right<0){
var right = parseInt($(window).width()) - e.pageX + xOffset;
$("#preview").css("top", top + "px").css("right", right + "px");
}else{
var left = e.pageX + xOffset;
$("#preview").css("top", top + "px").css("left", left + "px");
}
I made these fixes because I couldn't get your code to work in jsfiddle:
var xOffset = 40;
var yOffset = 40;
$("a.preview").bind('mouseover',function(e){
var rightFloat = parseFloat(e.pageX)+$("#preview").innerWidth();
var ptop = parseFloat(e.pageY) - yOffset;
var pleft = parseFloat(e.pageX) + xOffset;
$("#preview").css({"top":ptop + "px","left":pleft + "px"});
});
There's the fixes for the top half but I have no idea what you're trying to do with the bottom part (with the while loop). Can you explain what functionality you want?

Categories