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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more