【问题标题】:d3.js choropleth map --How do I map more than one property from CSV to JSON, so I can use it in a tooltip?d3.js choropleth map --如何将多个属性从 CSV 映射到 JSON,以便可以在工具提示中使用它?
【发布时间】:2015-12-15 15:58:26
【问题描述】:

我有一个用 d3.js 构建的等值线图。我将 data.csv 中的“Total_Score”属性映射到 JSON 文件中的“id”属性,并使用该分数为状态着色。我还在鼠标悬停时使用工具提示显示它。

不过,我也希望能够显示我的 CSV 文件中的其他属性。还有其他四个——“排名”、“第一”、“第二”和“第三”。我是否也必须为每一个创建地图?我从未绘制过多个地图,因此非常感谢任何指导或示例。

谢谢!

Here is a plunker for reference.

代码如下:

<!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8">
            <title>Worst Drivers</title>
            <script src="http://d3js.org/d3.v3.min.js"></script>
            <script src="d3.tip.js"></script>
            <style type="text/css">
                body{
                    background:#333;
                    font-family:Helvetica, Arial, sans-serif;
                    font-size:13px;
                    color:#fff;
                    padding:0px;
                    margin:0px;
                }
                h1{
                    margin:50px 0px 0px;
                    text-align:center;
                    font-size:30px;
                    font-weight:normal;
                }
                h2{
                    margin:0px;
                    padding:0px;
                }
                h4{
                    font-size:16px;
                }
                a{
                    text-decoration: none;
                    color: #2bbe8c;
                }
                #panel{
                    background:#fff;
                    color:#111;
                    width:27%;
                    height:100%;
                    float:right;
                    padding:3%;
                }
                #map{
                    width:66%;
                    float:left;
                }
                .sources{
                    font-size:12px;
                }
                .d3-tip{
                    background:#000;
                    opacity:.7;
                    padding:20px;
                    border-radius:3px;
                }
                .statename{
                    font-size:16px;
                }
                .mainno{
                    font-size:14px;
                }
                #legend{
                    position:absolute;
                    width:66%;
                    height:20px;
                }
                #legendinner{
                    margin:0 auto;
                    position:relative;
                    width:245px;
                }
                .legendleft{
                    width:50px;
                    float:left;
                    margin:0px;
                }
                .legendright{
                    width:50px;
                    float:right;
                    text-align:right;
                    margin:0px;
                }
            </style>
        </head>
        <body>
            <div id="container">
                <div id="map">
                    <div id="legend">
                        <div id="legendinner">
                            <svg width="250" height="15">
                                <rect x="0" y="0" width="50" height="10" fill="#041e47"></rect>
                                <rect x="50" y="0" width="50" height="10" fill="#063685"></rect>
                                <rect x="100" y="0" width="50" height="10" fill="#0449bb"></rect>
                                <rect x="150" y="0" width="50" height="10" fill="#055ced"></rect>
                                <rect x="200" y="0" width="50" height="10" fill="#5092ff"></rect>
                            </svg>
                            <p class="legendleft">Most</p>
                            <p class="legendright">Least</p>
                        </div>
                    </div>
                </div>
            </div>

            <script type="text/javascript">

                //Width and height
                var w = Math.max(window.innerWidth) / 3 *2;
                var h = Math.max(window.innerHeight) - 100;

                //Create SVG element
                map  = d3.select("#map")
                         .append("svg")
                                 .attr("id", "usstates")
                         .attr("width",  w)
                         .attr("height", h);

          var maph = document.getElementById('usstates').clientHeight;

                d3.select("#legend")
                .style("top", maph + 150 + "px");

                //Define map projection
                var p = d3.geo.albersUsa()
                        .translate([w/2, h/2])
                        .scale([1000]);

                //Define path generator
                var path = d3.geo.path()
                        .projection(p);



              //load the geoJSON file for drawing the map
                d3.json("states.json", function(error, states) {

                    var newDict = {}; //mapping for choropleth
                    var tip = d3.tip()
                            .attr('class', 'd3-tip')
                            .offset([40, 0])
                            .html(function(d,i) { 
                                return "<span class='statename'>" + d.properties.name + "</span>" + 
                                "<hr/>" +
                                "<span class='mainno'>Total Score: " + newDict[d.id] + 
                                "<br/>rank: </span>" +
                                "<hr/>" + 
                                "First: " +
                                "<br/>Second: " +
                                "<br/>Third: " ;
                            })

                    var mapstates = map.append("svg:g")
                            .attr("id", "states")
                            .style("fill", "#dedee0")
                            .style("stroke", "#aaa")
                            .style("stroke-width", .5);

                            mapstates.call(tip);

                    mapstates
                                    .selectAll("path")
                                    .data(states.features)
                                .enter().append("path")
                                .attr("d", path);

                        d3.csv("data.csv", function(error, data) {

                            data.forEach(function(d){
                              d.rank = + d.rank;
                                d.Total_Score   = +d.Total_Score;
                              newDict[d.id] = +d.Total_Score;
                            });

                            var minValue = d3.min(data, function(d,data) { return d.Total_Score; });
                            var maxValue = d3.max(data, function(d,data) { return d.Total_Score; });

                            //Quantize scale for map
                            var color = d3.scale.quantize()
                                    .domain([minValue, maxValue])
                                    .range(["#041e47", "#063685", "#0449bb", "#055ced", "#5092ff"]);



                            mapstates
                                            .selectAll("path")
                                        .attr("d", path)
                                            .on('mouseover', function(d) {

                                               d3.select(this).style('fill-opacity', .75);
                                            })
                                            .on('mouseout', function(d){
                                                d3.select(this).style("fill-opacity", 1);
                                            })
                                            .on('mouseover', tip.show)
                                            .on('mouseout', tip.hide)
                                            .attr("class", function(d){return newDict[d.id];})
                                            .attr("fill", function(d) { return color(newDict[d.id]); })
                                            .text("heyo");

                            mapstates.selectAll("text")
                                            .data(states.features)
                                            .enter()
                                            .append("text")
                                            .html(function(d){
                                                 return d.properties.abbr + ": " + newDict[d.id] ;
                                            })
                                            .attr("x", function(d){
                                                return path.centroid(d)[0];
                                            })
                                            .attr("y", function(d){
                                                 return  path.centroid(d)[1];
                                            })
                                            .attr("text-anchor","middle")
                                            .attr('font-size',11)
                                            .attr('font-weight', 'normal');

                        }); //close csv
                }); // close json

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

