javascript - 如何使用 d3 获取 svg 图像的缩放级别

标签 javascript d3.js svg

我有一个与 geojson 并排的 svg 图像。两幅图像中都有相应的物体。我已经使用 d3 添加了它们。我目前可以分别缩放和平移它们。现在,每当用户滚动任何图像时,我想获取缩放级别的值。我想在控制台上打印出该值。无论哪个滚动(放大或缩小),每个缩放滚动的值都应该打印到控制台。这是我的代码:

<!doctype html>
<html lang="en">    
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>Sketch-To-Metric Map Alignment by Qualitative Spatial Constraint Matching</title>

    <!-- the data of the map -->
    <script src="img/sketchmap_ids.json"></script>

    <!--Add support for earlier versions of Internet Explorer -->
    <!--[if lt IE 9]>
    <script src="lib/js/html5shiv.js"></script>
    <![endif]-->

    <filter id="offset" x="-20%" y="-10%" height="130%">
     <feGaussianBlur  in="SourceAlpha" stdDeviation="5"/>
      <feOffset dx="5" dy="5" result="B"/>
     <feMerge>
      <feMergeNode in="B"/>
      <feMergeNode in="SourceGraphic"/>
      </feMerge>
    </filter>

    <filter id="dropshadow_2" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
      <feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
      <feMerge> 
        <feMergeNode/> <!-- this contains the offset blurred image -->
        <feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
      </feMerge>
    </filter>
    <!-- circle r="10" style="filter:url(#dropshadow)"/ -->

    <filter id="dropshadow" height="130%">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3"/> 
      <feOffset dx="2" dy="2" result="offsetblur"/>
      <feComponentTransfer>
        <feFuncA type="linear" slope="0.2"/>
      </feComponentTransfer>
      <feMerge> 
        <feMergeNode/>
        <feMergeNode in="SourceGraphic"/> 
      </feMerge>
    </filter>

    <style>
        .shadow {
            -webkit-filter: drop-shadow( 5px 5px 5px 10px);
                    filter: drop-shadow( 5px 5px 2px); /* Same syntax as box-shadow */

        }
        .reveal section img { background:none; border:none; box-shadow:none; }
        .service {
            stroke-width: 4;
            stroke: #999999;
            fill: none;
        }
        .residential-line {
            stroke-width: 8;
            stroke: #b3b3b3;
            fill: none;
        }
        .fence,.footway,.cycleway,.track,.path,.pedestrian,.steps {
            stroke-width: 2;
            stroke: #2b1100;
            stroke-dasharray: 3,2,3;
            fill: none;
        }
        .primary {
            stroke-width: 18;
            stroke: #b3b3b3;
            fill: none;
        }
        .tertiary {
            stroke-width: 12;
            stroke: #b3b3b3;
            fill: none;
        }
        .bridge {
            stroke-width: 12;
            stroke: #cd853f;
            fill: none;
        }
        .graveyard {
            stroke-width: 2;
            stroke: #444444;
            stroke-dasharray: 3,2,3;
            fill: #668000;
        }
        .waterway-line,.river-line,.weir {
            stroke-width: 5;
            stroke: #2A7FFF;
            fill: none;
        }
        .water {
            stroke-width: 1;
            stroke: #0066FF;
            fill: #2A7FFF;;
        }
        .scrub,.forest {
            stroke-width: 1;
            stroke: #008033;
            fill: #008033;
        }
        .grass,.village_green,.greenhouse {
            stroke-width: 1;
            stroke: #5FD35F;
            fill: #5FD35F;
        }
        .residential,.commercial {
            stroke-width: 1;
            stroke: #FFF6D5;
            fill: #FFF6D5;
        }
        .parking,.bicycle_parking {
            stroke-width: 1;
            stroke: #FFE680;
            fill: #FFE680;
        }
        .university,.civic,.yes,.house,.school {
            stroke-width: 0;
            fill: #916F6F;
        }
        .map-panel {
            width: 100%;   
            border: 1px solid #444444;
        }
        #sketch3,#sketch4,#sketch5,#sketch6,#sketch10,#sketchgraph11,#sketchgraph12 {
            width: 45%;
            float: left;
            padding-bottom:0px;
        }

        #metric3,#metric4,#metric5,#metric6,#metric10,#metricgraph11,#metricgraph12 {
            width: 45%;
            float: right;
            padding-bottom:0px;
        }

        .text-pane-left {
            width: 45%;
            float: right;
            padding-bottom:0px;
        }

        .text-pane-right {
            width: 45%;
            float: right;
            padding-bottom:0px;
        }

        #mynetwork {
            width: 854px;    
            height: 480px; 
            position: relative; 
            border: 1px solid #444444;
            background-color: #dddddd;
        }

        #othernetwork {
            width: 800px;    
            height: 600px; 
            position: relative; 
            border: 1px solid #444444;
            background-color: #dddddd;
        }

        #visualization {
            width: 800px;    
            height: 600px; 
            position: relative; 
            border: 1px solid #444444;
            background-color: #dddddd;
        }

        body {
            color: #d3d3d3;
            font: 12pt arial;
            background-color: #ffffff;
        }
    </style>  
</head>

