Public
Edited
May 9, 2023
Insert cell
Insert cell
data = FileAttachment("credit_card_approvals_dataset.csv").csv()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
slice = d3.shuffle(data).slice(0,20)
Insert cell
Insert cell
circles = d3.select(svgContainer).select("#credit_card_approvals").selectAll("circle")
.data(slice)
.join("circle")
.attr("cx", function(d, i){
if (i < 10) {return 50 + i * 73}
else { return 50 + (i-10) * 73 }
})
.attr("cy", function(d, i){
if (i < 10) { return 165 }
else { return 240 }
})
.attr("r", "20")
.style("opacity", "0.8")
.attr("class", "datapoints")
.call(drag)
Insert cell
Insert cell
circle_colors = change_circle_color()
Insert cell
legend = color_legend(color_data)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
for (let i = 0; i < data.length; i++) {
if (data[i]["Gender"] == "0") {
data[i]["Gender"] = "Female"
} else {
data[i]["Gender"] = "Male"
}
if (data[i]["Married"] == "0") {
data[i]["Married"] = "Single/Divorced/etc."
} else {
data[i]["Married"] = "Married"
}
if (data[i]["BankCustomer"] == "0") {
data[i]["BankCustomer"] = "Does Not Have Bank Account"
} else {
data[i]["BankCustomer"] = "Has Bank Account"
}
if (data[i]["PriorDefault"] == "0") {
data[i]["PriorDefault"] = "No Prior Defaults"
} else {
data[i]["PriorDefault"] = "Had Prior Defaults"
}
if (data[i]["Employed"] == "0") {
data[i]["Employed"] = "Unemployed"
} else {
data[i]["Employed"] = "Employed"
}
if (data[i]["DriversLicense"] == "0") {
data[i]["DriversLicense"] = "No License"
} else {
data[i]["DriversLicense"] = "Has License"
}
if (data[i]["Approved"] == "0") {
data[i]["Approved"] = "Rejected"
} else {
data[i]["Approved"] = "Approved"
}
}
}
Insert cell
Insert cell
colors_gender = ({"Female":"indianred", "Male":"cadetblue"})
Insert cell
colors_age = d3.scaleLinear().domain([13, 81]).range(["cyan", "blue"])
Insert cell
colors_debt = d3.scaleLinear().domain([0, 28]).range(["crimson", "springgreen"])
Insert cell
colors_married = ({"Single/Divorced/etc.":"indianred", "Married":"cadetblue"})
Insert cell
colors_bankcustomer = ({"Does Not Have Bank Account":"indianred", "Has Bank Account":"cadetblue"})
Insert cell
colors_industry = ({"CommunicationServices":"indianred", "ConsumerDiscretionary":"coral", "ConsumerStaples":"mediumvioletred", "Education":"khaki", "Energy":"mediumorchid", "Financials":"mediumseagreen", "Healthcare":"paleturquoise", "Industrials":"navy", "InformationTechnology":"blanchedalmond", "Materials":"peru", "Real Estate":"aniquewhite", "Research":"gainsboro", "Transport":"royalblue", "Utilities":"maroon"})
Insert cell
colors_ethnicity = ({"White":"antiquewhite", "Black":"steelblue", "Asian":"lightsalmon", "Latino":"rebeccapurple", "Other":"darkseagreen"})
Insert cell
colors_yearsemployed = d3.scaleLinear().domain([0, 29]).range(["cyan", "blue"])
Insert cell
colors_priordefault = ({"Had Prior Defaults":"indianred", "No Prior Defaults":"cadetblue"})
Insert cell
colors_employed = ({"Unemployed":"indianred", "Employed":"cadetblue"})
Insert cell
colors_creditscore = d3.scaleLinear().domain([0, 67]).range(["crimson", "springgreen"])
Insert cell
colors_driverslicense = ({"No License":"indianred", "Has License":"cadetblue"})
Insert cell
colors_citizen = ({"ByBirth":"mediumseagreen", "ByOtherMeans":"lightsteelblue", "Temporary":"lightpink"})
Insert cell
colors_income = d3.scaleLinear().domain([0, 100000]).range(["cyan", "blue"])
Insert cell
colors_approved = ({"Rejected":"red", "Approved":"green"})
Insert cell
Insert cell
Insert cell
columns = ["Gender", "Age", "Debt", "Married", "BankCustomer", "Industry", "Ethnicity", "YearsEmployed", "PriorDefault", "Employed", "CreditScore", "DriversLicense", "Citizen", "Income"]
Insert cell
numerical_values = ["Age", "Debt", "YearsEmployed", "CreditScore", "Income"]
Insert cell
Insert cell
color_data = {
if (selectField == "Gender") { return colors_gender }
else if (selectField == "Age") { return colors_age }
else if (selectField == "Debt") { return colors_debt }
else if (selectField == "Married") { return colors_married }
else if (selectField == "BankCustomer") { return colors_bankcustomer }
else if (selectField == "Industry") { return colors_industry }
else if (selectField == "Ethnicity") { return colors_ethnicity }
else if (selectField == "YearsEmployed") { return colors_yearsemployed }
else if (selectField == "PriorDefault") { return colors_priordefault }
else if (selectField == "Employed") { return colors_employed }
else if (selectField == "CreditScore") { return colors_creditscore }
else if (selectField == "DriversLicense") { return colors_driverslicense }
else if (selectField == "Citizen") { return colors_citizen }
else if (selectField == "Income") { return colors_income }
}
Insert cell
Insert cell
defs = d3.select(svgContainer).select("#key").append("defs");
Insert cell
Insert cell
Insert cell
color_legend = (the_data) => {
d3.select(svgContainer).select("#key")
.append("rect")
.attr("width", "400")
.attr("height", "400")
.style("fill", "white")

if (numerical_values.includes(selectField)) { gradient_legend() }

// adapted from https://d3-graph-gallery.com/graph/custom_legend.html
d3.select(svgContainer).select("#key").selectAll("dots")
.data(Object.values(the_data))
.join("rect")
.attr("x", 70)
.attr("y", function(d,i){ return 30 + i*(25)})
.attr("width", 20)
.attr("height", 20)
.style("fill", function(d){
if (numerical_values.includes(selectField)) { return "white" }
else { return d }
})
.style("opacity", function(d){
if (numerical_values.includes(selectField)) { return "0.0" }
else { return "1.0" }
})

d3.select(svgContainer).select("#key").selectAll("labels")
.data(Object.keys(the_data))
.join("text")
.attr("x", 70 + 20*1.2)
.attr("y", function(d,i){ return 30 + i*(25) + (10)})
.style("fill", d3.color("black"))
.text(function(d){
if (numerical_values.includes(selectField)) { return "" }
else { return d }
})
.attr("text-anchor", "left")
.style("alignment-baseline", "middle")

d3.select(svgContainer).select("#key").append("text")
.attr("x", "65")
.attr("y", "15")
.text("Legend")
.attr("id", "legendTitle")

}
Insert cell
Insert cell
gradient_legend = () => {
// gradient legend code adapted from https://www.visualcinnamon.com/2016/05/smooth-color-legend-d3-svg-gradient/
d3.select(svgContainer).select("#key").append("rect")
.attr("x", "70")
.attr("y", "30")
.attr("width", "20")
.attr("height", "200")
.style("fill", function(d){
if (selectField == "Age") { return "url(#linear-gradient-age)" }
else if (selectField == "Debt") { return "url(#linear-gradient-debt)" }
else if (selectField == "YearsEmployed") { return "url(#linear-gradient-yearsemployed)" }
else if (selectField == "CreditScore") { return "url(#linear-gradient-creditscore)" }
else if (selectField == "Income") { return "url(#linear-gradient-income)" }
else { return "white" }
})
.style("opacity", function(d){
if (numerical_values.includes(selectField)) { return "1.0" }
else { return "0.0" }
});

// adapted from https://d3-graph-gallery.com/graph/custom_axis.html
var y = d3.scaleLinear()
.domain(function(d){
if (selectField == "Age") { return [13, 81] }
else if (selectField == "Debt") { return [0, 28] }
else if (selectField == "YearsEmployed") { return [0, 29] }
else if (selectField == "CreditScore") { return [0, 67] }
else if (selectField == "Income") { return [0, 100000] }
else { return [0, 0] }
})
.range([210, 10]);

if (numerical_values.includes(selectField)) {
d3.select(svgContainer).select("#key")
.append("g")
.attr("transform", "translate(100,20)")
.call(d3.axisRight(y));
}

d3.select(svgContainer).select("#key")
.append("text")
.attr("x", "110")
.attr("y", "37")
.text(function(d){
if (selectField == "Age") { return "13" }
else if (selectField == "Debt") { return "0" }
else if (selectField == "YearsEmployed") { return "0" }
else if (selectField == "CreditScore") { return "0" }
else if (selectField == "Income") { return "0" }
else { return "" }
})
.style("text-align", "left");

d3.select(svgContainer).select("#key")
.append("text")
.attr("x", "110")
.attr("y", "235")
.text(function(d){
if (selectField == "Age") { return "81" }
else if (selectField == "Debt") { return "28" }
else if (selectField == "YearsEmployed") { return "29" }
else if (selectField == "CreditScore") { return "67" }
else if (selectField == "Income") { return "100000" }
else { return "" }
})
.style("text-align", "left");
}
Insert cell
Insert cell
linearGradientAge = defs.append("linearGradient")
.attr("id", "linear-gradient-age");
Insert cell
{
linearGradientAge
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%");

linearGradientAge
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "cyan");

