Built with blockbuilder.org
Last active
April 22, 2020 16:59
-
-
Save djokicx/4fcd66d72a7c0140f8f10014fbfbe31d to your computer and use it in GitHub Desktop.
Yodlee Datasets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dataset | |
BASIC_AGG_DATA | |
ADVANCE_AGG_DATA | |
ACCT_PROFILE | |
DOCUMENTS | |
BASIC_AGG_DATA-BASIC_ACCOUNT_INFO | |
BASIC_AGG_DATA-ACCOUNT_DETAILS | |
BASIC_AGG_DATA-TRANSACTIONS | |
BASIC_AGG_DATA-HOLDINGS | |
BASIC_AGG_DATA-STATEMENTS | |
ADVANCE_AGG_DATA-INTEREST_DETAILS | |
ADVANCE_AGG_DATA-PAYMENT_DETAILS | |
ADVANCE_AGG_DATA-COVERAGE | |
ACCT_PROFILE-FULL_ACCT_NUMBER | |
ACCT_PROFILE-BANK_TRANSFER_CODE | |
ACCT_PROFILE-PAYMENT_PROFILE | |
ACCT_PROFILE-HOLDER_NAME | |
ACCT_PROFILE-HOLDER_DETAILS | |
DOCUMENTS-TAX | |
DOCUMENTS-STATEMENTS | |
DOCUMENTS-EBILLS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<link href="style.css" rel="stylesheet" type="text/css"> | |
<title>SF Arrests</title> | |
</head> | |
<body> | |
<!-- | |
hard-code the svg and various g layers so that even if the streets are loaded | |
and drawn last, they will still show up behind the symbols | |
--> | |
<svg width="960" height="700" id="vis"> | |
<g id="details" pointer-events="none"></g> | |
</svg> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script> | |
const data = "./datasets.csv"; | |
const diameter = 500; | |
const pad = 14; | |
const height = 500; | |
const width = 960; | |
const r = 13; | |
const radialLine = d3.linkRadial() | |
.angle(d => d.theta + Math.PI / 2) // rotate, 0 angle is mapped differently here | |
.radius(d => d.radial); | |
const numberFormat = d3.format(".2~s"); | |
let body; | |
let details; | |
d3.csv(data).then(function(original) { | |
nodes = new Set(original.map(row => row.dataset)) | |
let processed = original.map(function(row) { | |
let parent = row.dataset.substring(0, row.dataset.lastIndexOf("-")); | |
return { | |
name : row.dataset, | |
parent: nodes.has(parent) ? parent : "Datasets", | |
} | |
}) | |
processed.push( | |
{ | |
name: "Datasets", | |
parent: "", | |
} | |
) | |
let root = d3.stratify() | |
.id(function(row) { return row.name; }) | |
.parentId(function(row) {return row.parent;}) | |
(processed); | |
root.count(); | |
root.each(function(node) { | |
// copy this calculation since value is sometimes overwritten | |
node.data.leaves = node.value; | |
}) | |
root.sum(row => row.count) | |
root.each(function(node) { | |
// copy this calculation since value is sometimes overwritten | |
node.data.total = node.value; | |
}) | |
let data = root; | |
data.sort(function(a, b) { | |
return b.height - a.height || b.count - a.count; | |
}); | |
color = d3.scaleSequential([0, root.height], d3.interpolateBlues) | |
let layout = d3.cluster().size([2 * Math.PI, (diameter / 2) - pad]); | |
layout(data); | |
data.each(function(node) { | |
node.theta = node.x; | |
node.radial = node.y; | |
var point = toCartesian(node.radial, node.theta); | |
node.x = point.x; | |
node.y = point.y; | |
}); | |
let svg = d3.select("#vis") | |
.style("width", width) | |
.style("height", height); | |
let plot = svg.append("g") | |
.attr("id", "plot") | |
.attr("transform", `translate(${width/ 3}, ${height/2})`); | |
const extraInfo = svg.select("g#details") | |
details = extraInfo.append("foreignObject") | |
.attr("id", "details") | |
.attr("width", 960) | |
.attr("height", 600) | |
.attr("x", width/ 2 + 150) | |
.attr("y", height/5); | |
body = details.append("xhtml:body") | |
.style("text-align", "left") | |
.style("background", "none") | |
.html("<p>N/A</p>"); | |
details.style("visibility", "hidden"); | |
drawNodes(plot.append("g"), data.descendants(), true); | |
drawLinks(plot.append("g"), data.links(), radialLine); | |
}); | |
function toCartesian(r, theta) { | |
return { | |
x: r * Math.cos(theta), | |
y: r * Math.sin(theta) | |
}; | |
} | |
function drawLinks(g, links, generator) { | |
let paths = g.selectAll('path') | |
.data(links) | |
.enter() | |
.append('path') | |
.attr('d', generator) | |
.attr('class', 'link'); | |
} | |
function drawNodes(g, nodes, raise) { | |
let circles = g.selectAll('circle') | |
.data(nodes, node => node.data.name) | |
.enter() | |
.append('circle') | |
.attr('r', d => d.r ? d.r : r) | |
.attr('cx', d => d.x) | |
.attr('cy', d => d.y) | |
.attr('id', d => d.data.name) | |
.attr('class', 'node') | |
.style('fill', d => color(d.depth)); | |
setupEvents(g, circles, raise); | |
} | |
function setupEvents(g, selection, raise) { | |
selection.on('mouseover.highlight', function(d) { | |
// https://github.com/d3/d3-hierarchy#node_path | |
// returns path from d3.select(this) node to selection.data()[0] root node | |
let path = d3.select(this).datum().path(selection.data()[0]); | |
// select all of the nodes on the shortest path | |
let update = selection.data(path, node => node.data.name); | |
// highlight the selected nodes | |
update.classed('selected', true); | |
if (raise) { | |
update.raise(); | |
} | |
}); | |
selection.on('mouseout.highlight', function(d) { | |
let path = d3.select(this).datum().path(selection.data()[0]); | |
let update = selection.data(path, node => node.data.name); | |
update.classed('selected', false); | |
}); | |
// show tooltip text on mouseover (hover) | |
selection.on('mouseover.tooltip', function(d) { | |
let node = d3.select(this); | |
let nodeData = node.datum(); | |
let nodeChildren = nodeData.children; | |
console.log(node); | |
console.log(nodeChildren); | |
if(nodeChildren) { | |
nodeChildren.forEach(element => { | |
let childSelector = '#' + element.data.name; | |
showTooltip(g, d3.select(childSelector)); | |
}); | |
} | |
console.log(node.datum()); | |
let parentName = node.datum().id.substring(0, node.datum().id.lastIndexOf("-")); | |
if(!parentName.length == 0) { | |
let parent = d3.select("circle#" + parentName + ".node") | |
showTooltip(g, parent); | |
const html = ` | |
<table border="0" cellspacing="0" cellpadding="2"> | |
<tbody> | |
<tr> | |
<th>Attribute:</th> | |
<td id="attribute">${node.datum().id.substring(node.datum().id.lastIndexOf("-") + 1)}</td> | |
</tr> | |
<tr> | |
<th>Dataset:</th> | |
<td>${parentName}</td> | |
</tr> | |
<tr> | |
<th>Description:</th> | |
<td>Full account number</td> | |
</tr> | |
<tr> | |
<th>Qualities:</th> | |
<td>Sensitive information</td> | |
</tr> | |
<tr> | |
<th>Containers:</th> | |
<td> | |
<ul> | |
<li>Bank</li> | |
<li>Investment</li> | |
<li>Credit Card</li> | |
<li>Insurance</li> | |
<li>Loan</li> | |
<li>Reward</li> | |
</ul> | |
</td> | |
</tr> | |
<tr> | |
<th>Regions:</th> | |
<td> | |
<ul> | |
<li>US</li> | |
<li>UK</li> | |
<li>Canada</li> | |
<li>Insurance</li> | |
<li>Australia</li> | |
<li>India</li> | |
</ul> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
`; | |
body.html(html); | |
details.style("visibility", "visible"); | |
} | |
showTooltip(g, node); | |
}); | |
// remove tooltip text on mouseout | |
selection.on('mouseout.tooltip', function(d) { | |
g.selectAll("#tooltip").remove(); | |
details.style("visibility", "hidden"); | |
}); | |
} | |
function showTooltip(g, node) { | |
let gbox = g.node().getBBox(); // get bounding box of group BEFORE adding text | |
let nbox = node.node().getBBox(); // get bounding box of node | |
// calculate shift amount | |
let dx = nbox.width / 2; | |
let dy = nbox.height / 2; | |
// retrieve node attributes (calculate middle point) | |
let x = nbox.x + dx; | |
let y = nbox.y + dy; | |
// get data for node | |
let datum = node.datum(); | |
let name = node.datum().id.substring(node.datum().id.lastIndexOf("-") + 1); | |
// let name = datum.data.name.substring(datum.data.name) | |
text = `${name}`; | |
// create tooltip | |
let tooltip = g.append('text') | |
.text(text) | |
.attr('x', x) | |
.attr('y', y) | |
.attr('dy', -dy - 4) // shift upward above circle | |
.attr('text-anchor', 'middle') // anchor in the middle | |
.attr('id', 'tooltip'); | |
// it is possible the tooltip will fall off the edge of the | |
// plot area. we can detect when this happens, and set the | |
// text anchor appropriately | |
// get bounding box for the text | |
let tbox = tooltip.node().getBBox(); | |
// if text will fall off left side, anchor at start | |
if (tbox.x < gbox.x) { | |
tooltip.attr('text-anchor', 'start'); | |
tooltip.attr('dx', -dx); // nudge text over from center | |
} | |
// if text will fall off right side, anchor at end | |
else if ((tbox.x + tbox.width) > (gbox.x + gbox.width)) { | |
tooltip.attr('text-anchor', 'end'); | |
tooltip.attr('dx', dx); | |
} | |
// if text will fall off top side, place below circle instead | |
if (tbox.y < gbox.y) { | |
tooltip.attr('dy', dy + tbox.height); | |
} | |
} | |
</script> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
svg { | |
border: 1px dotted whitesmoke; | |
} | |
.node { | |
stroke: silver; | |
stroke-width: 3px; | |
} | |
.link { | |
fill: none; | |
stroke: silver; | |
stroke-width: 1px; | |
} | |
.selected { | |
stroke: #F05E23 !important; | |
stroke-width: 3px; | |
} | |
text#tooltip { | |
font-family: sans-serif; | |
font-size: 12px; | |
text-shadow: 1px 1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, -1px -1px 0 #fff; | |
font-weight: 900; | |
} | |
td#attribute { | |
font-weight: 900; | |
} | |
th { | |
font-weight: 100; | |
} | |
#details { | |
font-family: sans-serif; | |
font-size: 12px; | |
text-shadow: 1px 1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, -1px -1px 0 #fff; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment