Reputation: 553
The full code is visible and modifiable on observablehq
The relevant parts:
const columns = svg.selectAll("g")
.data(nested_city)
.enter()
.append("g")
.attr("city", function(d) { return d.key ;})
.attr("x", function(d) { return x(d.key) ;})
.attr("y", "0")
.attr("transform", function(d) { return "translate(" + x(d.key) + ",0)" ;})
.attr("class", "column")
.on("mouseover", function(d) {
d3.select(this)
.style("cursor","pointer");
})
.on("mouseout", function(d){
d3.select(this)
.style("cursor","default");
})
.call(d3.drag()
.subject(function() {
var t = d3.select(this);
var tr = getTranslation(t.attr("transform"));
return {x: t.attr("x") + tr[0],
y: t.attr("y") + tr[1]};
})
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
and the drag handlers:
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this).attr("transform", function(d,i){
var coordinates = d3.mouse(this);
var mx = coordinates[0]
console.log( coordinates[0])
return "translate(" + [mx,0] + ")"})
}
function dragended(d) {
d3.select(this).classed("active", false);
}
I'm trying to adapt the new drag and drop with translation (found here on SO) for d3 v4 version to my example on observableHQ, without success.
I have a very strange flickering behavior when i drag any of the two column (alternate between jump with old x values and new x values).
If you have any idea why ?
Upvotes: 1
Views: 555
Reputation: 900
There is a d3.mouse(this)
statement in the dragged()
function. This returns the x and y coordinates of the current event relative to the specified Container (ref). Your container for mouse(<container>)
is this
and means the dragged <g>
the element. But it should be the <svg>
. Therefore you should use d3.mouse(svg.node())
instead.
But be careful, since you haven't taken the offset inside the <g>
into account (it's hard to describe). Maybe you have to add the coordinates of the cursor position inside the <g>
.
IMHO I would anyway prefere to use d3.event
over d3.mouse
example.
Edit: New drag functions with correct coordinates
// New: Coordinates inside <g>
var coordG = 0;
function dragstarted(d) {
// New: Read out coordinates inside <g>
coordG = d3.mouse(this)[0];
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this).attr("transform", function(d,i){
var coordinates = d3.mouse(svg.node());
var mx = coordinates[0] - coordG;
console.log( coordG);
return "translate(" + [mx,0] + ")";
});
}
function dragended(d) {
d3.select(this).classed("active", false);
}
Upvotes: 2