data.csv 文件:

"State","id","first","second","third","TotalScore","rank"
    "Alabama",1,15,24,29,113,18
    "Alaska",2,22,51,50,195,49
    "Arizona",4,14,28,41,109,14
    "Arkansas",5,5,21,43,141,28
    "California",6,42,26,39,146,33
    "Colorado",8,33,4,24,101,11
    "Connecticut",9,48,44,9,185,47
    "Delaware",10,21,31,12,74,7
    "District of Columbia",11,51,8,32,139,27
    "Florida",12,19,29,30,131,24
    "Georgia",13,28,11,46,147,34
    "Hawaii",15,20,33,6,70,5
    "Idaho",16,27,20,36,152,38
    "Illinois",17,39,39,10,125,22
    "Indiana",18,36,19,34,165,42
    "Iowa",19,25,38,48,205,50
    "Kansas",20,17,15,47,151,37
    "Kentucky",21,6,2,49,131,24
    "Louisiana",22,7,5,19,71,6
    "Maine",23,26,10,17,103,12
    "Maryland",24,41,50,18,141,28
    "Massachusetts",25,50,37,8,156,39
    "Michigan",26,37,42,37,179,45
    "Minnesota",27,49,34,35,205,50
    "Mississippi",28,8,12,26,111,17
    "Missouri",29,24,18,13,91,10
    "Montana",30,3,6,1,59,2
    "Nebraska",31,29,16,7,141,28
    "Nevada",32,30,14,14,79,8
    "New Hampshire",33,43,46,33,190,48
    "New Jersey",34,46,43,21,160,40
    "New Mexico",35,11,27,42,109,14
    "New York",36,40,36,20,143,31
    "North Carolina",37,23,35,23,109,14
    "North Dakota",38,4,3,2,66,4
    "Ohio",39,35,22,15,135,26
    "Oklahoma",40,9,1,31,87,9
    "Oregon",41,34,49,45,184,46
    "Pennsylvania",42,18,32,25,105,13
    "Rhode Island",44,44,48,4,147,34
    "South Carolina",45,1,30,3,54,1
    "South Dakota",46,10,7,11,114,20
    "Tennessee",47,13,25,27,143,31
    "Texas",48,12,23,5,63,3
    "Utah",49,45,9,51,169,44
    "Vermont",50,31,13,40,113,18
    "Virginia",51,38,40,38,163,41
    "Washington",53,47,47,22,165,42
    "West Virginia",54,2,45,44,116,21
    "Wisconsin",55,32,17,16,130,23
    "Wyoming",56,16,41,28,149,36

(我无法在此处粘贴 states.json 文件,因为它超出了帖子允许的正文大小,但您可以转到 Plunker。)

【问题讨论】:

    标签: javascript json csv d3.js


    【解决方案1】:

    您可以创建对象并将它们放入您的 newDict。任何其他集合也可以。

    以下是添加具有排名和分数属性的新对象的代码。

    data.forEach(function(d){
      d.rank = d.rank;
      d.Total_Score = d.Total_Score;
      newDict[d.id] = {rank:d.rank, score:d.Total_Score};
    });
    

    这些可以像普通对象一样使用。

    mapstates
        .selectAll("path")
        .attr("d", path)
        .on('mouseover', function(d) {
            d3.select(this).style('fill-opacity', .75);
        })
        .on('mouseout', function(d){
            d3.select(this).style("fill-opacity", 1);
        })
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide)
        .attr("class", function(d){return newDict[d.id];})
        attr("fill", function(d) { return color(newDict[d.id].score); });
    

    添加任意数量的值是对 data.forEach 闭包的简单添加。

    Here's my fork 你的 plunker 已经实施了一些更改。

    【讨论】:

    • 太棒了!感谢您提供如此巨大的帮助!
    猜你喜欢
    • 2016-12-23
    • 2019-11-23
    • 1970-01-01
    • 2013-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多