通过 csv 文件使用 d3 将国家放在下拉列表中 [英] putting the country on drop down list using d3 via csv file

查看:35
本文介绍了通过 csv 文件使用 d3 将国家放在下拉列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

美好的一天,

我需要关于这个简单任务的帮助.我想要的只是在下拉列表中插入数据.当我在下拉列表中选择数据时,地图将根据所选值进行缩放.我已经有了关于每个国家/地区缩放的代码.但是当该国家/地区单击特定 tr 的国家/地区时,它就在表格中,地图将放大并且很好.问题是我想使用 d3 将国家/地区的值放入下拉列表中.有没有人可以帮我..

I need help regarding this simple task. All i want is to insert data in drop down. when i select data in drop down the map will zoom based on the selected value. i already have the code regarding the zooming of each country. but it is in the table when the country click on country of specific tr the map will zoom and it's fine. the problem is that i want to put that value of the country inside the drop down using d3. is can any one can help me..

这是我的代码.

          <!DOCTYPE html>
          <meta charset="utf-8">

             <style>

         .legend {
         font-size: 10px;
           z-index:0;

         }
          rect {
           fill: none;
                pointer-events: all;
           }

            .feature {
         fill: #ccc;
        cursor: pointer;
         }

         .feature.active {
           fill: orange;
       }

      .mesh {
fill: none;
stroke: #fff;
stroke-width: .5px;
stroke-linejoin: round;
      }

.csvTable table {
    border-collapse: collapse;
    text-align: left;
    width: 100%;
}

.csvTable {
    font: normal 12px/150% Arial, Helvetica, sans-serif;
    background: #fff;
    overflow: hidden;
    border: 1px solid #069;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
}

.csvTable table td, .csvTable table th {
    padding: 3px 10px;
}

.csvTable table thead th {
    background: 0;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#006699',endColorstr='#00557F');
    background-color: #006D2C;
    color: #FFF;
    font-size: 15px;
    font-weight: 700;
    border-left: 1px solid #0070A8;
}

    .csvTable table thead th:first-child {
        border: none;
    }

.csvTable table tbody td {
    color: #00496B;
    border-left: 1px solid #E1EEF4;
    font-size: 12px;
    border-bottom: 1px solid #E1EEF4;
    font-weight: 400;
}

    .csvTable table tbody td:first-child {
        border-left: none;
    }

.csvTable table tbody tr:last-child td {
    border-bottom: none;
}

.csvTable tr:hover td {
    background-color: #069;
    color: white;
}
</style>

  <script src="Script/d3.v3.min.js" ></script>
   <script src="Script/topojson.v1.min.js"></script>

  <!--<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->

       <body>
      <!-- Table to hold the Divs -->
           <table border="0" cellpadding="10" style="overflow-y: scroll;">
          <tr>
         <td><div id="country_select" class="csvTable"></div></td>
        <td><div id="table_container" class="csvTable"></div></td>
        <td><div id="map_container"></div></td>
    </tr>
     </table>

 <script>


var w = 900;
var h = 300;
var active;
var jsonOutside;

var projection = d3.geo.mercator()
     .center([0, 5])
     .rotate([0, 0])
     .scale(100)
     .translate([w / 2, h / 2])
     .precision(9);


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


var svg = d3.select("#map_container")
            .append("svg")
            .attr("width", w)
            .attr("height", h);

