d3.js 和来自 csv 文件图表宽度的数据可视化

d3.js and data visualization from csv file graph width

我的 d3.js 可视化有问题。在线图形宽度堆栈。它应该在下面的 1950 年和 2013 年之间的 js 文件和 Live example

var regions = { "SAS": "South Asia" , "ECS": "Europe and Central Asia", "MEA": "Middle East & North Africa", "SSF": "Sub-Saharan Africa", "LCN": "Latin America & Caribbean", "EAS": "East Asia & Pacific", "NAC": "North America" },
    w = 925,
    h = 550,
    margin = 30,
    startYear = 1950, 
    endYear = 2013,
    startAge = 0,
    endAge = 400,
    y = d3.scale.linear().domain([endAge, startAge]).range([0 + margin, h - margin]),
    x = d3.scale.linear().domain([1950, 2013]).range([0 + margin -5, w]),
    years = d3.range(startYear, endYear);

var vis = d3.select("#vis")
    .append("svg:svg")
    .attr("width", w)
    .attr("height", h)
    .append("svg:g")
    // .attr("transform", "translate(0, 600)");


var line = d3.svg.line()
    .x(function(d,i) { return x(d.x); })
    .y(function(d) { return y(d.y); });


// Regions
var countries_regions = {};
d3.text('country-regions.csv', 'text/csv', function(text) {
    var regions = d3.csv.parseRows(text);
    for (i=1; i < regions.length; i++) {
        countries_regions[regions[i][0]] = regions[i][1];
    }
});

var startEnd = {},
    countryCodes = {};
d3.text('life-expectancy-cleaned-all.csv', 'text/csv', function(text) {
    var countries = d3.csv.parseRows(text);

    for (i=1; i < countries.length; i++) {
        var values = countries[i].slice(2, countries[i.length-1]);
        var currData = [];
        countryCodes[countries[i][1]] = countries[i][0];

        var started = false;
        for (j=0; j < values.length; j++) {
            if (values[j] != '') {
                currData.push({ x: years[j], y: values[j] });

                if (!started) {
                    startEnd[countries[i][1]] = { 'startYear':years[j], 'startVal':values[j] };
                    started = true;
                } else if (j == values.length-1) {
                    startEnd[countries[i][1]]['endYear'] = years[j];
                    startEnd[countries[i][1]]['endVal'] = values[j];
                }

            }
        }
        vis.append("svg:path")
            .data([currData])
            .attr("country", countries[i][1])
            .attr("class", countries_regions[countries[i][1]])
            .attr("d", line)
            .on("mouseover", onmouseover)
            .on("mouseout", onmouseout);
    }
});  

vis.append("svg:line")
    .attr("x1", x(1950))
    .attr("y1", y(startAge))
    .attr("x2", x(2013))
    .attr("y2", y(startAge))
    .attr("class", "axis")

vis.append("svg:line")
    .attr("x1", x(startYear))
    .attr("y1", y(startAge))
    .attr("x2", x(startYear))
    .attr("y2", y(endAge))
    .attr("class", "axis")

vis.selectAll(".xLabel")
    .data(x.ticks(5))
    .enter().append("svg:text")
    .attr("class", "xLabel")
    .text(String)
    .attr("x", function(d) { return x(d) })
    .attr("y", h-10)
    .attr("text-anchor", "middle")

vis.selectAll(".yLabel")
    .data(y.ticks(4))
    .enter().append("svg:text")
    .attr("class", "yLabel")
    .text(String)
    .attr("x", 0)
    .attr("y", function(d) { return y(d) })
    .attr("text-anchor", "right")
    .attr("dy", 3)

vis.selectAll(".xTicks")
    .data(x.ticks(5))
    .enter().append("svg:line")
    .attr("class", "xTicks")
    .attr("x1", function(d) { return x(d); })
    .attr("y1", y(startAge))
    .attr("x2", function(d) { return x(d); })
    .attr("y2", y(startAge)+7)

vis.selectAll(".yTicks")
    .data(y.ticks(4))
    .enter().append("svg:line")
    .attr("class", "yTicks")
    .attr("y1", function(d) { return y(d); })
    .attr("x1", x(1950))
    .attr("y2", function(d) { return y(d); })
    .attr("x2", x(1960))

function onclick(d, i) {
    var currClass = d3.select(this).attr("class");
    if (d3.select(this).classed('selected')) {
        d3.select(this).attr("class", currClass.substring(0, currClass.length-9));
    } else {
        d3.select(this).classed('selected', true);
    }
}

function onmouseover(d, i) {
    var currClass = d3.select(this).attr("class");
    d3.select(this)
        .attr("class", currClass + " current");

    var countryCode = $(this).attr("country");
    var countryVals = startEnd[countryCode];
    var percentChange = 100 * (countryVals['endVal'] - countryVals['startVal']) / countryVals['startVal'];

    var blurb = '<h2>' + countryCodes[countryCode] + '</h2>';
    blurb += "<p>On average: number of deaths per 1000 live births " + Math.round(countryVals['startVal']) + "  in " + countryVals['startYear'] + " and " + Math.round(countryVals['endVal']) + "  in " + countryVals['endYear'] + ", ";
    if (percentChange >= 0) {
        blurb += "an increase of " + Math.round(percentChange) + " percent."
    } else {
        blurb += "a decrease of " + -1 * Math.round(percentChange) + " percent."
    }
    blurb += "</p>";

    $("#default-blurb").hide();
    $("#blurb-content").html(blurb);
}
function onmouseout(d, i) {
    var currClass = d3.select(this).attr("class");
    var prevClass = currClass.substring(0, currClass.length-8);
    d3.select(this)
        .attr("class", prevClass);
    // $("#blurb").text("hi again");
    $("#default-blurb").show();
    $("#blurb-content").html('');
}

function showRegion(regionCode) {
    var countries = d3.selectAll("path."+regionCode);
    if (countries.classed('highlight')) {
        countries.attr("class", regionCode);
    } else {
        countries.classed('highlight', true);
    }
}

csv 文件看起来像

CountryName,CountryCode,1950,1960,1970,1980,1990,2000,2010,2013 阿富汗,AFG,0,359.5,309,255,179.1,135.6,105.2,97.3 阿尔巴尼亚,ALB,0,0,0,77.3,40.5,26.1,16.5,14.9 阿尔及利亚,DZA,0,246.6,244.7,148,47.1,39.6,27.4,25.2 安道尔,AND,0,0,0,0,8.5,4.6,3.3,3

在您的数据中,您每 10 年就有一个数据点,但如果我没看错的话,您的 x-value 是 x: years[j]:

> d3.range(startYear, endYear)
[1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012]

因此,您在 1950、1951、1952、1953 而非 1950、1960、1970 等处绘制 x...

简单的解决方法是使用 d3.range(startYear, endYear, 10),正确的解决方法是从 CSV 文件的 header 中获取 x-value。