d3.js矩形缩放不起作用

时间:2013-05-23 20:29:04

标签: d3.js zoom

这是我目前的代码

 <!DOCTYPE html>
<meta charset="utf-8">
<title>Zoom by Rectangle</title>
<script src="http://d3js.org/d3.v2.min.js?2.10.1"></script>
<style>

body {
  font-family: sans-serif;
}

.noselect {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

svg {
  font: 10px sans-serif;
  shape-rendering: crispEdges;
}

rect {
  fill: #ddd;
}

rect.zoom {
  stroke: steelblue;
  fill-opacity: 0.5;
}

.axis path, .axis line {
  fill: none;
  stroke: #fff;
}

</style>
<p>
<script>
 var margin = {
            top : 20,
            right : 20,
            bottom : 30,
            left : 40
        }, width = 960 - margin.left - margin.right, height = 500 - margin.top
                - margin.bottom;

        var x = d3.scale.linear().range([ 0, width ]);

        var y = d3.scale.linear().range([ height, 0 ]);

        var color = d3.scale.category10();

        var xAxis = d3.svg.axis().scale(x).orient("bottom");

        var yAxis = d3.svg.axis().scale(y).orient("left");

        var zoom = d3.behavior.zoom().x(x).y(y).on("zoom", refresh);

        var svg = d3
                .select("body")
                .append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform",
                        "translate(" + margin.left + "," + margin.top + ")")
                .call(zoom)
                .append("g")
                .on(
                        "mousedown",
                        function() {
                            console.log("Mouse down");
                            var e = this;
                            var origin = d3.mouse(e);
                            var rect = svg.append("rect").attr("class", "zoom");
                            d3.select("body").classed("noselect", true);
                            origin[0] = Math.max(0, Math.min(width, origin[0]));
                            origin[1] = Math
                                    .max(0, Math.min(height, origin[1]));
                            d3.select(window).on(
                                    "mousemove.zoomRect",
                                    function() {
                                        console.log("Mouse moving");
                                        var m = d3.mouse(e);
                                        m[0] = Math.max(0, Math
                                                .min(width, m[0]));
                                        m[1] = Math.max(0, Math.min(height,
                                                m[1]));
                                        console.log(m[0]);
                                        console.log(m[1]);
                                        rect.attr("x",
                                                Math.min(origin[0], m[0]))
                                                .attr(
                                                        "y",
                                                        Math.min(origin[1],
                                                                m[1])).attr(
                                                        "width",
                                                        Math.abs(m[0]
                                                                - origin[0]))
                                                .attr(
                                                        "height",
                                                        Math.abs(m[1]
                                                                - origin[1]));
                                    }).on(
                                    "mouseup.zoomRect",
                                    function() {
                                        console.log("Mouse up");
                                        d3.select(window).on(
                                                "mousemove.zoomRect", null).on(
                                                "mouseup.zoomRect", null);
                                        d3.select("body").classed(
                                                "noselect", false);
                                        var m = d3.mouse(e);
                                        m[0] = Math.max(0, Math
                                                .min(width, m[0]));
                                        m[1] = Math.max(0, Math.min(height,
                                                m[1]));
                                        if (m[0] !== origin[0]
                                                && m[1] !== origin[1]) {
                                            zoom.x(
                                                    x
                                                            .domain([
                                                                    origin[0],
                                                                    m[0] ].map(
                                                                    x.invert)
                                                                    .sort()))
                                                    .y(
                                                            y.domain([
                                                                    origin[1],
                                                                    m[1] ].map(
                                                                    y.invert)
                                                                    .sort()));
                                        }
                                        rect.remove();
                                        refresh();
                                    }, true);
                            d3.event.stopPropagation();
                        });

        var data = [ {
            "x" : 30,
            "y" : 30,
            "r" : 20,
            "c" : "green",
            "s" : "s1"
        }, {
            "x" : 70,
            "y" : 70,
            "r" : 20,
            "c" : "purple",
            "s" : "s2"
        }, {
            "x" : 110,
            "y" : 100,
            "r" : 20,
            "c" : "red",
            "s" : "s3"
        } ];

        var data1 = [ {
            "x" : 30,
            "y" : 30
        }, {
            "x" : 70,
            "y" : 70
        }, {
            "x" : 90,
            "y" :90
        } ];

        x.domain(d3.extent(data, function(d) {
            return d.x;
        })).nice();
        y.domain(d3.extent(data, function(d) {
            return d.y;
        })).nice();

        svg.append("rect").attr("width", width).attr("height", height);

        svg.append("g").attr("class", "x axis").attr("transform",
                "translate(0," + height + ")").call(xAxis).append("text").attr(
                "class", "label").attr("x", width).attr("y", -6).style(
                "text-anchor", "end").text("Yield");

        svg.append("g").attr("class", "y axis").call(yAxis).append("text")
                .attr("class", "label").attr("transform", "rotate(-90)").attr(
                        "y", 6).attr("dy", ".71em").style("text-anchor", "end")
                .text("Skew")

        var line = d3.svg.line().x(function(d) {
            return x(d.x);
        }).y(function(d) {
            return y(d.y);
        });

        svg.append("path").datum(data1).attr("class", "line").attr("stroke",
                "steelblue").attr("stroke-width", 1.5).attr("d", line).attr(
                "fill", "none");

        svg.selectAll(".dot").data(data).enter().append("circle").attr("class",
                "dot").attr("r", 3.5).attr("cx", function(d) {
            return x(d.x);
        }).attr("cy", function(d) {
            return y(d.y);
        }).style("fill", function(d) {
            return color(d.c);
        });

        var legend = svg.selectAll(".legend").data(color.domain()).enter()
                .append("g").attr("class", "legend").attr("transform",
                        function(d, i) {
                            return "translate(0," + i * 20 + ")";
                        });

        legend.append("rect").attr("x", width - 18).attr("width", 18).attr(
                "height", 18).style("fill", color);

        legend.append("text").attr("x", width - 24).attr("y", 9).attr("dy",
                ".35em").style("text-anchor", "end").text(function(d) {
            return d;
        });

        function refresh() {
            svg.select(".x.axis").call(xAxis);
            svg.select(".y.axis").call(yAxis);
        }
</script>

问题是当用鼠标放大,x轴和y轴用放大范围更新但实际数据没有缩放时,看起来我在刷新方法中遗漏了一些东西,但我不知道。 (还在学习d3)

1 个答案:

答案 0 :(得分:1)

我几天前完成了Zoom,并假设我只需要更新轴,缩放将应用于整个可视化。但事实并非如此。您必须再次显式调用渲染(绘制矩形的位置)。然后,为了防止它添加重复的矩形,您必须正确处理updateexit部分。我看到你没有使用它。请在输入,更新,退出部分搜索教程。此外,还有关于D3 Wiki的教程(关于更新条形图等)。祝你好运。

相关问题