<body>

    <div class="map-panel" id="panel">
        <div class="map-pane-left" id="sketch4"></div>
        <div class="map-pane-right" id="metric4"></div>
    </div>                                                  

    <script src="d3/d3.min.js"></script>
    <script src="d3/topojson.min.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>





    <script>



        //load sketch map

        d3.xml("img/sketch_all_in_components_web.svg").mimeType("image/svg+xml").get(function(error, xml)           {
            if (error) throw error;

            function sketchMapZoomed() {
                    svg.selectAll("*").attr("transform", "translate(" + d3.event.translate + ")" + "                        scale(" + d3.event.scale + ")")
            }

      //var copy = xml.documentElement.cloneNode(true);
            document.getElementById('sketch4').appendChild(xml.documentElement);
            d3.select('#sketch4').selectAll('g,                                                                     path').on('mouseenter',animateMapTargets).on('mouseleave',removeFilter);      
            var svg = d3.select("svg")
            .call(d3.behavior.zoom().on("zoom", sketchMapZoomed ))
        });



        //load metric map




        var width = document.getElementById("sketch4").clientWidth;
        height = (width * 0.71053942806206943134954217685331);

        function metricMapZoomed () {
              svg.attr("transform", d3.event.transform)
      }

        var svg = d3.select("#metric4").append("svg")
            .attr("width", width)
            .attr("height", height)
            .attr("id", "metricmap")
            .call(d3.zoom().on("zoom", metricMapZoomed ))
      .append("g");

        //create a place holder rectangle to keep floats inline
        var svgContainer = d3.select("body").append("svg")
            .attr("width", width)
            .attr("height", width)
            .attr("id", "placeholder");

        d3.json("img/defense_data.json", function(error, map) {
            if (error) return console.error(error);

            var projection = d3.geo.mercator()
                .center([7.612337603149424, 51.96211781909236])
                .scale(3000000);
                //.translate(0,0);

            var path = d3.geo.path()
                .projection(projection);

            svg.selectAll(".city_block_landmarks")
                .data(topojson.feature(map, map.objects.city_block_landmarks).features)
                .enter().append("path")
                .attr("class", function(d){
                    //console.log(d.properties.class)
                    return d.properties.classfeature;
                })
                .attr("id", function(d){
                    //console.log(d.id)
                    return d.id;
                })
                .attr("d", path);

            svg.selectAll(".hidden_landmarks")
                .data(topojson.feature(map, map.objects.hidden_landmarks).features)
                .enter().append("path")
                .attr("class", function(d){
                    //console.log(d.properties.class)
                    return d.properties.classfeature;
                })
                .attr("id", function(d){
                    //console.log(d.id)
                    return d.id;
                })
                .attr("d", path);

            svg.selectAll(".botanica_mid_polygons")
                .data(topojson.feature(map, map.objects.botanica_mid_polygons).features)
                .enter().append("path")
                .attr("class", function(d){
                    //console.log(d.properties.class)
                    return d.properties.classfeature;
                })
                .attr("id", function(d){
                    //console.log(d.id)
                    return d.id;
                })
                .attr("d", path);

            svg.selectAll(".streets_linear_features")
                .data(topojson.feature(map, map.objects.streets_linear_features).features)
                .enter().append("path")
                .attr("class", function(d){
                    //console.log(d.properties.class)
                    return d.properties.classfeature;
                })
                .attr("id", function(d){
                    //console.log(d.id)
                    return d.id;
                })
                .attr("d", path);   
        });

        //animate objects on mouse on and remove animation on mouse off
        function animateMapTargets() {          
            if (this.id)
                if (targets[this.id])
                    targets[this.id].forEach(animateTargetNode);
        };

        function animateTargetNode(obj, i) {
            //console.log(d3.select('#'+obj)./*node().*/style('filter','url(#offset)'));
            //d3.select('#'+obj).style('filter','url(#offset)');
            //console.log(d3.select('#'+obj).classed("shadow", true));//
            d3.select('#'+obj).classed("shadow", true);
                //.attr()  style="filter:url(#dropshadow)"
                //.attr();
        }

        function removeFilter() {           
            if (this.id)
                if (targets[this.id])
                    targets[this.id].forEach(function animateTargetNode(obj, i) {
                        //d3.select('#'+obj).style('filter','none');
                        d3.select('#'+obj).classed("shadow", false);
                    });
        };




    </script>   
</body>
</html>

最佳答案

zoom events有一个 transform 属性:

event.transform - the current zoom transform.

zoom transform documentation对它的内部实现方式和原因有很好的解释。简而言之,它们被实现为一个可以表示平移和缩放的矩阵,并且 transform 通过属性公开它们。 “缩放级别”将是比例:

transform.k - the scale factor k.

因此像这样的 zoom 事件处理程序应该可以工作:

function zoomed(event) {
    console.log(event.transform.k);
}

关于javascript - 如何使用 d3 获取 svg 图像的缩放级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48422545/

相关文章:

javascript - 您如何仅在 div 中获取按钮?没有 JQuery

javascript - 第二次转换不起作用

javascript - 从 d3 获取图案并将其设置为 div 的边框

javascript - 如何在 sankey 中添加带有工具提示的节点名称列表

javascript - 在 AngularJS 中启动一个指令后不调用 $watch

javascript - 如何在将文本附加到 div 时将 onclick 内的文本引用为 onclick= "' +var +' "

javascript - 从 onChange 输入元素中调用的函数获取索引值

javascript - D3 将连续输入映射到预定离散箱时色标困惑?

node.js - jsdom.env 不是将 svg 导出到图像的函数

html - 如何在 svg 中显示 html 编码值?