Skip to content

Instantly share code, notes, and snippets.

@MattDionis
Last active June 10, 2018 16:39
Show Gist options
  • Save MattDionis/0477fd73b12753d17194 to your computer and use it in GitHub Desktop.
Save MattDionis/0477fd73b12753d17194 to your computer and use it in GitHub Desktop.
Voronoi Scatterplot

This scatterplot is the final visual of my blog on Using a D3 Voronoi grid to improve a chart's interactive experience in which the tooltip is attached to the circles while the event is triggered by an invisible Voronoi grid that lies over the scatterplot. It also has some other features such as a filtering function when clicking on a region in the legend

forked from nbremer's block: Final - Voronoi Scatterplot - Life expectancy vs GDP per capita

forked from MattDionis's block: Final - Voronoi Scatterplot - Life expectancy vs GDP per capita

forked from MattDionis's block: Final - Voronoi Scatterplot - Life expectancy vs GDP per capita

forked from MattDionis's block: Final - Voronoi Scatterplot - Life expectancy vs GDP per capita

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Scatterplot with Voronoi</title>
<!-- D3.js -->
<script src="http://d3js.org/d3.v3.js"></script>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<!-- Open Sans & CSS -->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:700,400,300' rel='stylesheet' type='text/css'>
<style>
body {
font-family: 'Open Sans', sans-serif;
font-size: 12px;
font-weight: 400;
color: #525252;
text-align: center;
}
html, body {
width:auto;
height:auto;
}
.axis path,
.axis line {
fill: none;
stroke: #B3B3B3;
shape-rendering: crispEdges;
}
.axis text {
font-size: 10px;
fill: #6B6B6B;
}
.popover {
pointer-events: none;
}
.legendCircle {
stroke-width:1;
stroke:#999;
stroke-dasharray:2 2;
fill:none;
}
.legendLine {
stroke-width: 1;
stroke: #D1D1D1;
shape-rendering: crispEdges;
}
.legendTitle {
fill: #1A1A1A;
color: #1A1A1A;
text-anchor: middle;
font-size: 10px;
}
.legendText {
fill: #949494;
text-anchor: start;
font-size: 9px;
}
@media (min-width: 500px) {
.col-sm-3, .col-sm-9 {
float: left;
}
.col-sm-9 {
width: 75%;
}
.col-sm-3 {
width: 25%;
}
}
</style>
</head>
<body>
<div id="cont" class="container-fluid text-center">
<div class="row scatter">
<h5 style="color: #3B3B3B;">Customer Transactions by Type</h5>
<h6 style="color: #A6A6A6;">(Customer Email)</h6>
<div class="col-sm-9">
<div id="vis"></div>
</div>
<div id = "legend" class="col-sm-3" style="padding-right: 0px; padding-left: 0px;">
<div class="legendTitle" style="font-size: 12px;">TRANSACTION TYPE</div>
<div class="legendText" style="font-size: 11px; color: #BABABA;">click to select all transactions by type</div>
<div id="legend"></div>
</div>
</div>
</div>
<script src="worldbank.js"></script>
<script src="script.js"></script>
</body>
</html>
var margin = {
left: 30,
top: 20,
right: 20,
bottom: 20
};
var width = Math.min($('#vis').width(), 800) - margin.left - margin.right;
var height = width * 2 / 3;
var vis = d3.select('#vis').insert('svg', ':first-child')
.attr({
width: width + margin.left + margin.right,
height: height + margin.top + margin.bottom
});
var wrapper = vis.append('g')
.attr('class', 'chordWrapper')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var opacityCircles = 0.7;
var color = d3.scale.ordinal()
.domain(['Deposit', 'Receive', 'Spend', 'Withdrawal'])
.range(['#00986F', '#41A5D1', '#695998', '#CD5053']);
var xScale = d3.scale.log()
.domain(d3.extent(countries, function(d) {
return d.create_date;
}))
.range([0, width])
.nice();
var xAxis = d3.svg.axis()
.orient('bottom')
.ticks(2)
.tickFormat(function (d) {
return xScale.tickFormat(8, function(d) {
var prefix = d3.formatPrefix(d);
return "$" + prefix.scale(d) + prefix.symbol;
})(d);
})
.scale(xScale);
wrapper.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(' + 0 + ',' + height + ')')
.call(xAxis);
var yScale = d3.scale.linear()
.range([height, 0])
.domain(d3.extent(countries, function(d) {
return d.usd_value;
}))
.nice();
var yAxis = d3.svg.axis()
.orient('left')
.ticks(6)
.scale(yScale);
wrapper.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + 0 + ',' + 0 + ')')
.call(yAxis);
var circleGroup = wrapper.append('g')
.attr('class', 'circleWrapper');
circleGroup.selectAll('countries')
.data(countries.sort(function(a, b) {
return b.risk_score > a.risk_score;
}))
.enter().append('circle')
.attr('class', function(d, i) {
return 'countries ' + d.id;
})
.style('opacity', opacityCircles)
.style('fill', function(d) {
return color(d.activity);
})
.attr('cx', function(d) {
return xScale(d.create_date);
})
.attr('cy', function(d) {
return yScale(d.usd_value);
})
.attr('r', 9);
var voronoi = d3.geom.voronoi()
.x(function(d) {
return xScale(d.create_date);
})
.y(function(d) {
return yScale(d.usd_value);
})
.clipExtent([[0, 0], [width, height]]);
var voronoiGroup = wrapper.append('g')
.attr('class', 'voronoiWrapper');
voronoiGroup.selectAll('path')
.data(voronoi(countries))
.enter().append('path')
.attr('d', function(d, i) {
return 'M' + d.join('L') + 'Z';
})
.datum(function(d, i) {
return d.point;
})
.attr('class', function(d, i) {
return 'voronoi ' + d.id;
})
.style('fill', 'none')
.style('pointer-events', 'all')
.on('mouseover', showTooltip)
.on('mouseout', removeTooltip);
wrapper.append('g')
.append('text')
.attr('class', 'x title')
.attr('text-anchor', 'end')
.style('font-size', '12px')
.attr('transform', 'translate(' + width + ',' + (height - 10) + ')')
.text('Date');
wrapper.append('g')
.append('text')
.attr('class', 'y title')
.attr('text-anchor', 'end')
.style('font-size', '12px')
.attr('transform', 'translate(18, 0) rotate(-90)')
.text('Transaction Amount');
var legendMargin = {
left: 5,
top: 10,
right: 5,
bottom: 10
};
var legendWidth = 145;
var legendHeight = 270;
var svgLegend = d3.select('#legend').append('svg')
.attr('width', (legendWidth + legendMargin.left + legendMargin.right))
.attr('height', (legendHeight + legendMargin.top + legendMargin.bottom));
var legendWrapper = svgLegend.append('g')
.attr('class', 'legendWrapper')
.attr('transform', 'translate(' + legendMargin.left + ',' + legendMargin.top +')');
var rectSize = 15;
var rowHeight = 20;
var maxWidth = 144;
var legend = legendWrapper.selectAll('.legendSquare')
.data(color.range())
.enter().append('g')
.attr('class', 'legendSquare')
.attr('transform', function(d, i) {
return 'translate(' + 0 + ',' + (i * rowHeight) + ')';
})
.style('cursor', 'pointer')
.on('mouseover', selectLegend(0.02))
.on('mouseout', selectLegend(opacityCircles))
.on('click', clickLegend);
legend.append('rect')
.attr('width', maxWidth)
.attr('height', rowHeight)
.style('fill', 'white');
legend.append('rect')
.attr('width', rectSize)
.attr('height', rectSize)
.style('fill', function(d) {
return d;
});
legend.append('text')
.attr('transform', 'translate(' + 22 + ',' + (rectSize / 2) + ')')
.attr('class', 'legendText')
.style('font-size', '10px')
.attr('dy', '.35em')
.text(function(d, i) {
return color.domain()[i];
});
function bubbleLegend(wrapperVar, scale, sizes, titleName) {
var legendSize1 = sizes[0];
var legendSize2 = sizes[1];
var legendSize3 = sizes[2];
var legendCenter = 0;
var legendBottom = 50;
var legendLineLength = 25;
var textPadding = 5;
var numFormat = d3.format(',');
wrapperVar.append('text')
.attr('class','legendTitle')
.attr('transform', 'translate(' + legendCenter + ',' + 0 + ')')
.attr('x', 0 + 'px')
.attr('y', 0 + 'px')
.attr('dy', '1em')
.text(titleName);
wrapperVar.append('circle')
.attr('r', scale(legendSize1))
.attr('class','legendCircle')
.attr('cx', legendCenter)
.attr('cy', (legendBottom-scale(legendSize1)));
wrapperVar.append('circle')
.attr('r', scale(legendSize2))
.attr('class','legendCircle')
.attr('cx', legendCenter)
.attr('cy', (legendBottom-scale(legendSize2)));
wrapperVar.append('circle')
.attr('r', scale(legendSize3))
.attr('class','legendCircle')
.attr('cx', legendCenter)
.attr('cy', (legendBottom-scale(legendSize3)));
wrapperVar.append('line')
.attr('class','legendLine')
.attr('x1', legendCenter)
.attr('y1', (legendBottom - 2 * scale(legendSize1)))
.attr('x2', (legendCenter + legendLineLength))
.attr('y2', (legendBottom - 2 * scale(legendSize1)));
wrapperVar.append('line')
.attr('class','legendLine')
.attr('x1', legendCenter)
.attr('y1', (legendBottom - 2 * scale(legendSize2)))
.attr('x2', (legendCenter + legendLineLength))
.attr('y2', (legendBottom - 2 * scale(legendSize2)));
wrapperVar.append('line')
.attr('class','legendLine')
.attr('x1', legendCenter)
.attr('y1', (legendBottom - 2 * scale(legendSize3)))
.attr('x2', (legendCenter + legendLineLength))
.attr('y2', (legendBottom - 2 * scale(legendSize3)));
wrapperVar.append('text')
.attr('class','legendText')
.attr('x', (legendCenter + legendLineLength + textPadding))
.attr('y', (legendBottom - 2 * scale(legendSize1)))
.attr('dy', '0.25em')
.text('$ ' + numFormat(Math.round(legendSize1 / 1e9)) + ' B');
wrapperVar.append('text')
.attr('class','legendText')
.attr('x', (legendCenter + legendLineLength + textPadding))
.attr('y', (legendBottom - 2 * scale(legendSize2)))
.attr('dy', '0.25em')
.text('$ ' + numFormat(Math.round(legendSize2 / 1e9)) + ' B');
wrapperVar.append('text')
.attr('class','legendText')
.attr('x', (legendCenter + legendLineLength + textPadding))
.attr('y', (legendBottom - 2 * scale(legendSize3)))
.attr('dy', '0.25em')
.text('$ ' + numFormat(Math.round(legendSize3 / 1e9)) + ' B');
}
function selectLegend(opacity) {
return function(d, i) {
var chosen = color.domain()[i];
wrapper.selectAll('.countries')
.filter(function(d) {
return d.activity !== chosen;
})
.transition()
.style('opacity', opacity);
};
}
function clickLegend(d, i) {
event.stopPropagation();
d3.selectAll('.legendSquare')
.on('mouseover', null)
.on('mouseout', null);
var chosen = color.domain()[i];
wrapper.selectAll('.countries')
.style('opacity', opacityCircles)
.style('visibility', function(d) {
if (d.activity !== chosen) {
return 'hidden';
} else {
return 'visible';
}
});
wrapper.selectAll('.voronoi')
.on('mouseover', function(d, i) {
if(d.activity !== chosen) {
return null;
} else {
return showTooltip.call(this, d, i);
}
})
.on('mouseout', function(d, i) {
if(d.activity !== chosen) {
return null;
} else {
return removeTooltip.call(this, d, i);
}
});
}
function resetClick() {
d3.selectAll('.legendSquare')
.on('mouseover', selectLegend(0.02))
.on('mouseout', selectLegend(opacityCircles));
wrapper.selectAll('.countries')
.style('opacity', opacityCircles)
.style('visibility', 'visible');
wrapper.selectAll('.voronoi')
.on('mouseover', showTooltip)
.on('mouseout', function (d, i) {
removeTooltip.call(this, d, i);
});
}
d3.select('body').on('click', resetClick);
function removeTooltip (d, i) {
var element = d3.selectAll('.countries.' + d.id);
element.style('opacity', opacityCircles);
$('.popover').each(function() {
$(this).remove();
});
d3.selectAll('.guide')
.transition().duration(200)
.style('opacity', 0)
.remove();
}
function showTooltip (d, i) {
var element = d3.selectAll('.countries.' + d.id);
$(element).popover({
placement: 'auto top',
container: '#vis',
trigger: 'manual',
html : true,
content: function() {
return '<span style="font-size: 11px; text-align: center;">' + d.activity + ": $" + d.usd_value + '</span>';
}
});
$(element).popover('show');
element.style('opacity', 1);
wrapper.append('g')
.attr('class', 'guide')
.append('line')
.attr('x1', element.attr('cx'))
.attr('x2', element.attr('cx'))
.attr('y1', element.attr('cy'))
.attr('y2', (height))
.style('stroke', element.style('fill'))
.style('opacity', 0)
.style('pointer-events', 'none')
.transition().duration(200)
.style('opacity', 0.5);
wrapper.append('g')
.attr('class', 'guide')
.append('line')
.attr('x1', +element.attr('cx'))
.attr('x2', 0)
.attr('y1', element.attr('cy'))
.attr('y2', element.attr('cy'))
.style('stroke', element.style('fill'))
.style('opacity', 0)
.style('pointer-events', 'none')
.transition().duration(200)
.style('opacity', 0.5);
}
var countries = [
{
"id": "AFG",
"activity": "Deposit",
"create_date": 561.2,
"usd_value": 59.60009756
},
{
"id": "ALB",
"activity": "Receive",
"create_date": 4094.36,
"usd_value": 76.9785122
},
{
"id": "DZA",
"activity": "Spend",
"create_date": 4349.57,
"usd_value": 70.61660976
},
{
"id": "AGO",
"activity": "Withdrawal",
"create_date": 4218.65,
"usd_value": 50.65417073
},
{
"id": "ARM",
"activity": "Deposit",
"create_date": 3124.78,
"usd_value": 74.21965854
},
{
"id": "AZE",
"activity": "Deposit",
"create_date": 5842.81,
"usd_value": 70.45029268
},
{
"id": "BHR",
"activity": "Deposit",
"create_date": 20545.97,
"usd_value": 76.26485366
},
{
"id": "BGD",
"activity": "Deposit",
"create_date": 762.8,
"usd_value": 69.48580488
},
{
"id": "BLR",
"activity": "Receive",
"create_date": 5818.85,
"usd_value": 70.40487805
},
{
"id": "BEN",
"activity": "Withdrawal",
"create_date": 690,
"usd_value": 58.74668293
},
{
"id": "BTN",
"activity": "Deposit",
"create_date": 2211.34,
"usd_value": 67.00468293
},
{
"id": "BIH",
"activity": "Receive",
"create_date": 4380.6,
"usd_value": 75.80668293
},
{
"id": "BWA",
"activity": "Withdrawal",
"create_date": 6980.36,
"usd_value": 46.44029268
},
{
"id": "BGR",
"activity": "Receive",
"create_date": 6580.81,
"usd_value": 73.51219512
},
{
"id": "BFA",
"activity": "Withdrawal",
"create_date": 578.67,
"usd_value": 55.0067561
},
{
"id": "BDI",
"activity": "Spend",
"create_date": 219.53,
"usd_value": 52.62402439
},
{
"id": "CPV",
"activity": "Withdrawal",
"create_date": 3413.26,
"usd_value": 73.85697561
},
{
"id": "CMR",
"activity": "Withdrawal",
"create_date": 1145.37,
"usd_value": 53.69482927
},
{
"id": "CAF",
"activity": "Withdrawal",
"create_date": 456.56,
"usd_value": 48.09873171
},
{
"id": "TCD",
"activity": "Withdrawal",
"create_date": 909.3,
"usd_value": 49.76985366
},
{
"id": "COM",
"activity": "Spend",
"create_date": 756.81,
"usd_value": 60.20341463
},
{
"id": "COG",
"activity": "Withdrawal",
"create_date": 2920.41,
"usd_value": 57.20402439
},
{
"id": "CIV",
"activity": "Withdrawal",
"create_date": 1311.33,
"usd_value": 49.67529268
},
{
"id": "HRV",
"activity": "Receive",
"create_date": 13500.85,
"usd_value": 76.47560976
},
{
"id": "CYP",
"activity": "Deposit",
"create_date": 27889.04,
"usd_value": 79.30982927
},
{
"id": "CZE",
"activity": "Receive",
"create_date": 19764.02,
"usd_value": 77.42439024
},
{
"id": "DJI",
"activity": "Spend",
"create_date": 1353.19,
"usd_value": 60.29119512
},
{
"id": "EGY",
"activity": "Spend",
"create_date": 2803.53,
"usd_value": 70.45082927
},
{
"id": "GNQ",
"activity": "Withdrawal",
"create_date": 16638.13,
"usd_value": 51.53307317
},
{
"id": "ERI",
"activity": "Spend",
"create_date": 368.75,
"usd_value": 61.18509756
},
{
"id": "ETH",
"activity": "Spend",
"create_date": 343.69,
"usd_value": 61.46795122
},
{
"id": "GAB",
"activity": "Withdrawal",
"create_date": 9362.11,
"usd_value": 62.2897561
},
{
"id": "GMB",
"activity": "Withdrawal",
"create_date": 566.35,
"usd_value": 58.1335122
},
{
"id": "GEO",
"activity": "Deposit",
"create_date": 2613.76,
"usd_value": 73.67473171
},
{
"id": "GHA",
"activity": "Withdrawal",
"create_date": 1326.09,
"usd_value": 60.59956098
},
{
"id": "GRC",
"activity": "Receive",
"create_date": 26861.46,
"usd_value": 80.38780488
},
{
"id": "GIN",
"activity": "Withdrawal",
"create_date": 435.45,
"usd_value": 55.298
},
{
"id": "GNB",
"activity": "Withdrawal",
"create_date": 534.15,
"usd_value": 53.55843902
},
{
"id": "HUN",
"activity": "Receive",
"create_date": 12958.53,
"usd_value": 74.20731707
},
{
"id": "IND",
"activity": "Deposit",
"create_date": 1417.07,
"usd_value": 65.6942439
},
{
"id": "IRN",
"activity": "Deposit",
"create_date": 5674.92,
"usd_value": 73.13014634
},
{
"id": "IRQ",
"activity": "Deposit",
"create_date": 4473.71,
"usd_value": 68.8297561
},
{
"id": "ISR",
"activity": "Deposit",
"create_date": 30550.92,
"usd_value": 81.60243902
},
{
"id": "ITA",
"activity": "Receive",
"create_date": 35875.73,
"usd_value": 82.03658537
},
{
"id": "JOR",
"activity": "Deposit",
"create_date": 4370.72,
"usd_value": 73.43587805
},
{
"id": "KEN",
"activity": "Spend",
"create_date": 977.78,
"usd_value": 59.54707317
},
{
"id": "KWT",
"activity": "Deposit",
"create_date": 38584.48,
"usd_value": 74.16192683
},
{
"id": "LBN",
"activity": "Deposit",
"create_date": 8755.85,
"usd_value": 79.25278049
},
{
"id": "LSO",
"activity": "Withdrawal",
"create_date": 1083.02,
"usd_value": 47.48341463
},
{
"id": "LBR",
"activity": "Withdrawal",
"create_date": 326.6,
"usd_value": 59.43431707
},
{
"id": "LBY",
"activity": "Spend",
"create_date": 12375.45,
"usd_value": 74.7924878
},
{
"id": "MKD",
"activity": "Receive",
"create_date": 4442.3,
"usd_value": 74.72214634
},
{
"id": "MDG",
"activity": "Spend",
"create_date": 414.14,
"usd_value": 63.34973171
},
{
"id": "MWI",
"activity": "Spend",
"create_date": 359.58,
"usd_value": 53.46570732
},
{
"id": "MDV",
"activity": "Deposit",
"create_date": 6552.48,
"usd_value": 76.78631707
},
{
"id": "MLI",
"activity": "Withdrawal",
"create_date": 673.69,
"usd_value": 53.77073171
},
{
"id": "MLT",
"activity": "Receive",
"create_date": 19695.26,
"usd_value": 81.39756098
},
{
"id": "MRT",
"activity": "Withdrawal",
"create_date": 977.15,
"usd_value": 61.0232439
},
{
"id": "MUS",
"activity": "Spend",
"create_date": 7772.1,
"usd_value": 72.96731707
},
{
"id": "MDA",
"activity": "Receive",
"create_date": 1631.54,
"usd_value": 68.45812195
},
{
"id": "MNE",
"activity": "Receive",
"create_date": 6636.07,
"usd_value": 74.41673171
},
{
"id": "MAR",
"activity": "Spend",
"create_date": 2822.73,
"usd_value": 70.17158537
},
{
"id": "MOZ",
"activity": "Spend",
"create_date": 424.13,
"usd_value": 49.13707317
},
{
"id": "NAM",
"activity": "Withdrawal",
"create_date": 5177.68,
"usd_value": 62.48029268
},
{
"id": "NPL",
"activity": "Deposit",
"create_date": 595.77,
"usd_value": 67.10492683
},
{
"id": "NER",
"activity": "Withdrawal",
"create_date": 359.8,
"usd_value": 56.98563415
},
{
"id": "NGA",
"activity": "Withdrawal",
"create_date": 2310.86,
"usd_value": 51.28941463
},
{
"id": "OMN",
"activity": "Deposit",
"create_date": 20922.66,
"usd_value": 76.04580488
},
{
"id": "PAK",
"activity": "Deposit",
"create_date": 1023.2,
"usd_value": 66.12634146
},
{
"id": "POL",
"activity": "Receive",
"create_date": 12484.07,
"usd_value": 76.24634146
},
{
"id": "PRT",
"activity": "Receive",
"create_date": 22538.65,
"usd_value": 79.02682927
},
{
"id": "QAT",
"activity": "Deposit",
"create_date": 71510.16,
"usd_value": 78.14604878
},
{
"id": "RUS",
"activity": "Receive",
"create_date": 10709.77,
"usd_value": 68.85609756
},
{
"id": "RWA",
"activity": "Spend",
"create_date": 525.85,
"usd_value": 62.21214634
},
{
"id": "STP",
"activity": "Withdrawal",
"create_date": 1127.98,
"usd_value": 65.85368293
},
{
"id": "SAU",
"activity": "Deposit",
"create_date": 19326.58,
"usd_value": 75.07560976
},
{
"id": "SEN",
"activity": "Withdrawal",
"create_date": 998.6,
"usd_value": 62.84187805
},
{
"id": "SRB",
"activity": "Receive",
"create_date": 5399.3,
"usd_value": 74.33658537
},
{
"id": "SYC",
"activity": "Spend",
"create_date": 10842.82,
"usd_value": 73.19756098
},
{
"id": "SLE",
"activity": "Withdrawal",
"create_date": 448.22,
"usd_value": 44.83895122
},
{
"id": "SVK",
"activity": "Receive",
"create_date": 16509.9,
"usd_value": 75.11219512
},
{
"id": "SVN",
"activity": "Receive",
"create_date": 23417.64,
"usd_value": 79.42195122
},
{
"id": "ZAF",
"activity": "Withdrawal",
"create_date": 7389.96,
"usd_value": 54.3907561
},
{
"id": "ESP",
"activity": "Receive",
"create_date": 30736,
"usd_value": 81.62682927
},
{
"id": "LKA",
"activity": "Deposit",
"create_date": 2400.02,
"usd_value": 73.75526829
},
{
"id": "SDN",
"activity": "Spend",
"create_date": 1439.52,
"usd_value": 61.47829268
},
{
"id": "SWZ",
"activity": "Withdrawal",
"create_date": 3261.6,
"usd_value": 48.3457561
},
{
"id": "TZA",
"activity": "Spend",
"create_date": 707.93,
"usd_value": 59.18170732
},
{
"id": "TGO",
"activity": "Withdrawal",
"create_date": 503.16,
"usd_value": 55.46887805
},
{
"id": "TUN",
"activity": "Spend",
"create_date": 4212.15,
"usd_value": 74.60243902
},
{
"id": "TUR",
"activity": "Deposit",
"create_date": 10135.75,
"usd_value": 74.21119512
},
{
"id": "UGA",
"activity": "Spend",
"create_date": 553.26,
"usd_value": 57.29653659
},
{
"id": "UKR",
"activity": "Receive",
"create_date": 2974,
"usd_value": 70.26536585
},
{
"id": "ARE",
"activity": "Deposit",
"create_date": 33885.93,
"usd_value": 76.59860976
},
{
"id": "YEM",
"activity": "Deposit",
"create_date": 1394.53,
"usd_value": 62.52765854
},
{
"id": "ZMB",
"activity": "Spend",
"create_date": 1533.28,
"usd_value": 54.52756098
},
{
"id": "ZWE",
"activity": "Spend",
"create_date": 723.16,
"usd_value": 53.59312195
}
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment