I am developing a set of d3 Reusable Charts - vanilla and in one page. (I know this is not great practice but as this is a learning exercise for me I find it easier to follow the code this way.) Using the pattern from ProD3 Book by Marcos Iglesias https://www.apress.com/gp/book/9781484252024.
I can implement on.click events (ish).
But I am trying to do so with Drag events using this "d3 minimal drag example" https://bl.ocks.org/codetricity/7ced6f3b3c95d64e7d7467e430716a63.
I have the Dispatcher object to broadcast the 'customHover' event:
const dispatcher = d3.dispatch('customDrag');
Then I have the ".on" event nested in the "draghandler" function with the "d3.drag()" called from the "enter selection". But I am not sure if this is correct way to do this - it is only configuration I tried that didn't cause errors.
discs.enter()
.append('circle')
.attr('class', 'Discs')
.attr('cx', 50)
.attr('cy', 50)
.attr('r', 20)
.attr('stroke', 'black')
.attr('fill', '#69a3b2');
let dragHandler = d3.drag()
.on('drag', function(d) {
dispatcher.call('customDrag', this, d);
});
discs.call(dragHandler);
Then the accessor function is here:
exports.on = function() {
let value = dispatcher.on.apply(dispatcher, arguments);
return value === dispatcher ? exports : value;
};
Then I have called this in this way:
let position = [50]
let myChart = d3.reusable.chart()
.on('customDrag', function(d){
d3.select(this).classed("dragging", true).attr('cx', d3.event.x).attr('cy', d3.event.y);
});
d3.select("#chart")
.datum(position)
.call(myChart);
JSFiddle here: https://jsfiddle.net/Maltbyjim/y1mpuh4c/1/
I can't figure out where I am going wrong.
The only thing I think I may have missed is the possible translation of the x and y coord positions, but I don;t know how I would do that with drag coords.
Sorry if this seems daft, I don't understand d3 or js particularly well. And couldn't see a previous question that addressed this issue.
CodePudding user response:
I think the issue is related to this line:
discs.call(dragHandler);
You will need instead to select the discs again to apply the drag:
svg.select('.Discs').call(dragHandler);
See it working here: https://jsfiddle.net/mku50xyh/1/