我有一个按年份过滤然后按组嵌套的数据。前几年有一组,而其余的年份则有七到八组线。除了线条,我还绘制了实际数据的点。
这是2007年的情节,其中只有一组:
2007 line plot
请注意,y轴丢失了,只显示了点,但没有线。
这是2010年的情节,分为八组:
2010 lines plot
注意y轴,所有点和线都在显示。
这是相关的代码:
定义线
var line = d3.svg.line()
.x(function(d) { return LoanAmount_scale(d['amount_mean']); })
.y(function(d) { return Investor_scale(d['Investors_mean']); });
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right )
.attr("height", height + margin.top + margin.bottom);
var plot = svg.append("g")
.attr("class", "chart")
.attr("width" , width- margin.left)
.attr("height", height)
.attr("transform","translate ("+ margin.left + "," + margin.top + ")");
菜单选择
// setting stage for dropdown menu
// years
var years = ['Select Year'];
var i= 2006;
for( i = 2006; i<= 2014; i++){
years.push(i);
}
// selecting an option
var select = d3.select('body')
.append('select')
.attr('class','select')
.attr('id','select_id')
.on('change',change);
// available options on dropdown menu
var option = select.selectAll('option')
.data(years)
.enter()
.append('option')
.text(function(d){ return d});
// menu selection of year
function change(){
var select_year = d3.select('select')
.property('value')
// reset chart before updating year
update(data,'Select Year');
// update year
update(data,select_year);
}
更新功能按组过滤年份和巢穴,然后绘制线和点
function update(data, year){
var Filtered = data.filter(function(d){ return d["LoanOrig_Yr"] == year});
var nested_by_rating = d3.nest()
.key(function(d) {
return d['ProsperRating']
}).sortKeys(d3.ascending)
.entries(Filtered);
// add lines for each rating
var lines = plot.selectAll("path")
.data(nested_by_rating)
// remove old lines
lines.exit().remove();
plot.selectAll("circle")
.data(nested_by_rating)
.exit().remove();
nested_by_rating.forEach( function(d,i){
var prosperR = d.key
// entering data
lines.enter()
.append("path")
.attr("class", "line")
.attr("d", line(d.values))
.attr("stroke", RatingColor(prosperR))
.attr("stroke-width", 3)
.attr("stroke-opacity",0.3)
.attr("fill","none");
debugger;
plot.selectAll("path.dot")
.data(d.values)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", line.x())
.attr("cy", line.y())
.attr("r", 3.5)
.attr("fill","Black");
debugger;
// dynamic legend
svg.append("text")
.attr("x", 1300)
.attr("y", 100 + i*20)
.attr("class", "legend") // style the legend
.style("fill", function() { // Add the colours dynamically
return d.color = RatingColor(prosperR); })
.text(prosperR);
在选择年份之间重置图表
// reseting chart between years
if (year == 'Select Year'){
gX.call(xAxis);
gY.call(yAxis);
svg.append("text")
.attr("x", 1300)
.attr("y", 100)
.attr("class", "legend") // style the legend
.style("fill", "white")
.text(["NR"]);
svg.selectAll("legend_text")
.data(["1.AA","2.A","3.B","4.C","5.D","6.E","7.HR","NR"])
.enter()
.append("text")
.attr("class","legend")
.attr("x", 1300)
.attr("y", function(d,i){return 100 + i*20;
})
.attr("class", "legend") // style the legend
.style("fill", "white")
.style("stroke","white")
.text(function(d,i){return d;});
} \\ end if statement
} \\end .forEach statement
使用浏览器检查器跟踪数据输入和退出时,我发现两种情况下的数据都按预期方式移入和移出。观察点数据是使用line.x()和line.y()传递的,因此很奇怪,该行在2007年和其他类似年份中没有显示一组。
对于解决此错误的任何帮助,我们将不胜感激。谢谢。
答案 0 :(得分:0)
您可以通过选择所有路径来删除直线,并且轴线是path
。
图例的更新每次都添加了很多条目。
通过将填充设置为白色或黑色来隐藏/显示黑色图例文本。
Select Year
的轴不需要更新图形,它们对于所有图形都保持不变。
var data = d3.csv.parse(d3.select("#dataset").text());
data.forEach(function(d){
d.LoanOrig_Yr = parseInt(+d.LoanOrig_Yr);
d.amount_median = parseFloat(+d.amount_median);
d.Investors_median = parseInt(+d.Investors_median);
});
function draw(data) {
var margin = {top: 5, right: 100, bottom: 150, left: 80},
width = 1460 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var margin2 = {top: 430, right: 200, bottom: 110, left:80},
height2 = 600 - margin2.top - margin2.bottom;
var margin3 = {top: 40, right:20, bottom: 80, left:180},
width2 = 1300 - margin3.left - margin3.right;
// display title
d3.select("body")
.append("h2")
.text("Funding low risk loans is shared by more investors than high risk loans");
// guiding text
d3.select("body")
.append("p")
.text("An investor may fund the whole loan or fractions of several loans with minimum"+
" investment amount of $25."+
" Prosper rating started in July 2009." +
" Prosper Rating (ordered): AA (lowest risk), A, B, C, D, E, HR (high risk), NR (not rated)." +
" Points on the line reflect loan amount average computed by "+
" agregating loans over brackets of size $1500, starting at $1000." +
" Data for 2014 is only for the first quarter."
);
var Investor_extent = d3.extent(data, function(d){
return d.Investors_median;
});
var Investor_scale = d3.scale.linear()
.domain(Investor_extent)
.range([height,margin.top]);
var LoanAmount_extent = d3.extent(data, function(d){
return d.amount_median;
});
var LoanAmount_scale = d3.scale.linear()
.range([margin.left, width])
.domain(LoanAmount_extent);
var ProsperRating = ["1.AA","2.A","3.B","4.C","5.D","6.E","7.HR","NR"];
var colors = ['Brown','Red','Orange','Yellow','Green','Blue','Purple','Gray'];
var RatingColor = d3.scale.ordinal()
.domain(ProsperRating)
.range(colors);
var xAxis = d3.svg.axis()
.scale(LoanAmount_scale)
.orient("bottom")
.ticks(12);
var yAxis = d3.svg.axis()
.scale(Investor_scale)
.orient("left")
.ticks(10);
var line = d3.svg.line()
.x(function(d) { return LoanAmount_scale(d.amount_median); })
.y(function(d) { return Investor_scale(d.Investors_median); });
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right )
.attr("height", height + margin.top + margin.bottom);
var plot = svg.append("g")
.attr("class", "chart")
.attr("width" , width- margin.left)
.attr("height", height)
.attr("transform","translate ("+ margin.left + "," + margin.top + ")");
var div = d3.select("body")
.append("div")
.attr("class","tooltip")
.style("opacity",0);
// setting stage for dropdown menu
// years
var years = ['Select Year', 2007, 2010];
// selecting an option
var select = d3.select('body')
.append('select')
.attr('class','select')
.attr('id','select_id')
.on('change',change);
// available options on dropdown menu
var option = select.selectAll('option')
.data(years)
.enter()
.append('option')
.text(function(d){ return d});
// menu selection of year
function change(){
var select_year = d3.select('select')
.property('value')
// reset chart before updating year
update(data,'Select Year');
// update year
update(data,select_year);
}
// add x axis
var gX = plot.append("g")
.attr("class","x axis")
.attr("transform","translate (0 " + height + ")")
.call(xAxis);
// add y axis
var gY = plot.append("g")
.attr("class", "y axis")
.attr("transform" , "translate( " + margin.left + " ,0)")
.call(yAxis);
//add x axis label
plot.append("text")
.attr("class", "x label")
.attr("text-anchor", "middle")
.attr("x", width/2 )
.attr("y", height + 40)
.text("Loan Amount median (US dollars)");
//add y axis label
plot.append("text")
.attr("class", "y label")
.attr("text-anchor", "middle")
.attr("x",0-(height/2))
.attr("y", 20)
.attr("dy", "1em")
.attr("transform", "rotate(-90)")
.text("Median number of investors who share funding one loan");
// legend title
svg.append("text")
.attr("x",1300)
.attr("y",70)
.attr("class","legend_title")
.style("fill","white")
.text("Legend: Prosper Rating");
svg.append("text")
.attr("x",1300)
.attr("y",30)
.attr("class","legend_title")
.style("fill","white")
.text("point mouse at line to determine rating");
function update(data, year){
var Filtered = data.filter(function(d){ return d.LoanOrig_Yr == year});
var nested_by_rating = d3.nest()
.key(function(d) { return d.ProsperRating })
.sortKeys(d3.ascending)
.entries(Filtered);
// add lines for each rating
var lines = plot.selectAll(".line")
.data(nested_by_rating)
// remove old lines
lines.exit().remove();
plot.selectAll("circle")
.data(nested_by_rating)
.exit().remove();
nested_by_rating.forEach( function(d,i){
var prosperR = d.key;
// entering data
lines.enter()
.append("path")
.attr("class", "line")
.attr("d", line(d.values))
.attr("stroke", RatingColor(prosperR))
.attr("stroke-width", 3)
.attr("stroke-opacity",0.3)
.attr("fill","none");
plot.selectAll("path.dot")
.data(d.values)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", line.x())
.attr("cy", line.y())
.attr("r", 3.5)
.attr("fill","Black");
// dynamic legend
svg.append("text")
.attr("x", 1300)
.attr("y", 100 + i*20)
.attr("class", "legend") // style the legend
.style("fill", function() { return RatingColor(prosperR); }) // Add the colours dynamically
.text(prosperR);
// mouse hover tip tool
lines.on("mouseover", function(d){
div.transition()
.duration(200)
.style("opacity", 0.9);
div.html("Prosper Rating : " + prosperR)
.style("left", (d3.event.pageX) + "px")
style("top", (d3.event.pageY - 2) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
})
});
// reseting chart between years
if (year == 'Select Year'){
svg.selectAll(".legend_title").style("fill","white");
svg.selectAll(".legend").remove();
} else {
svg.selectAll(".legend_title").style("fill","black");
}
}
}
draw(data);