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。
我的 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。