&#34;错误:<path>属性d:预期数量&#34;

时间:2016-08-09 10:08:17

标签: javascript csv d3.js svg cartogram

我尝试使用cartogram.js和d3.js创建一个制图。我已经使用了cartogram.js repo和here中的示例来组合一个脚本,该脚本使用d3.geo.mercator()投影生成SVG内的世界地图,现在我正在尝试使用cartogram.js库扭曲地图但是我收到以下错误:

d3.js:8756 Error: <path> attribute d: Expected number, "MNaN,NaNLNaN,NaNL…".
   (anonymous function) @ d3.js:8756
   tick @ d3.js:8956
   (anonymous function) @ d3.js:8936
   d3_timer_mark @ d3.js:2166
   d3_timer_step @ d3.js:2147

这是我用来歪曲地图的代码:

var dataLoaded = new Event("dataLoaded"),
svg = d3.select("svg"),
proj = d3.geo.mercator(),
path = d3.geo.path()
    .projection(proj),
countries = svg.append("g")
    .attr("id", "countries")
    .selectAll("path"),
carto = d3.cartogram()
    .projection(proj)
    .properties(function(d) {
        return d.properties
    }),
mapData = d3.map(),
geometries,
topology

function init() {
    d3.csv("data/data.csv", function(data) {
        data.forEach(function (d) {
            mapData.set(d.COUNTRY, d.VALUE)
        })
    })

    d3.json("data/world.json", function(data) {
        topology = data
        geometries = topology.objects.countries

        var features = carto.features(topology, geometries)

        countries = countries
            .data(features)
            .enter()
            .append("path")
            .attr("fill", function (e) {
                return "#000000"
            })
            .attr("d", path)

        document.dispatchEvent(dataLoaded)
    })
}

document.addEventListener("dataLoaded", function() {
    $("#container").css("visibility", "visible").hide().fadeIn("fast")
    $("header").css("visibility", "visible").hide().fadeIn("slow")

     carto.value(function(d) {
        return +mapData.get(d.properties.name)
     })

     countries.data(carto(topology, geometries).features)

     countries.transition()
        .duration(750)
        .attr("d", carto.path);
})

init()

以及包含我想用来扭曲地图的数据的CSV文件:

COUNTRY,VALUE
Afghanistan,90
Albania,390
Algeria,90
Andora,110
Angola,10
Antigua,2400
Argentina,320
Armenia,40
Australia,6600
Austria,1300
Axerbaijan,0
Bahamas,1900
Bahrain,90
Bangladesh,50
Barbados,8100
Belarus,20
Belgium,260
Belize,480
Benin,0
Bhutan,170
Bolivia,90
Bosnia,70
Botswana,110
Brazil,1300
Brunei,40
Bulgaria,3600
Burkina Faso,0
Burundi,0
Cabo Verde,0
Cambodia,720
Cameroon,10
Canada,4400
Central African Republic,0
Chad,10
Chile,320
China,1600
Combodia,0
Comoros,10
Congo,20
Costa Rica,2900
Cote d'Ivoire,0
Croatia,9900
Cuba,14800
Cyprus,8100
Czech Republic,70
Denmark,320
Dijbouti,0
Dominica,0
Dominican Republic,4400
Ecuador,90
Egypt,6600
El Salvador,10
Equatorial Guinea,0
Eritrea,10
Estonia,110
Ethiopia,70
Fiji,1900
Finland,720
France,2900
Gabon,10
Gambia,2400
Georgia,70
Germany,880
Ghana,210
Greece,14800
Grenada,720
Guatemala,40
Guinea,0
Guinea - Bissau,0
Guyana,50
Haiti,90
Honduras,110
Hungary,170
Iceland,8100
India,2900
Indonesia,390
Iran,390
Iraq,140
Ireland,1900
Israel,590
Italy,9900
Jamaica,6600
Japan,3600
Jordan,480
Kazakhstan,40
Kenya,1000
Kiribati,10
Kosovo,10
Kuwait,40
Kyrgyzstan,10
Laos,70
Latvia,110
Lebanon,70
Lesotho,0
Liberia,10
Libya,30
Liechtenstein,10
Lithuania,70
Luxembourg,50
Macedonia,70
Madagascar,0
Malawi,40
Malaysia,1300
Maldives,12100
Mali,40
Malta,12100
Marshall Islands,10
Mauritania,10
Mauritius,6600
Mexico,18100
Micronesia,20
Moldova,20
Monaco,590
Mongolia,110
Montenegro,880
Morocco,4400
Mozambique,90
Myanmar,90
Namibia,210
Nauru,10
Nepal,0
Netherlands,50
New Zealand,1900
Nicaragua,50
Niger,10
Nigeria,90
North Korea,390
Norway,1600
Oman,590
Pakistan,110
Palau,50
Palestine,10
Panama,210
Papua New Guinea,40
Paraguay,10
Peru,1000
Philippines,590
Poland,880
Portugal,12100
Qatar,210
Romania,320
Russia,480
Rwanda,20
Saint Kitts and Nevis,0
Saint Lucia,90
Saint Vincent and the Grenadines,0
Samoa,90
San Marino,70
Sao Tome and Principe,10
Saudi Arabia,110
Senegal,70
Serbia,50
Seychelles,1600
Sierra Leone,20
Singapore,880
Slovakia,70
Slovenia,390
Solomon Islands,10
Somalia,70
South Africa,1900
South Korea,140
South Sudan ,0
Spain,14800
Sri Lanka,3600
Sudan,20
Suriname,10
Sweden,720
Switzerland,1300
Syria,590
Taiwan,50
Tajikistan,10
Tanzania,260
Thailand,14800
Timor-Leste,0
Togo,10
Tonga,50
Trinidad and Tobago,140
Tunisia,4400
Turkey,9900
Turkmenistan,10
Tuvalu,30
Uganda,50
Ukraine,70
United Arab Emirates,20
United Kingdom,50
United States of America,3600
Uruguay,50
Uzbekistan,30
Vanuatu,30
Vatican City,30
Venezuela,170
Vietnam,2400
Yemen,20
Zambia,90
Zimbabwe,70