linearGradientAge
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "blue");
}
Insert cell
linearGradientDebt = defs.append("linearGradient")
.attr("id", "linear-gradient-debt");
Insert cell
{
linearGradientDebt
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%");

linearGradientDebt
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "crimson");

linearGradientDebt
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "springgreen");
}
Insert cell
linearGradientYearsEmployed = defs.append("linearGradient")
.attr("id", "linear-gradient-yearsemployed");
Insert cell
{
linearGradientYearsEmployed
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%");

linearGradientYearsEmployed
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "cyan");

linearGradientYearsEmployed
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "blue");
}
Insert cell
linearGradientCreditScore = defs.append("linearGradient")
.attr("id", "linear-gradient-creditscore");
Insert cell
{
linearGradientCreditScore
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%");

linearGradientCreditScore
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "crimson");

linearGradientCreditScore
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "springgreen");
}
Insert cell
linearGradientIncome = defs.append("linearGradient")
.attr("id", "linear-gradient-income");
Insert cell
{
linearGradientIncome
.attr("x1", "0%")
.attr("y1", "0%")
.attr("x2", "0%")
.attr("y2", "100%");

linearGradientIncome
.append("stop")
.attr("offset", "0%")
.attr("stop-color", "cyan");

linearGradientIncome
.append("stop")
.attr("offset", "100%")
.attr("stop-color", "blue");
}
Insert cell
Insert cell
change_circle_color = () => {
circles.style("fill",function(d) {
if (selectField == "Gender") { return colors_gender[d["Gender"]] }
else if (selectField == "Age") { return colors_age(d["Age"]) }
else if (selectField == "Debt") { return colors_debt(d["Debt"]) }
else if (selectField == "Married") { return colors_married[d["Married"]] }
else if (selectField == "BankCustomer") { return colors_bankcustomer[d["BankCustomer"]] }
else if (selectField == "Industry") { return colors_industry[d["Industry"]] }
else if (selectField == "Ethnicity") { return colors_ethnicity[d["Ethnicity"]] }
else if (selectField == "YearsEmployed") { return colors_yearsemployed(d["YearsEmployed"]) }
else if (selectField == "PriorDefault") { return colors_priordefault[d["PriorDefault"]] }
else if (selectField == "Employed") { return colors_employed[d["Employed"]] }
else if (selectField == "CreditScore") { return colors_creditscore(d["CreditScore"]) }
else if (selectField == "DriversLicense") { return colors_driverslicense[d["DriversLicense"]] }
else if (selectField == "Citizen") { return colors_citizen[d["Citizen"]] }
else if (selectField == "Income") { return colors_income(d["Income"]) }
else { return d3.color("gray")}
})
}
Insert cell
Insert cell
show_correct_answers = (d) => {
circles.style("fill", function(d){ return colors_approved[d["Approved"]] });
d3.select(svgContainer).select("#key")
.append("rect")
.attr("width", "400")
.attr("height", "400")
.style("fill", "white")
// adapted from https://d3-graph-gallery.com/graph/custom_legend.html
d3.select(svgContainer).select("#key").selectAll("dots")
.data(Object.values(colors_approved))
.join("rect")
.attr("x", 70)
.attr("y", function(d,i){ return 30 + i*(25)})
.attr("width", 20)
.attr("height", 20)
.style("fill", function(d){ return d })

d3.select(svgContainer).select("#key").selectAll("labels")
.data(Object.keys(colors_approved))
.join("text")
.attr("x", 70 + 20*1.2)
.attr("y", function(d,i){ return 30 + i*(25) + (10)})
.style("fill", d3.color("black"))
.text(function(d){ return d })
.attr("text-anchor", "left")
.style("alignment-baseline", "middle")

d3.select(svgContainer).select("#key").append("text")
.attr("x", "65")
.attr("y", "15")
.text("Legend")
.attr("id", "legendTitle")
}
Insert cell
Insert cell
hide_correct_answers = (d) => {
change_circle_color();
color_legend(color_data);
gradient_legend();
}
Insert cell
drag = {

function dragstarted() {
d3.select(this).attr("stroke", "black");
}

function dragged(event, d) {
d3.select(this).raise().attr("cx", event.x).attr("cy", event.y);
}

function dragended() {
d3.select(this).attr("stroke", null);
}

return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more