d3.js无法读取null的属性'sourceEvent'

ste*_*edA 6 javascript dom-events d3.js

我刚开始学习d3.js库.我需要制作一个svg编辑器,我教过使用这个编辑器是个好主意.我有一个问题,我做了一些功能,我想在鼠标点击时加载这些功能.函数正在创建从A点到B点的线,所以我只需要在单击Line按钮时启动这些功能.

这是代码块:

var line;
var container = d3.select("body").append("svg")
    .on('mousedown',mousedown)
    .on('mouseup',mouseup);


function mousedown() {
    var coordinates = d3.mouse(this);
        line = container.append("line")
        .attr("x1", coordinates[0])
        .attr("y1", coordinates[1])
        .attr("x2", coordinates[0])
        .attr("y2", coordinates[1]);

container.on("mousemove", mousemove);
};

 function mousemove(){
    var coordinates = d3.mouse(this);
        line.attr("x2", coordinates[0])
            .attr("y2", coordinates[1]);
};
function mouseup(){
     container.on("mousemove", null);
};
Run Code Online (Sandbox Code Playgroud)

HTML

<button id="lineBtn">Line</button>
Run Code Online (Sandbox Code Playgroud)

CSS

line {
   stroke: black;
   stroke-width: 3px;
}

svg{
    border:1px solid black;
    width:500px;
    height:500px;
    margin-left: 40%;
    margin-right:40%; 
}
Run Code Online (Sandbox Code Playgroud)

Ger*_*ado 0

根据您的评论,问题在于您处理按钮的方式:

document.getElementById("lineBtn").onclick = function drawLine(){ 
    mousedown(); 
    mousemove(); 
    mouseup(); 
};
Run Code Online (Sandbox Code Playgroud)

由于多种原因,您不能像这样调用这些函数,但主要是因为没有this传递到d3.mouse事件,因此没有源事件。

更好的方法是使用按钮设置正确的侦听器,如下所示:

d3.select("#lineBtn").on("click", function() {
  container.on('mousedown', mousedownLine)
    .on('mouseup', mouseupLine);
});

d3.select("#circleBtn").on("click", function() {
  container.on('mousedown', mousedownCircle)
    .on('mouseup', mouseupCircle);
});
Run Code Online (Sandbox Code Playgroud)

这是一个演示(使用 D3 v5,在这个问题上与您的 v3 没有什么不同):

document.getElementById("lineBtn").onclick = function drawLine(){ 
    mousedown(); 
    mousemove(); 
    mouseup(); 
};
Run Code Online (Sandbox Code Playgroud)
d3.select("#lineBtn").on("click", function() {
  container.on('mousedown', mousedownLine)
    .on('mouseup', mouseupLine);
});

d3.select("#circleBtn").on("click", function() {
  container.on('mousedown', mousedownCircle)
    .on('mouseup', mouseupCircle);
});
Run Code Online (Sandbox Code Playgroud)
var line;
var circle;
var container = d3.select("body").append("svg");

d3.select("#lineBtn").on("click", function() {
  container.on('mousedown', mousedownLine)
    .on('mouseup', mouseupLine);
});

d3.select("#circleBtn").on("click", function() {
  container.on('mousedown', mousedownCircle)
    .on('mouseup', mouseupCircle);
});

function mousedownLine() {
  container.on("mousemove", mousemoveLine);
  var coordinates = d3.mouse(this);
  line = container.append("line")
    .attr("x1", coordinates[0])
    .attr("y1", coordinates[1])
    .attr("x2", coordinates[0])
    .attr("y2", coordinates[1]);
};

function mousemoveLine() {
  var coordinates = d3.mouse(this);
  line.attr("x2", coordinates[0])
    .attr("y2", coordinates[1]);
};

function mouseupLine() {
  container.on("mousemove", null);
};

function mousedownCircle() {
  container.on("mousemove", mousemoveCircle);
  var coordinates = d3.mouse(this);
  circle = container.append("circle")
    .attr("cx", coordinates[0])
    .attr("cy", coordinates[1]);
};

function mousemoveCircle() {
  var coordinates = d3.mouse(this);
  circle.attr("r", Math.hypot(coordinates[0] - circle.attr("cx"), coordinates[1] - circle.attr("cy")));
};

function mouseupCircle() {
  container.on("mousemove", null);
};
Run Code Online (Sandbox Code Playgroud)