d3鼠标移动十字线边界

时间:2014-06-12 16:16:15

标签: javascript d3.js

[更新]

点击此处jsfiddle


[原帖]

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

我尝试添加if else来限制十字线,但它不起作用。例如,我在.style("display", (xCoord>=minX & xCoord<=maxX & yCoord>=minY & yCoord<=maxY) ? "block" : "none")函数中尝试了类似addCrossHair()的内容。

<!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>

1 个答案:

答案 0 :(得分:3)

执行此操作的方法是使实际画布(即您正在绘制点的位置)与轴渲染的元素分开g元素。然后可以平移画布,使其位于轴的右侧和上方。十字准线处理程序将附加到此画布g元素(这不是很简单,请参阅this question)并且十字准线或点不会出现在画布之外。

完整演示here