Public
Edited
May 9, 2023
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viz = d3.select(svgContainer)
Insert cell
Insert cell
{
// then we attach an .on("click", () => doSomething) to each of the buttons or control inputs above.
const btns = d3.select(svgContainer).select("#controls");

// register event listeners
// btns.select("#allpasswords-on").on("click", () => layerOn("allpasswords"));
// btns.select("#allpasswords-off").on("click", () => layerOff("allpasswords"));
btns.select("#allpasswords-only").on("click", () => layerOnlyOn("allpasswords"));
// btns.select("#difficulty-on").on("click", () => layerOn("difficulty"));
// btns.select("#difficulty-off").on("click", () => layerOff("difficulty"));
btns.select("#difficulty-only").on("click", () => layerOnlyOn("difficulty"));
// btns.select("#length-on").on("click", () => layerOn("length"));
// btns.select("#length-off").on("click", () => layerOff("length"));
btns.select("#length-only").on("click", () => layerOnlyOn("length"));

// btns.select("#btn-allOn").on("click", allOn);
//btns.select("#btn-allOff").on("click", allOff);

// btns.select("#allpasswords-toggle").on("click", () => layerToggleOnOff("allpasswords"));
// btns.select("#difficulty-toggle").on("click", () => layerToggleOnOff("difficulty"));
// btns.select("#length-toggle").on("click", () => layerToggleOnOff("length"));

btns.select("#slider").on("input", (evt) => layerOnlyOn("layer" + evt.target.value));
}
Insert cell
Insert cell
// layerOff = (id) => {
// viz.select("#" + id).style("visibility","hidden")
// }
Insert cell
// layerOn = (id) => {
// viz.select("#" + id).style("visibility","visible")
// }
Insert cell
// layerToggleOnOff = (id) => {
// let layer = viz.select("#" + id);
// if (layer.style("visibility") == "hidden") {
// layer.style("visibility","visible");
// } else {
// layer.style("visibility","hidden");
// }
// }
Insert cell
// allOn = () => {
// viz.selectAll("g").style("visibility","visible")
// }
Insert cell
allOff = () => {
//viz.selectAll("g").style("visibility","hidden")
viz.select("#allpasswords").style("visibility","hidden");
viz.select("#difficulty").style("visibility","hidden");
viz.select("#length").style("visibility","hidden");
}
Insert cell
layerOnlyOn = (id) => {
allOff();
viz.select("#" + id).style("visibility","visible")
}
Insert cell
// viewof dataAggregationSelected = Inputs.radio(new Map([["All Passwords", allDataSorted], ["Group by Password Type", rollupData], ["Count by Crack Difficulty", rollupDataByDifficulty]]), {value: allDataSorted, label: "Select one:"})

