d3鼠标移动越过头发边界

d3 mouse move cross hair boundary

本文关键字:头发 边界 鼠标 移动 d3      更新时间:2023-09-26

[更新]

单击此处的jsfiddle。


[原始帖子]

移动鼠标时如何限制十字线的坐标?请注意,当我将鼠标移动到x轴的左侧或y轴的底部时,十字线和文本仍然显示。当鼠标移动到x轴左侧或y轴底部时,我希望十字线和文本停止显示。

我曾尝试添加if else来限制交叉头发,但没有成功。例如,我在addCrossHair()函数中尝试了类似.style("display", (xCoord>=minX & xCoord<=maxX & yCoord>=minY & yCoord<=maxY) ? "block" : "none")的东西。

<!DOCTYPE html>
<meta charset="utf-8">
<head>
    <style>
        .axis path,
        .axis line
        {
            fill:none;
            rendering:crispEdges;
            stroke:black;
            width:2.5;
        }
    </style>
</head>
<body>
    <script src="d3.min.js"></script>
    <script>
        var width = 800,
            height = 600;
        var randomX = [],
            randomY = [];
        for (var i = 0; i <= 500; i++) {
            randomX[i] = Math.random() * 400;
            randomY[i] = Math.random() * 400;
        }
        var minX = d3.min(randomX),
            maxX = d3.max(randomX),
            minY = d3.min(randomY),
            maxY = d3.max(randomY);
        var xScale = d3.scale.linear().domain([minX, maxX]).range([0, width]);
        var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
        var yScale = d3.scale.linear().domain([minY, maxY]).range([height, 0]);
        var yAxis = d3.svg.axis().scale(yScale).orient("left");
        var svgContainer = d3.select("body").append("div").append("svg").attr("width", width).attr("height", height);
        var svg = svgContainer.append("g").attr("transform", "translate(50, 50)");
        svg.append("g").attr("class", "axis").attr("transform", "translate(0,530)").call(xAxis);
        svg.append("g").attr("class", "axis").call(yAxis);
        var crossHair = svg.append("g").attr("class", "crosshair");
        crossHair.append("line").attr("id", "h_crosshair") // horizontal cross hair
            .attr("x1", 0)
            .attr("y1", 0)
            .attr("x2", 0)
            .attr("y2", 0)
            .style("stroke", "gray")
            .style("stroke-width", "1px")
            .style("stroke-dasharray", "5,5")
            .style("display", "none");
        crossHair.append("line").attr("id", "v_crosshair") // vertical cross hair
            .attr("x1", 0)
            .attr("y1", 0)
            .attr("x2", 0)
            .attr("y2", 0)
            .style("stroke", "gray")
            .style("stroke-width", "1px")
            .style("stroke-dasharray", "5,5")
            .style("display", "none");
        crossHair.append("text").attr("id", "crosshair_text") // text label for cross hair
            .style("font-size", "10px")
            .style("stroke", "gray")
            .style("stroke-width", "0.5px");
        svgContainer.on("mousemove", function () {
            var xCoord = d3.mouse(this)[0] - 50,
                yCoord = d3.mouse(this)[1] - 50;
                addCrossHair(xCoord, yCoord);
            })
            .on("mouseover", function () {d3.selectAll(".crosshair").style("display", "block");})
            .on("mouseout", function () {d3.selectAll(".crosshair").style("display", "none");});
        function addCrossHair(xCoord, yCoord) {
            // Update horizontal cross hair
            d3.select("#h_crosshair")
                .attr("x1", xScale(minX))
                .attr("y1", yCoord)
                .attr("x2", xScale(maxX))
                .attr("y2", yCoord)
                .style("display", "block");
            // Update vertical cross hair
            d3.select("#v_crosshair")
                .attr("x1", xCoord)
                .attr("y1", yScale(minY))
                .attr("x2", xCoord)
                .attr("y2", yScale(maxY))
                .style("display", "block");
            // Update text label
            d3.select("#crosshair_text")
                .attr("transform", "translate(" + (xCoord + 5) + "," + (yCoord - 5) + ")")
                .text("(" + xScale.invert(xCoord) + " , " + yScale.invert(yCoord) + ")");
        }
        svg.selectAll("scatter-dots")
            .data(randomY)
            .enter().append("svg:circle")
            .attr("cy", function (d) {
                return yScale(d);
            })
            .attr("cx", function (d, i) {
                return xScale(randomX[i]);
            })
            .style("fill", "brown")
            .attr("r", 3)
    </script>
</body>

实现这一点的方法是使实际画布(即绘制点的位置(成为与轴渲染到的画布分离的g元素。然后可以平移画布,使其位于轴的右侧和上方。十字光标处理程序将附加到此画布g元素(这不是很简单,请参阅此问题(,并且十字光标或点不会出现在画布之外。

在此处完成演示。