我没有在此项目之前使用d3.js的任何经验,所以我希望您能给我任何反馈/指导。

我正在使用d3版本3.5.17,fyi。

感谢。

UPDATE - 9/8/2016 15:22 BST

根据@Mark的建议,我已经实施d3-queue,但问题仍然存在。但是,如果我对此实施做了任何错误,我会感激任何人都可以给我的任何见解! :)

var svg = d3.select("svg"),
proj = d3.geo.mercator(),
path = d3.geo.path()
    .projection(proj),
countries = svg.append("g")
    .attr("id", "countries")
    .selectAll("path"),
carto = d3.cartogram()
    .projection(proj)
    .properties(function(d) {
        return d.properties
    }),
queue = d3.queue()
    .defer(csv)
    .defer(json)
    .awaitAll(ready),
mapData = d3.map(),
geometries,
topology

function json(callback) {
    d3.json("data/world.json", function(data) {
        topology = data
        geometries = topology.objects.countries

        var features = carto.features(topology, geometries)

        countries = countries
            .data(features)
            .enter()
            .append("path")
            .attr("fill", function (e) {
                return "#000000"
            })
            .attr("d", path)

        callback()
    })
}

function csv(callback) {
    d3.csv("data/data.csv", function(data) {
        data.forEach(function (d) {
            mapData.set(d.COUNTRY, +d.VALUE)
        })

        callback()
    })
}

function ready() {
    $("#container").css("visibility", "visible").hide().fadeIn("fast")
    $("header").css("visibility", "visible").hide().fadeIn("slow")

    carto.value(function(d) {
        if (mapData.has(d.properties.name)) {
            return +mapData.get(d.properties.name)
        }
    })

    countries.data(carto(topology, geometries).features)

    countries.transition()
        .duration(750)
        .attr("d", carto.path);
}

更新2 - 9/8/2016 18:05 BST

以下是Plunker脚本的最新版本,可用于测试,由@Mark提供:http://plnkr.co/edit/iK9EZSIfwIXjIEBHhlep?p=preview

虽然结果图表没有正确显示,但我的初始错误似乎已修复。

更新3 - 10/8/2016 20:45 BST

@Mark的回答有助于澄清我的很多问题,因此我得到了部分功能的制图,但为了解决详细问题here,我使用{{1}重新生成了我的地图文件}参数和和之后我再次收到以下错误:

--stitch-poles false

@Mark对这个错误的初步修复仍然存在,因此我很困惑为什么会重新出现这个错误。您可以看到我的最新代码here和我的新地图topojson文件here。再次感谢。

1 个答案:

答案 0 :(得分:1)

好的,我正在取得进展。事实证明,在修复.value函数后,您没有获得catrogram的原因是您的值太过分了。为什么这会引发cartogram.js,我不确定,但通过引入比例可以轻松解决问题。

使用您的数据:

s = d3.scale.linear().range([1,100]).domain(d3.extent(data, function(d){ return  +d.VALUE}));

然后在您的.value访问者中:

carto.value(function(d,i) {
  if (mapData.has(d.properties.name)) {
    return s(mapData.get(d.properties.name));
  } else {
    return 1;
  }
});
但是,唉,你所有的问题都没有解决。似乎国家&#34;包装&#34;投影(即俄罗斯和斐济)被cartogram.js生成的路径扭曲。这里有一个解决方法,详细讨论here

无论如何,here's what we've got so far