I am using this example to implement dragging on a graph.
The most relevant part:
/// IMPLEMENT DRAG BEHAVIOR
drag = d3.drag().on("drag", dragged)
function dragged(event,d) {
d3.select(this).attr("transform", 'translate(' + event.x + ',' + 0 + ')')
}
for (line of quantile_horizontal_lines) {
line.call(drag)
}
The function dragged expects an event. But the object passed into dragged is just the coordinates of my line, with nothing about the event. Of course, it has no attribute x, so the code doesn't work.
An event object is supposed to look like this:
I can't figure out what I'm doing differently from the example.
My full code:
/// BASIC LINE GRAPH SETUP
// 2. Use the margin convention practice
var margin = {top: 50, right: 50, bottom: 50, left: 50}
, width = window.innerWidth - margin.left - margin.right // Use the window's width
, height = window.innerHeight - margin.top - margin.bottom; // Use the window's height
// 8. An array of objects of length N. Each object has key -> value pair, the key being "y" and the value is a random number
var dataset = data
// The number of datapoints
var n = data.length
// 5. X scale will use the index of our data
var xScale = d3.scaleLinear()
.domain([metadata.xmin, metadata.xmax]) // input
.range([0, width]); // output
// 6. Y scale will use the randomly generate number
var yScale = d3.scaleLinear()
.domain([metadata.ymin, metadata.ymax]) // input
.range([height, 0]); // output
// 7. d3's line generator
var line = d3.line()
.x(function(d) { return xScale(d.x); }) // set the x values for the line generator
.y(function(d) { return yScale(d.y); }) // set the y values for the line generator
// 1. Add the SVG to the graph div and employ #2
var svg = d3.select("#graph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// 3. Call the x axis in a group tag
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom
// 4. Call the y axis in a group tag
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft
// 9. Append the path, bind the data, and call the line generator
plane = svg.append("g").attr('class','plane')
plane.append("path")
.datum(dataset) // 10. Binds data to the line
.attr("class", "line") // Assign a class for styling
.attr("d", line); // 11. Calls the line generator
d3.select('.line') // move this to a CSS file later
.attr('fill','none')
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
/// ADD HORIZONTAL/VERTICAL LINES
plane.on('click',onclick)
onclick = function (event){
x = xScale.invert(event.layerX - margin.left);
y = yScale.invert(event.layerY - margin.right);
console.log(x,y)
}
quantile_horizontal_lines = new Array()
function drawQuantileLines(quantiles) {
console.log("running drawQuantileLines")
for (let i = 0; i < quantiles.length; i++) {
quantile = quantiles[i]
quantile_horizontal_line_0 = {'x': quantile.x, 'y': metadata.ymin}
quantile_horizontal_line_1 = {'x': quantile.x, 'y': quantile.y}
quantile_horizontal_lines.push(
plane.append("path")
.datum([quantile_horizontal_line_0, quantile_horizontal_line_1])
.attr('d', line)
.attr('class', 'line')
.attr('stroke', 'red'))
}
}
drawQuantileLines(quantiles)
/// IMPLEMENT DRAG BEHAVIOR
drag = d3.drag().on("drag", dragged)
function dragged(event,d) {
d3.select(this).attr("transform", 'translate(' + event.x + ',' + 0 + ')')
}
for (line of quantile_horizontal_lines) {
line.call(drag)
}
data, metadata, and quantiles are JSON objects generated from Python using json.dumps(). I doubt the JSONs are invalid in some way; I am able to draw the lines fine, the problem is with the dragging.

