D3.js-使用下拉菜单缩放到bbox [英] D3.js - Zooming to bbox with a dropdown menu

查看:94
本文介绍了D3.js-使用下拉菜单缩放到bbox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在地图上,我想使用一个包含这些国家名称或ID的下拉菜单来放大特定国家/地区的bbox.

On a map I would like to zoom on the bbox of specific countries with a dropdown menu that contains the names or ids of those countries.

通过以下示例,我通过点击国家/地区实现了这一目标: https://bl. ocks.org/mbostock/4699541 . 但是,现在我不想通过单击国家/地区,而是在下拉菜单中选择国家/地区来实现此目的.

I achieved to do that by clicking on the country thanks to this example : https://bl.ocks.org/mbostock/4699541. But now I would like to do this not by clicking on the country but when I select it in a dropdown menu.

我在这里找到了一些答案:通过CSV文件使用d3将国家/地区放在下拉列表中.但这在我的情况下不起作用(我认为问题出在"jsonOutside.features.forEach(function(d)")部分).

I found some answers here : putting the country on drop down list using d3 via csv file. But it doesn't work in my case (I think the problem is with the "jsonOutside.features.forEach(function (d)" part).

我试图这样做,但是不起作用:

I tried that to do that but it doesn't work:

d3.select("#zoom").on("change", function() {    //trying to zoom on the bbox with the dropdown menu     
            var selected = this.value;          //but it doesn't work
            clicked(selected);          
});

我在此代码中放置了一个console.log,它向我返回了正确的值(国家/地区的ID).我也在"clicked"函数中完成了此操作,它为我返回了一个对象. 因此,我认为问题在于我的下拉菜单仅包含国家/地区名称,而不包含单击功能使用的国家/地区对象.

I placed a console.log in this code that returns me the right value (the id of the country). I've also done that in the "clicked" function and it returns me an object. So I think the problem is that my dropdown menu only contains countries names, not their objects that are used by the clicked function.

这是我其余的代码:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <script src="http://d3js.org/d3.v3.min.js"></script>
        <script src="http://d3js.org/topojson.v1.min.js"></script>
        <script src="http://d3js.org/queue.v1.min.js"></script>

        <style type="text/css">         
            #form {
                width: 20%;
                padding-top: 200px;
                margin-left: 2%;
            }

            #svg {
                display: block;
                margin-left: 30%;
                margin-top: -300px;
                border: 1px;
            }

            #map {
                border: 2px;
            }

        </style>
    </head>

    <body>
        </div>
            <form id="form">
                <fieldset>
                    <legend>Zoom on</legend>
                    <div>
                        <select id="zoom">
                            <option value="01">01</option> //options containing the countries id
                            <option value="02">02</option>
                            <option value="03">03</option>
                        </select>
                    </div>
                </fieldset>
            </form> 
            <div id="map"></div>
        </div>
    </body>
</html>
<script type="text/javascript">
var width = 600, height = 550, centered;

var path = d3.geo.path();

var projection = d3.geo.conicConformal() //focus on the topojson
    .center([2.454071, 47.279229])
    .scale(3000)
    .translate([width / 2, height / 2]);

path.projection(projection);

var svg = d3.select('#map').append("svg")
    .attr("id", "svg")
    .attr("width", width)
    .attr("height", height);

var departments = svg.append("g");

function clicked(d) { //zoom on bbox function
  var x, y, k;

  if (d && centered !== d) {
    var centroid = path.centroid(d);
    x = centroid[0];
    y = centroid[1];
    k = 4;
    centered = d;
  } else {
    x = width / 2;
    y = height / 2;
    k = 1;
    centered = null;
  }

  svg.selectAll("path")
      .classed("active", centered && function(d) { return d === centered; });

  svg.transition()
      .duration(750)
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -x + "," + -y + ")")
      .style("stroke-width", 1.5 / k + "px");
}

d3.json('https://gist.githubusercontent.com/PierreVivet/f46c2fe235ec7d7ab2db3dbaa163cc50/raw/f2f3fb092beb94f3a0582a9a82a040fa789028c1/departements.json', function(req, data) {
    data.objects.territoire.geometries.forEach(function (d) {
        d.properties = {};
        d.properties.code = d.code;
    });

    departments.selectAll("path")
        .data(topojson.feature(data, data.objects.territoire).features)
        .enter()
        .append("path")
        .attr("d", path)
        .attr('id', function(d) {return "d" + d.properties.code;})
        .style("fill", "white")
        .style("stroke", "black")
        .style("stroke-width", ".5px")
        .on("click", clicked); //the function works fine by clicking on the country
});

d3.select("#zoom").on("change", function() {    //trying to zoom on the bbox with the dropdown menu     
        var selected = this.value;              //but it doesn't work
        clicked(selected);          
});
</script>

您对此有任何想法吗?

谢谢

推荐答案

我找到了问题的答案.

我接近它,唯一的问题是我使用html手动创建了选择菜单.关键是直接用d3创建并填充它,因此我们可以在右边的'd'处使用onclick函数.

I was close to it, the only problem was that I manually created the select menu with html. The point is to create and populate it directly with d3, so we can use the onclick function with the right 'd'.

使用的代码如下:

var select = d3.select('#map')
    .append('select')

select.selectAll("option")
    .data(topojson.feature(data, data.objects.territoire).features)
    .enter().append("option")
    .text(function(d) { return d.properties.code; })
    .on("click", function(d) { clicked(d); });

那不是很复杂,但是由于我还是D3的新手,所以我需要了解语法.

That was not very complex, but as I'm still new to D3 I needed to understand the syntax.

感谢Lars Kotthoff在这里找到的答案: https://groups. google.com/forum/#!topic/d3-js/g6PLMZbRLvs

Thanks for Lars Kotthoff answers found here : https://groups.google.com/forum/#!topic/d3-js/g6PLMZbRLvs

这篇关于D3.js-使用下拉菜单缩放到bbox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