Javascript 在svg元素上挂钩鼠标事件时,NVD3图表控件不起作用
我在nvd3中有一个面积图:Javascript 在svg元素上挂钩鼠标事件时,NVD3图表控件不起作用,javascript,svg,nvd3.js,Javascript,Svg,Nvd3.js,我在nvd3中有一个面积图: var chart = nv.models.stackedAreaChart() .x(function (d) { return d[0] }) .y(function (d) { return Math.round(d[1]) }) .clipEdge(true) .showControls(true) .useInteractiveGuideline(true); 如您所见,我启用了showControls,它在图表的
var chart = nv.models.stackedAreaChart()
.x(function (d) { return d[0] })
.y(function (d) { return Math.round(d[1]) })
.clipEdge(true)
.showControls(true)
.useInteractiveGuideline(true);
如您所见,我启用了showControls,它在图表的左上角显示三个堆叠、流式和展开的小按钮
var mouseDown = false;
var mouseDownCoords;
var rect = svg.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", 0).attr("height", 0)
.attr("fill", "rgba(43,48,87,0.3)");
svg.on('mousedown', function () {
var height = svg[0][0].height;
mouseDownCoords = d3.mouse(this);
mouseDown = true;
rect.attr("x", mouseDownCoords[0]);
rect.attr("height", height.animVal.value);
// Register mousemove when the mouse button is down
svg.on('mousemove', function () {
var coords = d3.mouse(this);
rect.attr("width", Math.max(coords[0] - mouseDownCoords[0], 0));
});
});
svg.on('mouseup', function () {
if (mouseDown) {
var coords = d3.mouse(this);
var width = Math.max(coords[0] - mouseDownCoords[0], 0);
mouseDown = false;
rect.attr("width", 0);
if (width > 0) {
var totalWidth = svg[0][0].width.animVal.value;
var totalPeriod = dateTo.getTime() - dateFrom.getTime();
var newDateFrom = new Date(Math.floor(dateFrom.getTime() + totalPeriod * mouseDownCoords[0] / totalWidth));
var newDateTo = new Date(Math.floor(newDateFrom.getTime() + totalPeriod * width / totalWidth));
window.setSearchTimeframe(newDateFrom, newDateTo);
}
}
// Unregister mousemove
svg.on('mousemove', null);
});
由于需要通过拖动鼠标来选择图表的子部分,因此我通过在包含图表的SVG元素上连接mouseup、mousedown和mousemove事件来实现以下解决方案
var mouseDown = false;
var mouseDownCoords;
var rect = svg.append("rect")
.attr("x", 0).attr("y", 0)
.attr("width", 0).attr("height", 0)
.attr("fill", "rgba(43,48,87,0.3)");
svg.on('mousedown', function () {
var height = svg[0][0].height;
mouseDownCoords = d3.mouse(this);
mouseDown = true;
rect.attr("x", mouseDownCoords[0]);
rect.attr("height", height.animVal.value);
// Register mousemove when the mouse button is down
svg.on('mousemove', function () {
var coords = d3.mouse(this);
rect.attr("width", Math.max(coords[0] - mouseDownCoords[0], 0));
});
});
svg.on('mouseup', function () {
if (mouseDown) {
var coords = d3.mouse(this);
var width = Math.max(coords[0] - mouseDownCoords[0], 0);
mouseDown = false;
rect.attr("width", 0);
if (width > 0) {
var totalWidth = svg[0][0].width.animVal.value;
var totalPeriod = dateTo.getTime() - dateFrom.getTime();
var newDateFrom = new Date(Math.floor(dateFrom.getTime() + totalPeriod * mouseDownCoords[0] / totalWidth));
var newDateTo = new Date(Math.floor(newDateFrom.getTime() + totalPeriod * width / totalWidth));
window.setSearchTimeframe(newDateFrom, newDateTo);
}
}
// Unregister mousemove
svg.on('mousemove', null);
});
但是,注册这些事件回调会停止控制按钮的工作。当我点击它们时,什么也不会发生,即使指针在我悬停它们时正确地改变。你说得对,在NVD3内置事件系统之外的元素上注册事件似乎真的会在内部破坏事情,在我看来,这不应该是这样。您可以通过在图表中需要自定义行为的部分放置一个不可见的元素来解决此问题 演示 红色矩形是具有自定义行为的图表的一部分,单击它 var chartElement=d3.selectchart svg; var图; nv.addGraphfunction{ chart=nv.models.pieChart .X功能{ 返回d.标签 } .功能正常{ 返回d值 } .showLabelstrue; var图表数据=[{ 标签:富, 价值:67 }, { 标签:酒吧, 价值:33 }]; 图表元素 .datumchartData .呼叫图; $customUI.onmousedown,函数{ 注意一些习惯行为。。。; }; 收益表; }; 包装纸{ 位置:相对位置; } 图表{ 位置:绝对位置; 高度:500px; } 海关{ 位置:绝对位置; 背景:红色; 不透明度:0.2; 宽度:100px; 高度:100px; 左:100px; 顶部:200px; } 自定义用户界面:悬停{ 不透明度:0.5; }
这是一个很好的解决办法,但有一个问题。在图表上有一个隐藏的覆盖将阻止鼠标事件通过,并且我有基于这些的其他行为:例如,当您在某个区域上移动光标时,工具提示将显示当前x值上的项目数。我可以移动x轴底部的隐形包装,但这会限制可用性。我真的希望有一种方法可以直接修复nvd3事件。是的,这是一种非常有缺陷的方法。如果您尚未: