if(!cf){ var cf = {data:{}}; } if(!cf.loadStatus){ cf.loadStatus = {}; } /** * number of schools * @type {Number} */ cf.nSchools = null; /** * college factual color scheme * @type {Array} */ cf.colors = ["#00999A","#F05C49","#1C75BB","#62CD21","#F99400","#2B3990","#999999"]; cf.lightColors = ["#83CCCB","#F5ADA5","#8FBBDB","#B1E594","#FBC885","#959DC5","#CCCCCC"]; /** * dynamically obtain data * @param varName the variable to get * @param callback a callback taking one parameter (the variable) */ cf.withVariable = function(varName,callback){ //case: script has been loaded and data is ready if(cf.data[varName]){ if(callback != null) { cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]); } return; } //case: script has not started loading var scriptPath = "data/"+varName+"_v1.0.js"; if(!cf.loadStatus[varName]){ var scriptNode = document.createElement('SCRIPT'); scriptNode.type = 'text/javascript'; scriptNode.src = scriptPath; var headNode = document.getElementsByTagName('HEAD'); if (headNode[0] != null){ headNode[0].appendChild(scriptNode); } cf.loadStatus[varName] = "loading"; if (callback != null) { scriptNode.onreadystagechange = function(){ cf.loadStatus[varName] = "loaded"; cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]); }; scriptNode.onload = function(){ cf.loadStatus[varName] = "loaded"; cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]); }; } return; } //case: script has started loading, but has not completed var scripts = document.getElementsByTagName('SCRIPT') var index = -1; for(var i =0;i -1){ index = i; } } var scriptNode = scripts[index]; if(callback != null){ if(scriptNode.onreadystagechange){ var func = scriptNode.onreadystagechange; scriptNode.onreadystagechange = function(){func(); cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]);}; }else{ scriptNode.onreadystagechange = function(){cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]);}; } if(scriptNode.onload){ var func = scriptNode.onload; scriptNode.onload = function(){func(); cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]);}; }else{ scriptNode.onload = function(){cf.nSchools = cf.data[varName].data.length; callback(cf.data[varName]);}; } } } /** * bar chart */ cf.barChart = function(){ var format = d3.format(".0%"); var width = 400; var height = 150; var buffer = 10; var className = "barChart"; function chart(selection){ selection.each(function(data) { // Select the svg element, if it exists. var chart = d3.select(this).selectAll("svg"); // Otherwise, create the skeletal chart. if(!chart[0].length){ d3.select(this).append("svg"); chart = d3.select(this).selectAll("svg"); } // Update the outer dimensions. chart.attr("class", className) .attr("width", width) .attr("height",height); tmp = chart var names = data.map(function(x){return x.name;}); var y = d3.scale.ordinal() .domain(names) .rangeBands([0, height]); chart.selectAll("yaxis") .data(data) .enter().append("text") .attr("class", "yaxis") .attr("x", function(d){return -3;}) .attr("y", function(d,i) { return y(d.name) + y.rangeBand(d.name) / 2; }) .attr("dx", -3) // padding-right .attr("dy", ".35em") // vertical-align: middle .attr("text-anchor", "end") // text-align: right .text(function(d){return d.name;}); var axisNodes = chart.selectAll(".yaxis")[0]; var axisTextWidth = Math.ceil( d3.max(axisNodes.map(function(x){return x.getComputedTextLength();})))+4; var x = d3.scale.linear() .domain([0, d3.max(data.map(function(x){return x.data;}))]) .range([0, width-axisTextWidth-buffer]); chart.selectAll("rect") .data(data) .enter().append("rect") .attr("y", function(d,i){ return y(d.name);}) .attr("x", axisTextWidth+buffer) .attr("width", function(d){return x(d.data);}) .attr("height", y.rangeBand()); //.attr("onmouseover",function(d){ return "tooltip.show(\""+d.data+"\");";}) //.attr("onmouseout","tooltip.hide();"); chart.selectAll("bar") .data(data) .enter().append("text") .attr("class", "bar") .attr("x", function(d){return axisTextWidth+buffer+x(d.data)-3;}) .attr("y", function(d,i) { return y(d.name) + y.rangeBand(d.name) / 2; }) .attr("dx", -3) // padding-right .attr("dy", ".35em") // vertical-align: middle .attr("text-anchor", "end") // text-align: right .text(function(d){return format(d.data);}); var barText = chart.selectAll(".bar")[0]; for(var i=0;i90 && angle<270){ var result = "M"+textArc(d).split("L")[1]; return result.substr(0,result.length-1) } return textArc(d).split("L")[0]; } ) .attr("id",function(d,i){ return "path"+i+"_"+chartId;}) .style("fill", "none"); /*g.append("text").append("textPath") .attr("class","textInside") .attr("startOffset",function(d){ return "50%"; }) .attr("xlink:href",function(d,i){ return "#path"+i+"_"+chartId;}) .attr("spacing","exact") .style("text-anchor", "middle") .append("tspan") .text(function(d) { return d.data.name; }) .on("mouseover",over) .on("mouseout",out); var textPathNodes = g.selectAll(".textInside"); var tspans = g.selectAll("tspan");*/ //var textPathWidth = []; //for(var i=0;i90 && angle<270){ result = "M"+textArcOutside(t).split("L")[1]; result = result.substr(0,result.length-1) piedat[i].top = true; //d3.select(tspans[i][0]).attr("dy",".71em"); }else{ result = textArcOutside(t).split("L")[0]; } console.debug(piedat[i].name) console.debug(result) console.debug(d3.select("#path"+i+"_"+chartId) .attr("d")) d3.select("#path"+i+"_"+chartId) .attr("d", result) var lims = {s:mid - (tw/2)/outerRadius, e:mid + (tw/2)/outerRadius, name:data[i].name} var overlap = false; for(var k = 0 ;k2*Math.PI && breaks[k].s<2*Math.PI && (lims.e-2*Math.PI)>breaks[k].s) overlap=true; if(breaks[k].e>lims.s && breaks[k].elims.s && breaks[k].slims.e) overlap=true; } piedat[i].overlap = overlap; piedat[i].mid = -mid - Math.PI; if(overlap){ }else{ mid = -mid - Math.PI; g.append("line").attr("class","tick") .attr("y1",outerRadius*Math.cos(mid)) .attr("x1",outerRadius*Math.sin(mid)) .attr("y2",(outerRadius+3)*Math.cos(mid)) .attr("x2",(outerRadius+3)*Math.sin(mid)) breaks[j] = lims; j++; } } } g.append("text").append("textPath") .attr("class",function(d,i){ return d.inside ? "textInside" : "textOutside"; }) .attr("startOffset",function(d){ return "50%"; }) .attr("xlink:href",function(d,i){ return "#path"+i+"_"+chartId;}) .attr("spacing","exact") .style("text-anchor", "middle") .append("tspan") .attr("dy",function(d){return d.top ? ".71em" : "0em";}) .text(function(d) { return d.overlap ? "" : d.data.name; }) .on("mouseover",over) .on("mouseout",out); tn.text(""); var centerCircle = g.append("circle") .attr("cx",0) .attr("cy",0) .attr("r",innerRadius) .attr("fill","white") var selectedValueBack = g.append("rect") .attr("x",0) .attr("y",-innerRadius/2-15) .attr("width",0) .attr("height",30) .attr("fill","white") .attr("stroke","#DCDCDC") .attr("rx",10) var selectedValueLabel = g.append("text") .attr("class","valueLabel") .attr("x",0) .attr("y",-innerRadius/2) .attr("dy", ".35em") .style("text-anchor", "middle") .text(""); var percentLabel = g.append("text") .attr("class","percentLabel") .attr("x",0) .attr("y",innerRadius/5) .attr("dy", ".35em") .style("text-anchor", "middle") .style("font-size", (innerRadius-15)+"px") .text(""); }); } chart.width = function(_) { if (!arguments.length) return width; width = _; return chart; }; chart.thickness = function(_) { if (!arguments.length) return thickness; thickness = _; return chart; }; chart.height = function(_) { if (!arguments.length) return height; height = _; return chart; }; chart.format = function(_) { if (!arguments.length) return format; format = _; return chart; }; chart.colors = function(_) { if (!arguments.length) return colors; colors = _; return chart; }; chart.colorCenter = function(_) { if (!arguments.length) return colorCenter; colorCenter = _; return chart; }; chart.className = function(_) { if (!arguments.length) return className; className = _; return chart; }; return chart; } cf.doughnutChartExample = function(){ var data = [{name:"sfdf",data:.03}, {name:"a",data:.9}, {name:"bdsffsdfshjkhjkhjkhjkhkdf",data:.6}, {name:"blaa blaa blaa",data:.3}, {name:"c",data:.2}, {name:"enter",data:.05}, {name:"other",data:.02}]; d3.select("body").append("div").attr("class","doughnutChart"); var func = cf.doughnutChart().width(200).height(200).thickness(40).colorCenter(false); d3.select(".doughnutChart").datum(data).call(func); d3.select("body").append("div").attr("class","livsit"); var data = [{name:"On Campus",data:.485}, {name:"With Family",data:.385}, {name:"Independent",data:.13}]; var func = cf.doughnutChart().width(200).height(200).thickness(40).colorCenter(false); d3.select(".livsit").datum(data).call(func); } cf.densityChart = function(){ var variable; var schoolID = -1; var margin = {top: 28, right: 20, bottom: 30, left: 20}, width = 400 - margin.left - margin.right, height = 200 - margin.top - margin.bottom; var format = d3.format(); function chart(selection){ selection.each(function(data) { variable = data; // Select the svg element, if it exists. var svg = d3.select(this).selectAll("svg"); // Otherwise, create the skeletal chart. if(!svg[0].length){ d3.select(this).append("svg"); svg = d3.select(this).selectAll("svg"); } var svg = svg .attr("class","densityChart") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var min = d3.min(variable.data); var max = d3.max(variable.data); var x = d3.scale.linear() .domain([min,max]) .range([0, width]); var y = d3.scale.linear() .domain([0,1]) .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") .ticks(3) .tickFormat(format); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var area = d3.svg.area() .x(function(d) { return x(d.x); }) .y0(height) .y1(function(d) { return y(d.y); }); var line = d3.svg.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }) .interpolate("basis"); var filteredVariable = variable.data.filter(Number); var kde = science.stats.kde().sample(filteredVariable); var tdat = kde(d3.range(min,max,(max-min)/300)); for(var i=0;i (width-ln)){ var interp = [{x:x(sx), y:y(sy)}, {x:(x(sx)+ln+lx)/2+30, y:(y(sy)+ly)/2}, {x:lx+ln, y:ly}]; }else{ var interp = [{x:x(sx), y:y(sy)}, {x:(x(sx)+lx)/2-30, y:(y(sy)+ly)/2}, {x:lx, y:ly}]; } } svg.append("circle").attr("cx",x(sx)).attr("cy",y(sy)).attr("r",5) svg.append("path").datum(interp) .attr("d", line)//function(d) { document.write(d.x);return line.interpolate(d)(interp); }) .attr("fill","none").attr("stroke","black"); } if(schoolID>=0){ cf.withVariable("UNITID", function(UNITID){ cf.withVariable("INSTNM",function(INSTNM){ var index = UNITID.data.indexOf(schoolID) var sx = variable.data[index]; var sy = 0.75*kde([sx])[0][1]/ymax; var mx = d3.mean(filteredVariable); var my = 0.75*kde([mx])[0][1]/ymax; if(sx!=null) plotLabel(sx,sy,INSTNM.data[index],"Value: "+format(sx),sxmx?"left":"right",0); }) }); } var brushText = svg.append("text") .attr("class","label") .attr("x",margin.left+width/2) .attr("y",height-5) .text("") .style("text-anchor", "middle"); svg.append("path").attr("class","brushPath"); var brush = d3.svg.brush() .x(x) .on("brush", runBrush); var brushArea = d3.svg.area() .interpolate("monotone") .x(x) .y0(height) .y1(y); svg.append("rect") .attr("width", width) .attr("height", height) .attr("fill","none"); svg.append("g") .attr("class", "x brush") .call(brush) .selectAll("rect") .attr("y", 3) .attr("height", height-3) .on("mouseover",function(){ path.transition().attr("class","areaSelected") }) .on("mouseout",function(){ path.transition().attr("class","area") }); svg.append("line") .attr("class","axisLine") .style("stroke","white") .style("stroke-width","2px") .attr("x1",x(tdat[0].x)) .attr("y1",height) .attr("x2",x(tdat[tdat.length-1].x)) .attr("y2",height) function runBrush(a) { if(brush.empty()){ brushText.text(""); return; } svg.select(".brushPath").attr("d", brushArea); var l = brush.extent()[0], u = brush.extent()[1], n = filteredVariable.length, c = 0, v = 0; for(var i=0;i=l) c++ } brushText.text(c + " of " + n + " ("+ d3.format(".0%")(c/n)+ ")"); //svg.select(".x.axis").call(xAxis); } }); } chart.width = function(_) { if (!arguments.length) return width; width = _; return chart; }; chart.height = function(_) { if (!arguments.length) return height; height = _; return chart; }; chart.margin = function(_) { if (!arguments.length) return margin; margin = _; height = margin; return chart; }; chart.format = function(_) { if (!arguments.length) return format; format = _; return chart; }; chart.schoolID = function(_) { if (!arguments.length) return schoolID; schoolID = _; return chart; }; return chart; } cf.densityChartExample = function(){ d3.select("body").append("div").attr("class","dChart"); var func1 = cf.densityChart() .schoolID(140818) .height(50) .format(d3.format(".1%")); cf.withVariable("percWomen",function(percWomen){ d3.select(".dChart").datum(percWomen).call(func1); }); d3.select("body").append("div").attr("class","dChart1"); var func = cf.densityChart() .schoolID(140818) .height(50) .format(function(x){ return "$" + d3.format(",.0f")(x);}); cf.withVariable("aveCost",function(variable){ d3.select(".dChart1").datum(variable).call(func); }); } cf.subDensityChart = function(){ var plot = {}; plot.variable; plot.schoolName = "" plot.margin = {top: 15, right: 20, bottom: 10, left: 20}; plot.width = 150; plot.height = 60; plot.format = d3.format(); plot.variable = null; plot.root = null; plot.maxHeight = 1; plot.title = ""; plot.description = ""; plot.brushListener = null; plot.chart = function(root,data){ var thePlot = this; var width = plot.width - plot.margin.left - plot.margin.right; var height = plot.height - plot.margin.top - plot.margin.bottom; if(data!=null) this.variable = data; if(root!=null) this.root=root; var svg = root .attr("class","densityChart") .attr("width", this.width ) .attr("height", this.height) .append("g") .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")"); var min = d3.min(this.variable.data); var max = d3.max(this.variable.data); var x = d3.scale.linear() .domain([min,max]) .range([0, width]); var y = d3.scale.linear() .domain([0,1]) .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") .ticks(3) .tickFormat(this.format); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var area = d3.svg.area() .x(function(d) { return x(d.x); }) .y0(height) .y1(function(d) { return y(d.y); }); var line = d3.svg.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }) .interpolate("basis"); var filteredVariable = this.variable.data.filter(Number); var kde = science.stats.kde().sample(filteredVariable); var tdat = kde(d3.range(min,max,(max-min)/300)); for(var i=0;imx?"left":"right",0); }); } var brushText = svg.append("text") .attr("class","brushLabel") .attr("x",width/2) .attr("y",height-3) .text("") .style("text-anchor", "middle"); var titleText = svg.append("text") .attr("class","titleLabel") .attr("x",width/2) .attr("y",-2) .text(this.title) .style("text-anchor", "middle") .attr("onmouseover","tooltip.show(\""+this.description+"\", 100);") .attr("onmouseout","tooltip.hide();"); svg.append("path").attr("class","brushPath"); var brush = d3.svg.brush() .x(x) .on("brush", runBrush) .on("brushend",triggerBrush); function clearSelection(){ if(!brush.empty()){ console.debug("clear") svg.select(".brush").call(brush.clear()); triggerBrush(); } } var brushArea = d3.svg.area() .interpolate("monotone") .x(x) .y0(height) .y1(y); svg.append("rect") .attr("width", width) .attr("height", height) .attr("fill","none"); svg.append("g") .attr("class", "x brush") .call(brush) .selectAll("rect") .attr("y", 0) .attr("height", height) .on("mouseover",function(){ density.attr("class","areaSelected") }) .on("mouseout",function(){ density.attr("class","area") }); root.selectAll("text").on("click",clearSelection); svg.append("line") .attr("class","axisLine") .style("stroke","white") .style("stroke-width","2px") .attr("x1",x(tdat[0].x)) .attr("y1",height) .attr("x2",x(tdat[tdat.length-1].x)) .attr("y2",height) function runBrush(a) { if(brush.empty()){ brushText.text(""); /*var filter = []; for(var i=0;i=l) c++ } brushText.text(c + " of " + n + " ("+ d3.format(".0%")(c/n)+ ")"); //svg.select(".x.axis").call(xAxis); } function triggerBrush(a){ if(brush.empty()){ if(plot.brushListener!=null) plot.brushListener(null); return; } var l = brush.extent()[0], u = brush.extent()[1]; var filter = []; for(var i=0;i=l) filter[i] = true; else filter[i] = false; } if(plot.brushListener!=null) plot.brushListener(filter); } this.update = function(include){ filteredVariable = []; var j=0; for(var i=0;imx?"left":"right",0); },1000); }); } } }; plot.opt = function(option, value) { if (arguments.length<2) return this[option]; this[option] = value; return this; }; return plot; } cf.subBarChart = function(){ var plot = {}; plot.format = function(x){return x;}; plot.margin = {top: 25, right: 20, bottom: 0, left: 20}; plot.width = 150; plot.height = 90; plot.buffer = 10; plot.variable = null; plot.brushListener = null; plot.className = "subBarChart"; plot.counts = function(variable){ result = []; for(var i=0;i0){ filter[k] = filter[k] || plot.variable.data[k] === (j+1); }else{ filter[k] = plot.variable.data[k] === (j+1) } } } if(!hasSelected){ for(var j=0;j1 - Best, 1296 - Worst") .opt("brushListener",function(inc){return brushListener(3,inc)}); plot.subPlots[3] = dc; dc.chart(root,variable) }); cf.withVariable("aveValueRank",function(variable){ var root = svg.append("g").attr("transform","translate(150,"+(plot.subHt+2*plot.catHt)+")"); var dc = cf.subDensityChart() .opt("title","Value") .opt("description","The College Factual value rank for the institution.
1 - Best, 1274 - Worst" + "
(Based on average cost across all students excluding financial aid)") .opt("brushListener",function(inc){return brushListener(4,inc)}); plot.subPlots[4] = dc; dc.chart(root,variable) }); makeCatTitle("Selectivity",plot.catHt+plot.subHt+plot.catHt/2,plot.subWt*3,plot.subWt*5); cf.withVariable("SAT",function(variable){ var root = svg.append("g").attr("transform","translate(450,"+(plot.subHt+2*plot.catHt)+")"); var dc = cf.subDensityChart() .opt("title","SAT") .opt("description","The average SAT score for incoming students") .opt("brushListener",function(inc){return brushListener(5,inc)}); plot.subPlots[5] = dc; dc.chart(root,variable) }); cf.withVariable("AccRate",function(variable){ var root = svg.append("g").attr("transform","translate(600,"+(plot.subHt+2*plot.catHt)+")"); var dc = cf.subDensityChart() .opt("title","% Accepted") .opt("description","The percentage of applicants accepted for admission.
" + "Low scores represent more exclusive institutions") .opt("format",d3.format(".0%")) .opt("brushListener",function(inc){return brushListener(6,inc)}); plot.subPlots[6] = dc; dc.chart(root,variable) }); makeCatTitle("Instruction",plot.catHt/2,plot.subWt*3,plot.subWt*5); cf.withVariable("EmpTeachFTPct",function(variable){ var root = svg.append("g").attr("transform","translate(450,"+(plot.catHt)+")"); var dc = cf.subDensityChart() .opt("title","FT Faculty") .opt("description","The percentage of instructional employees who are full time") .opt("format",d3.format(".0%")) .opt("brushListener",function(inc){return brushListener(7,inc)}); plot.subPlots[7] = dc; dc.chart(root,variable) }); cf.withVariable("StudFacRat",function(variable){ var root = svg.append("g").attr("transform","translate(600,"+(plot.catHt)+")"); var dc = cf.subDensityChart() .opt("title","Faculty Ratio") .opt("description","The ratio of instructional employees to full time undergraduate students") .opt("format",function(x){return "1:" + x;}) .opt("brushListener",function(inc){return brushListener(8,inc)}); plot.subPlots[8] = dc; dc.chart(root,variable) }); makeCatTitle("Institution",plot.catHt*2+plot.subHt*2+plot.catHt/2,plot.subWt*0,plot.subWt*5); cf.withVariable("aveCost",function(variable){ var root = svg.append("g").attr("transform","translate(600,"+(2*plot.subHt+3*plot.catHt)+")"); var dc = cf.subDensityChart() .opt("height",85) .opt("title","Cost") .opt("description","Average cost for full time undergraduates before aid.") .opt("format",function(x){ return "$" + d3.format(",.0f")(x/1000)+"k";}) .opt("brushListener",function(inc){return brushListener(9,inc)}); plot.subPlots[9] = dc; dc.chart(root,variable) }); cf.withVariable("setting",function(variable){ var root = svg.append("g").attr("transform","translate(450,"+(2*plot.subHt+3*plot.catHt)+")"); var bc = cf.subBarChart() .opt("title","Campus") .opt("description","The setting of the campus.") .opt("brushListener",function(inc){return brushListener(10,inc)}); plot.subPlots[10] = bc; bc.chart(root,variable) }); cf.withVariable("USNRegion",function(variable){ var root = svg.append("g").attr("transform","translate(150,"+(2*plot.subHt+3*plot.catHt)+")"); var bc = cf.subBarChart() .opt("title","Region") .opt("description","The location of the campus.") .opt("brushListener",function(inc){return brushListener(11,inc)}); plot.subPlots[11] = bc; bc.chart(root,variable) }); cf.withVariable("sizeCat",function(variable){ var root = svg.append("g").attr("transform","translate(0,"+(2*plot.subHt+3*plot.catHt)+")"); var bc = cf.subBarChart() .opt("title","Size") .opt("description","Total # of undergraduate students.") .opt("brushListener",function(inc){return brushListener(12,inc)}); plot.subPlots[12] = bc; bc.chart(root,variable) }); function updateDataTable(dt,include,col){ if(include==null){ include = []; for(var i =0;i" + variable.data[i]+"",i,1, false,false); } cf.withVariable("RBrightHub",function(variable){ for(var i =0;i' ); var tab = $("#example"); dataTable = cf.collegeTable(tab).populate(); plot.registerDataTable(dataTable); }