Currently, I am developing a unique package that combines Angular and D3 (v3) and my main focus is on integrating D3's dragging feature into the package. Although I am very close to achieving success, there is a minor bug that I need to address. When the plots are initially rendered, the elements (specifically rectangles) cannot be dragged unless the text on the x-axis is selected using the cursor. Once the text is highlighted, the dragging functionality works perfectly. However, fixing this initial bug is crucial for the overall user experience.
To better illustrate the issue, you can find a demonstration in a Github.io project here. The dragging behavior from D3 is defined in the ivml library version 0.0.0 (included in the repository) within lines 903-966, which I have included below:
if (Bars.events.dragE) {
// Note: xs(0) refers to pixel value at 0 on the x-scale. Must be reset for generalizability
// function returns width (in pixels) of bar. Used to ensure drag doesn't exceed plot area
function returnw(d, i){
if (values_function(d, i) <= 0) {
Bars.elements.barController.offset(position_function(d, i), xs(0) - xs(values_function(d, i)), values_function(d, i));
return xs(0) - xs(values_function(d, i));
}
else {
Bars.elements.barController.offset(position_function(d, i), xs(values_function(d, i)) - xs(0), values_function(d, i))
return Math.abs(xs(0)-xs(values_function(d, i)))
}
}
var drag = d3.behavior.drag()
.on('dragstart', draginit)
.on('drag', dragmove)
.on('dragend', dragfin);
function draginit(d){
d3.event.sourceEvent.stopPropagation();
// replace fill color with variable for user input function
Bars.events.dragE(d, i, d3.select(this).attr('style', 'fill: yellow; stroke: black; stroke-width: 3px;'))
}
function dragmove(d){
var svgwidth = Bars.elements.chartController.plotObject.attributes.width //margin of plotObject
var svginterval = svgwidth/(Bars.elements.chartController.plotObject.attributes.xmax-Bars.elements.chartController.plotObject.attributes.xmin) //number of pixels between whole numbers in coordinate plot
Bars.events.dragE(d, i,
d3.select(this)
.attr("x", function(d, i){
if (d3.event.x < 0) {return 0}
else if (d3.event.x + returnw(d,i) > svgwidth){ return (svgwidth - returnw(d,i))}
else {return xs(Math.floor(d3.event.x/svginterval)) } }));
var valuechange = d3.event.x < 0 ? 0 : (d3.event.x + returnw(d,i) > svgwidth ? svgwidth - returnw(d,i) : d3.event.x);
console.log("Start value changed to: ", Math.floor(valuechange/svginterval));
}
function dragfin(d){
Bars.events.dragE(d, i, d3.select(this).attr('style', 'stroke: black; stroke-width: 0px;')
.attr('fill', Bars.attributes.fill))
}
rects.attr("cursor", "ew-resize")
.on('dragstart', function(d, i){
Bars.events.dragE(d, i, d3.select(this).call(drag))
})
.on('drag', function (d, i) {
window.dragThis = this;
Bars.events.dragE(d, i,
d3.select(this).call(drag))
})
.on("dragend", function(d, i){
Bars.events.dragE(d, i, d3.select(this).call(drag))
})
}
As I continue to navigate through Angular, Javascript, and D3 functionalities, any advice or suggestions on resolving this slight setback would be immensely valuable!