// Grouping Fields --> char upper, char_digit, char_symbol
// want to group by password type then crack difficulty
Insert cell
viewof sortField = Inputs.select(["length", "password_type", "crack_difficulty"], {label: "Sort By:", value: "password_type"}) //delete later if figure out on-screen sliders
Insert cell
Insert cell
UvaPasswords = FileAttachment("testpass.csv").csv()
Insert cell
// UvaPasswords.forEach(d => {
// if (d.alphabet_size == "10") {d.password_type = "numeric"}
// else if (d.alphabet_size == "26") {d.password_type = "alphabetic"}
// else if (d.alphabet_size == "36") {d.password_type = "alphanumeric"}
// else if (d.alphabet_size == "43") {d.password_type = "numeric-symbolic"}
// else if (d.alphabet_size == "59") {d.password_type = "alphabetic-symbolic"}
// else if (d.alphabet_size == "69") {d.password_type = "alphanumeric-symbolic"}
// })
Insert cell
//slicedData = d3.shuffle(UvaPasswords).slice(0,1000)
Insert cell
UvaPasswords.forEach(d => {
delete d[""]; //column name is an empty string, so "" will match it
})
Insert cell
sortedData = d3.sort(UvaPasswords, (a,b) => d3.ascending(a[sortField],b[sortField]))
Insert cell
Insert cell
import {layoutChildren} from "@emfielduva/dvlib_layout"
Insert cell
dataLayout = layoutChildren("passwords", sortedData);
Insert cell
allDataSorted = d3.sort(UvaPasswords, (a,b) => d3.ascending(a[sortField], b[sortField])) //sorts passwords in ascending order
//sortField created above (select from drop-down menu)
Insert cell
rollupData = d3.rollups(UvaPasswords, v => d3.count(v, d => toNum(d["search_space_count"])), d => d["password_type"]).sort((a,b) => d3.ascending(a[1],b[1]))
Insert cell
rollupDataByDifficulty = d3.rollups(UvaPasswords, v => d3.count(v, d => toNum(d["search_space_count"])), d => d["crack_difficulty"], d => d["password_type"]); //sorts data by crack difficulty and then password type
Insert cell
rollupDataByLength = d3.rollups(UvaPasswords, v => d3.count(v, d => toNum(d["search_space_count"])), d => d["length"], d => d["password_type"]); ////sorts data by length and then password type
Insert cell
Insert cell
Insert cell
import {dvPackCircles} from "@emfielduva/dvlib_layout"
Insert cell
pcElem = d3.select(svgContainer).select('#allpasswords')
Insert cell
pc = dvPackCircles(pcElem,dataLayout,600,600,"alphabet_size",options); // alphabet_size works fine
Insert cell
//pc = dvPackCircles(pcElem,dataLayout,600,600,"search_space_count",options); // for some reason doesn't like search_space_count
Insert cell
Insert cell
options = ({
transitionMS: 1000,
padding: 1,
classField: "password_type",
textLabelField: "password"
})
Insert cell
Insert cell
pc2Elem2 = d3.select(svgContainer).select("#allpasswords")
Insert cell
pc3Elem2 = d3.select(svgContainer).select("#difficulty")
Insert cell
pc4Elem2 = d3.select(svgContainer).select("#length")
Insert cell
Insert cell
import {toNum} from "@emfielduva/dvlib_layout"
Insert cell
rollupData2 = d3.rollups(UvaPasswords, v => d3.count(v, d => toNum(d["search_space_count"])), d => d["password_type"]).sort((a,b) => d3.ascending(a[1],b[1])) //use d3.count to count how many of each type of password
//.sort(a,b) --> compares each a and b value and sorts them
//a[1] --> sorts by column 1 (numeric value)
Insert cell
//rollupDataByLength = d3.rollups(UvaPasswords, v => d3.count(v, d => toNum(d["search_space_count"])), d => d["length"]).sort((a,b) => d3.ascending(a[1],b[1]))

//don't think length is "showing" anything in terms of telling a story
Insert cell
Insert cell
viewof tableRollup = Inputs.table(rollupData)
Insert cell
dataLayoutFullSum = layoutChildren("passwords",rollupData);
Insert cell
pc2Elem = d3.select(svgContainer2).select("#layer1")
Insert cell
pc2 = dvPackCircles(pc2Elem,dataLayoutFullSum,600,600,'',options)

//maybe want to switch order --> group by difficulty then type?
Insert cell
Insert cell
dataLayoutByDifficulty = layoutChildren("passwords", rollupDataByDifficulty);
Insert cell
pc3Elem = d3.select(svgContainer3).select("#difficulty")
Insert cell
pc3 = dvPackCircles(pc3Elem2,dataLayoutByDifficulty,600,600,'',options)
Insert cell
Insert cell
dataLayoutByLength = layoutChildren("passwords", rollupDataByLength);
Insert cell
pc4Elem = d3.select(svgContainer4).select("#length")
Insert cell
pc4 = dvPackCircles(pc4Elem2, dataLayoutByLength,600,600, '',options)
Insert cell
Insert cell
groupDifficulty = d3.groups(UvaPasswords, d => d["crack_difficulty"]) // groups passwords by crack_difficulty (4 categories - easy, moderate, challenging, difficult)
Insert cell
dataLayoutGroupDifficulty= layoutChildren("passwords", groupDifficulty);
Insert cell
pc5Elem = d3.select(svgContainer5).select("#groupdifficulty")
Insert cell
pc5 = dvPackCircles(pc5Elem,dataLayoutGroupDifficulty,1050,600,"length",options)
Insert cell
// options2 = ({
// transitionMS: 1000,
// padding: 1,
// classField: "password_type",
// textLabelField: "password"
// })
Insert cell
Insert cell
groupLength = d3.groups(UvaPasswords, d => d["length"])
Insert cell
dataLayoutGroupLength = layoutChildren("passwords", groupLength);
Insert cell
pc6Elem = d3.select(svgContainer6).select("#grouplength")
Insert cell
pc6 = dvPackCircles(pc6Elem,dataLayoutGroupLength,900,600,"alphabet_size",options)
Insert cell
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