我有一个散射图,它具有完美的变焦功能。我正在尝试添加工具提示,以便在'mouseenter'
<circle>
元素上,工具提示会触发。我有这个工作,即'mouseenter'
事件被调用,但当鼠标停留在此<circle>
时我无法缩放。有没有办法让它们同时发生?
以下是重现此问题的最低版本代码。
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<button id="resetBtn">Reset</button>
<div id="chart"></div>
<script>
var data = [
{
x: 0.5, y: 0.5
},
{
x: 0.6, y: 0.6
},
{
x: 0.45, y: 0.65
},
{
x: 0.76, y: 0.61
},
{
x: 0.51, y: 0.05
},
{
x: 0.16, y: 6.8
}
];
var plot = volcanoPlot()
.xColumn("x")
.yColumn("y");
d3.select('#chart')
.data([data])
.call(plot);
function volcanoPlot() {
var width = 960,
height = 500,
margin = {top: 20, right: 20, bottom: 40, left: 50},
xColumn,
dotRadius = 10,
yColumn,
xScale = d3.scaleLinear(),
yScale = d3.scaleLog();
function chart(selection){
var innerWidth = width - margin.left - margin.right, // set the size of the chart within its container
innerHeight = height - margin.top - margin.bottom;
selection.each(function(data) {
xScale.range([0, innerWidth])
.domain(d3.extent(data, function(d) { return d[xColumn]; }))
.nice();
yScale.range([0, innerHeight])
.domain(d3.extent(data, function(d) { return d[yColumn]; }))
.nice();
var zoom = d3.zoom()
.scaleExtent([1, 20])
.translateExtent([[0, 0], [width, height]])
.on('zoom', zoomFunction);
var svg = d3.select(this).append('svg')
.attr('height', height)
.attr('width', width)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
d3.select('#resetBtn')
.style('top', margin.top * 1.5 + 'px')
.style('left', margin.left * 1.25 + 'px')
.on('click', reset);
svg.append('defs').append('clipPath')
.attr('id', 'clip')
.append('rect')
.attr('height', innerHeight)
.attr('width', innerWidth);
// add the axes
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var gX = svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + innerHeight + ')')
.call(xAxis);
gX.append('text')
.attr('class', 'label')
.attr('transform', 'translate(' + width / 2 + ',' + (margin.bottom - 6) + ')')
.attr('text-anchor', 'middle')
.text(xColumn);
var gY = svg.append('g')
.attr('class', 'y axis')
.call(yAxis);
gY.append('text')
.attr('class', 'label')
.attr('transform', 'translate(' + (0 - margin.left / 1.5) + ',' + (height / 2) + ') rotate(-90)')
.style('text-anchor', 'middle')
.text(yColumn);
var zoomBox = svg.append('rect')
.attr('class', 'zoom')
.attr('height', innerHeight)
.attr('width', innerWidth)
.attr('fill', 'none')
.attr('pointer-events', 'all')
.call(zoom);
var circles = svg.append('g')
.attr('class', 'circlesContainer')
.attr('clip-path', 'url(#clip)');
circles.selectAll(".dot")
.data(data)
.enter().append('circle')
.attr('r', dotRadius)
.attr('cx', function(d) { return xScale(d[xColumn]); })
.attr('cy', function(d) { return yScale(d[yColumn]); })
.attr('class', 'dot')
.attr('stroke', 'none')
.on('mouseenter', function(){
console.log("hi");
});
function zoomFunction() {
var transform = d3.zoomTransform(this);
d3.selectAll('.dot')
.attr('transform', transform)
.attr('r', dotRadius / Math.sqrt(transform.k));
gX.call(xAxis.scale(d3.event.transform.rescaleX(xScale)));
gY.call(yAxis.scale(d3.event.transform.rescaleY(yScale)));
}
function reset() {
var ease = d3.easePolyIn.exponent(4.0);
d3.select('.zoom')
.transition().duration(750)
.ease(ease)
.call(zoom.transform, d3.zoomIdentity);
}
});
}
chart.width = function(value) {
if (!arguments.length) return width;
width = value;
return chart;
};
chart.height = function(value) {
if (!arguments.length) return height;
height = value;
return chart;
};
chart.margin = function(value) {
if (!arguments.length) return margin;
margin = value;
return chart;
};
chart.xColumn = function(value) {
if (!arguments.length) return xColumn;
xColumn = value;
return chart;
};
chart.yColumn = function(value) {
if (!arguments.length) return yColumn;
yColumn = value;
return chart;
};
return chart;
}
</script>
</body>
</html>
答案 0 :(得分:1)
您在矩形上调用缩放功能,因此,当您将鼠标悬停在圆圈上时,缩放功能将无效。它与mouseenter
功能无关:您可以移除mouseenter
,当您将鼠标悬停在圆圈上时,缩放功能仍然无效。
一个简单的解决方案是调用SVG组上的缩放,而不是矩形:
var svg = d3.select(this).append('svg')
.attr('height', height)
.attr('width', width)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.call(zoom);
以下是仅包含此更改的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<button id="resetBtn">Reset</button>
<div id="chart"></div>
<script>
var data = [
{
x: 0.5, y: 0.5
},
{
x: 0.6, y: 0.6
},
{
x: 0.45, y: 0.65
},
{
x: 0.76, y: 0.61
},
{
x: 0.51, y: 0.05
},
{
x: 0.16, y: 6.8
}
];
var plot = volcanoPlot()
.xColumn("x")
.yColumn("y");
d3.select('#chart')
.data([data])
.call(plot);
function volcanoPlot() {
var width = 960,
height = 500,
margin = {top: 20, right: 20, bottom: 40, left: 50},
xColumn,
dotRadius = 10,
yColumn,
xScale = d3.scaleLinear(),
yScale = d3.scaleLog();
function chart(selection){
var innerWidth = width - margin.left - margin.right, // set the size of the chart within its container
innerHeight = height - margin.top - margin.bottom;
selection.each(function(data) {
xScale.range([0, innerWidth])
.domain(d3.extent(data, function(d) { return d[xColumn]; }))
.nice();
yScale.range([0, innerHeight])
.domain(d3.extent(data, function(d) { return d[yColumn]; }))
.nice();
var zoom = d3.zoom()
.scaleExtent([1, 20])
.translateExtent([[0, 0], [width, height]])
.on('zoom', zoomFunction);
var svg = d3.select(this).append('svg')
.attr('height', height)
.attr('width', width)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.call(zoom);
d3.select('#resetBtn')
.style('top', margin.top * 1.5 + 'px')
.style('left', margin.left * 1.25 + 'px')
.on('click', reset);
svg.append('defs').append('clipPath')
.attr('id', 'clip')
.append('rect')
.attr('height', innerHeight)
.attr('width', innerWidth);
// add the axes
var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);
var gX = svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + innerHeight + ')')
.call(xAxis);
gX.append('text')
.attr('class', 'label')
.attr('transform', 'translate(' + width / 2 + ',' + (margin.bottom - 6) + ')')
.attr('text-anchor', 'middle')
.text(xColumn);
var gY = svg.append('g')
.attr('class', 'y axis')
.call(yAxis);
gY.append('text')
.attr('class', 'label')
.attr('transform', 'translate(' + (0 - margin.left / 1.5) + ',' + (height / 2) + ') rotate(-90)')
.style('text-anchor', 'middle')
.text(yColumn);
var zoomBox = svg.append('rect')
.attr('class', 'zoom')
.attr('height', innerHeight)
.attr('width', innerWidth)
.attr('fill', 'none')
.attr('pointer-events', 'all');
var circles = svg.append('g')
.attr('class', 'circlesContainer')
.attr('clip-path', 'url(#clip)');
circles.selectAll(".dot")
.data(data)
.enter().append('circle')
.attr('r', dotRadius)
.attr('cx', function(d) { return xScale(d[xColumn]); })
.attr('cy', function(d) { return yScale(d[yColumn]); })
.attr('class', 'dot')
.attr('stroke', 'none')
.on('mouseenter', function(){
console.log("hi");
});
function zoomFunction() {
var transform = d3.zoomTransform(this);
d3.selectAll('.dot')
.attr('transform', transform)
.attr('r', dotRadius / Math.sqrt(transform.k));
gX.call(xAxis.scale(d3.event.transform.rescaleX(xScale)));
gY.call(yAxis.scale(d3.event.transform.rescaleY(yScale)));
}
function reset() {
var ease = d3.easePolyIn.exponent(4.0);
d3.select('.zoom')
.transition().duration(750)
.ease(ease)
.call(zoom.transform, d3.zoomIdentity);
}
});
}
chart.width = function(value) {
if (!arguments.length) return width;
width = value;
return chart;
};
chart.height = function(value) {
if (!arguments.length) return height;
height = value;
return chart;
};
chart.margin = function(value) {
if (!arguments.length) return margin;
margin = value;
return chart;
};
chart.xColumn = function(value) {
if (!arguments.length) return xColumn;
xColumn = value;
return chart;
};
chart.yColumn = function(value) {
if (!arguments.length) return yColumn;
yColumn = value;
return chart;
};
return chart;
}
</script>
</body>
</html>
&#13;