var color_domain = [1, 50000, 250000, 70000000, 150000000, 300000000];
var ext_color_domain = [100, 50000, 250000, 70000000, 150000000, 300000000];
var legend_labels = ["< 5000", "5000+", "100000+", "500000+", "7500000+", "> 15000000"];
// var legend_labels = ["< 5000", "5000+", "15000+", "35000+", "75000+", "> 150000"];
var color = d3.scale.log()
.domain(color_domain)

 .range(["#adfcad", "#ffcb40", "#ffba00", "#ff7d73", "#ff4e40", "#ff1300"]);
    // .range(["#adfcad", "#ccff66", "#ffff00", "#cc9933", "#0099ff", "#ff1300"])

      // from colorbrewer (http://colorbrewer2.org/)
         //var colours = ["#BAE4B3", "#74C476", "#31A354", "#006D2C"];


        //var colScale = d3.scale.ordinal()
         //                  .range(colours);

        svg.append("rect")
    .attr("width", w)
    .attr("height", h)
    .on("click", reset);

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

      d3.csv("data/TotalReputationBlocked.csv", function (data) {
    d3.json("data/world-population.geo.json", function (json) {

        json.features.forEach(function (d, i) {
            data.forEach(function (e, j) {
                if (d.properties.name === e.Country) {
                    d.properties.value = +e.Result;
                };
            })
        })

        jsonOutside = json; // pass json to a global so tableRowClicked has access


        var dispatch = d3.dispatch("load", "countrychange");
        d3.csv("data/ERSReputationBlocked.csv", type, function (error, country) {
            if (error) throw error;
            var countryById = d3.map();
            country.forEach(function (d) { countryById.set(d.id, d); });
            dispatch.load(countryById);
            dispatch.countrychange(countryById.get("Philippines"));

        });
        dispatch.on("load.menu", function (countryById) {
            var select = d3.select("body")

              .append("div")
              .append("select")
              //.on("change", function () { dispatch.countrychange(countryById.get(this.value)); });

                .on("click", click)
            // .on("change", function (d) { tableRowClicked(d); });

            select.selectAll("option")
              .data(countryById.values())
              .enter().append("option")
              .attr("value", function (d) { return d.id; })
              .text(function (d) { return d.Country; });

            dispatch.on("countrychange.map", function (d) {
                select.property("value", d)
                //.on("click",tableRowClicked)
               .on("click", click)
            //    //end of selection
            });
        });
        //end of selection
        //var columns = ["Country", "Result"];
        //var table = d3.select("#table_container").append("table"),
        //      thead = table.append("thead"),
        //      tbody = table.append("tbody");

        //// append the header row
        //thead.append("tr")
        //      .selectAll("th")
        //      .data(columns)
        //      .enter()
        //      .append("th")
        //      .text(function (column) { return column; });


        //// create a row for each object in the data
        //var rows = tbody.selectAll("tr")
        //     .data(data)
        //     .enter()
        //     .append("tr");


        //// create a cell in each row for each column
        //var cells = rows.selectAll("td")
        //     .data(function (row) {
        //         return columns.map(function (column) {
        //             return { column: column, value: row[column] };
        //         });
        //     })
        //     .enter()
        //     .append("td")
        //     .text(function (d) { return d.value; }
        //     )
        //     .on("click", function (d) { tableRowClicked(d); }); // added on click event to td         element NB you need to click on the cell with the conuty name 

        // add extents (max and min) from data results for choropleth
        //color.domain(d3.extent(data, function (d) { return d.Result; }));



                //Bind data and create one path per GeoJSON feature
                g.selectAll("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .attr("class", "feature")
                   .attr("id", function (d) { return d.properties.name; }) // added id so click could work on id which is common between the json and csv data

                    //.on("click",function (d) { tableRowClicked(d); })
                     .on("click", function (d) { click(d); })
                   .style("stroke", "white")
                   //.style("fill", function (d, i) { return colScale(d.properties.value); }); // fill based on colour scale
                 .style("fill", function (d) {
                     return color(d.properties.value);
                 });

                g.append("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("class", "mesh")
                   .attr("d", path);

            });
        });




        function type(d) {
            d.total = d3.sum(d.value, function (k) { return d[k] = +d[k]; });
            return d;
        }



var legend = svg.selectAll("g.legend")
.data(ext_color_domain)
.enter().append("g")
.attr("class", "legend");

var ls_w = 20, ls_h = 20;

legend.append("rect")
.attr("x", 20)
.attr("y", function (d, i) { return h - (i * ls_h) - 2 * ls_h; })
.attr("width", ls_w)
.attr("height", ls_h)
.style("fill", function (d, i) { return color(d); })
.style("opacity", 0.8);

legend.append("text")
.attr("x", 50)
.attr("y", function (d, i) { return h - (i * ls_h) - ls_h - 4; })
.text(function (d, i) { return legend_labels[i]; });









function click(d) {

    if (active === d) return reset();
    g.selectAll(".active").classed("active", false);
    d3.select("#" + d.properties.name).classed("active", active = d); // changed selection to id

    var b = path.bounds(d);

    g.transition().duration(1000).attr("transform",
        "translate(" + projection.translate() + ")"
        + "scale(" + .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h) + ")"
        + "translate(" + -(b[1][0] + b[0][0]) / 2 + "," + -(b[1][1] + b[0][1]) / 2 + ")");
}

function reset() {
    g.selectAll(".active").classed("active", active = false);
    g.transition().duration(750).attr("transform", "");
}

function tableRowClicked(x) {
    jsonOutside.features.forEach(function (d) { // loop through json data to match td entry
        if (x.value === d.properties.name) {
            alert(x.value)
            var country = d;
            click(d); // pass json element that matches td data to click 
        };
    })
}

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

这段代码工作正常,唯一的问题是我不能把那个国家放在下拉菜单中,我希望有人可以帮助我..

this code works fine the only problem is that i cant put that country on the drop down, I hope there's some one who can help me..

感谢程序员

推荐答案

HTML 中的下拉菜单是通过使用 元素而不是

元素,如下所示:

To create this structure, you can just go through and adapt the part of the original code where it created the table. You start by creating a <select> element instead of a <table> element, like this:

var dropDown = d3.select("#table_container").append("select")
                    .attr("name", "country-list");

您可以跳过 theadtbody 部分,因为下拉菜单的结构要简单得多.然后,我们不是连接数据来创建tr(表格行)元素的选择,而是连接它来创建option 元素的选择:

You can skip the thead and tbody parts, since the structure of the dropdown menu is so much simpler. Then, instead of joining data to create a selection of tr (table row) elements, we join it to create a selection of option elements:

var options = dropDown.selectAll("option")
               .data(data) // eg., data = [ {'value': 10}, {'value': 11}, {'value': 12} ]
               .enter()
               .append("option");

然后根据数据添加value属性和option元素的文本内容:

Then add the value attribute and the text content of the option element based on the data:

options.text(function (d) { return d.value; })
       .attr("value", function (d) { return d.value; });

我希望这一切都是直截了当的.当您添加事件处理程序时,它会变得有点复杂.

I hope that's all straight-forward. It gets a little more complicated when you add the event handler.

不是响应单个国家/地区名称上的点击"事件,而是将下拉列表的事件处理程序作为一个整体添加到列表中,并响应 "change" 事件:

Instead of responding to a "click" event on an individual country name, the event handler for a drop-down list is added to the list as a whole, and responds to a "change" event:

dropDown.on("change", menuChanged);

因为事件处理程序附加到整个列表,而不是附加到每个单独的选项元素,但是,它无法从所选元素传递 d 数据对象.相反,所选元素的 value 属性存储在全局 d3.event 对象,如d3.event.target.value.这就是为什么我小心地设置每个选项元素的 value 属性以匹配数据对象的 value 属性.

Because the event handler is attached to the entire list instead of to each individual option element, however, it can't get passed the d data object from the element that was selected. Instead, the value attribute of the selected element is stored within the global d3.event object, as d3.event.target.value. This is why I was careful to set the value attribute of each option element to match the value property of the data object.

因此您需要做的最后一件事是更改您的事件处理程序方法以使用事件值而不是传入的数据值:

So the final thing you need to do is to change your event handler method to use the event value instead of a passed-in data value:

/*  BEFORE
function tableRowClicked(x) {
      //x is the data object for that individual table row

    jsonOutside.features.forEach(function (d) { 
        // loop through json data to match td entry

        if (x.value === d.properties.name) {
        //for each data object in the features array (d), compare it's
        //name against the one in the table row data object

            alert(x.value)
            var country = d; //this does nothing...
            click(d); // pass json element that matches td data to click 
        };
    })
}
//*/
//* AFTER
function menuChanged() {
          //the name isn't important, but has to match the name
          //you added to the menu's "change" event listener.

    var selectedValue = d3.event.target.value;  
         //get the name of the selected option from the change event object

    jsonOutside.features.forEach(function (d) { 
        // loop through json data to match td entry

        if (selectedValue === d.properties.name) {
        //for each data object in the features array (d), compare it's
        //name against the one you got from the event object
        //if they match, then:

            alert(selectedValue)  //remove this line when things are working!

            click(d); // pass json element that matches selected value to click
             //which will respond the same way as if you clicked the country on
             //the map. 
        };
    })
}
//*/

我在此处的下拉菜单中有一个稍微简单的事件示例:
http://fiddle.jshell.net/7KJC7/2/
选项元素在 HTML 中预先编码而不是从数据创建,但我展示了如何从 d3.event 对象访问有关选择的不同类型的数据,并与发生的情况进行比较(没有) 当您尝试将事件处理程序放在单个 元素上时.

I've got a slightly simpler example of an event on a drop-down menu here:
http://fiddle.jshell.net/7KJC7/2/
The option elements are pre-coded in the HTML instead of created from data, but I show how to access different types of data about the selection from the d3.event object, and compare with what happens (nothing) when you try to put the event handler on the individual <option> elements.

这篇关于通过 csv 文件使用 d3 将国家放在下拉列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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