Data Source: https://coinmarketcap.com/tokens/views/all/
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js"></script>
<title>Token types</title>
<style>
body {
margin: 0px;
}
.domain {
display: none;
}
.legendCells text {
font-size: 12.6pt;
font-family: sans-serif;
}
.legend-label {
fill: #000000;
font-size: 20pt;
font-family: sans-serif;
}
.link {
text-decoration: underline;
fill: #0000EE;
}
#credit-wrapper {
transform: translate(575px, 450px);
font-family: Montserrat, sans-serif;
font-size: .8em;
}
.credit-link {
text-anchor: middle;
fill: #000000;
text-decoration: underline;
}
</style>
</head>
<body>
<svg width="960" height="500"></svg>
<script>
const pieValue = d => d.value;
const colorValue = d => d.key;
const colorLabel = 'Token Type';
const margin = { left: 5, right: 400, top: 5, bottom: 1 };
const svg = d3.select('svg');
const width = svg.attr('width');
const height = svg.attr('height');
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
svg.attr("xmlns","https://www.w3.org/2000/svg");
svg.attr("xmlns:xlink","https://www.w3.org/1999/xlink");
const pie = d3.pie().value(pieValue);
const arc = d3.arc()
.innerRadius(0)
.outerRadius(innerHeight/2.7);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const pieG = g.append('g')
.attr('transform', `translate(${innerWidth / 2},${innerHeight /2})`);
const colorLegendG = g.append('g')
.attr('transform', `translate(${innerWidth + 0}, 90)`);
colorLegendG.append('text')
.attr('class', 'legend-label')
.attr('x', -20)
.attr('y', -25)
.text(colorLabel);
const colorScale = d3.scaleOrdinal()
.range(d3.schemeCategory20);
const colorLegend = d3.legendColor()
.scale(colorScale)
.shape('circle')
.shapePadding(4)
.shapeRadius(7);
const row = d => {
return d;
};
var tokens = {};
tokens['Ethereum'] = 'https://www.ethereum.org/';
tokens['Waves'] = 'https://wavesplatform.com/';
tokens['BitShares'] = 'https://bitshares.org/';
tokens['Omni'] = 'https://www.omnilayer.org/';
tokens['Counterparty'] = 'https://counterparty.io/';
tokens['Qtum'] = 'https://qtum.org/';
tokens['NEO'] = 'https://neo.org/';
tokens['Nxt'] = 'https://nxtplatform.org/';
tokens['NEM'] = 'https://nem.io/';
tokens['Ubiq'] = 'https://ubiqsmart.com/';
tokens['Burst'] = 'https://www.burst-coin.org/';
tokens['Stellar'] = 'https://www.stellar.org/';
tokens['Ethereum Classic'] = 'https://ethereumclassic.github.io/';
tokens['NuBits'] = 'https://nubits.com/';
tokens['Ardor'] = 'https://www.ardorplatform.org/';
d3.csv('platforms.csv', row, dataRaw => {
const token_types = [];
const types = [];
var total = 0;
var i = 0;
for (data in dataRaw) {
if(dataRaw[data]['id']) {
total += 1;
platform = dataRaw[data]['platform'];
if (types.includes(platform) == false) {
types.push(platform);
}
}
}
for(type in types) {
var tt = {};
tt.platform = types[type];
var type_count = 0;
for (data in dataRaw) {
if(dataRaw[data]['platform'] == types[type]) {
type_count ++;
}
}
tt.typeCount = type_count;
tt.perc = parseFloat(parseFloat((type_count / total) * 100).toFixed(1));
tt.key = tt.platform + '|' + tt.perc + '|' + tt.typeCount;
token_types.push(tt);
}
token_types.sort(compareValues('perc'));
var arcs = d3.pie()
.value(function(d) { return d.perc; })
(token_types);
pieG.selectAll('path').data(arcs)
.enter().append('path')
.attr('d', arc)
.attr('fill', d => colorScale(colorValue(d.data)));
colorLegendG.call(colorLegend)
.selectAll('.cell text')
.attr('dy', '0.1em');
var token_names = [];
var percs = [];
var coinCount = [];
colorLegendG.selectAll('g.cell')
.each(function(d) {
if(d) {
childNodes = d3.select(this)._groups[0][0].childNodes;
if(childNodes.length == 2) {
var arr = childNodes[1].childNodes[0].textContent.split('|');
var index = 2;
if(arr.length == 4) {
index = 3;
token_names.push(arr[0] + ' ' + arr[1]);
}
else {
token_names.push(arr[0]);
}
percs.push(arr[1]);
coinCount.push(arr[index]);
d3.select(this)._groups[0][0].childNodes[1].remove();
}
}
});
colorLegendG.selectAll('g.cell')
.append('text')
.attr('id', 'subtitle-text')
.attr('dy', '0.1em')
.attr('transform', 'translate(17, 5)')
.append('tspan')
.append('a')
.attr('class', 'link')
.attr('xlink:href', function(d, i) {
return tokens[token_names[i]];
})
.attr('target', '_blank')
.text(function(d, i) {
return token_names[i] + ' (' + percs[i] + '%, ' + coinCount[i] + ' total)';
});
addCredit();
});
function compareValues(key, order='desc') {
return function(a, b) {
if(!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
return 0;
}
const varA = (typeof a[key] === 'string') ?
a[key].toUpperCase() : a[key];
const varB = (typeof b[key] === 'string') ?
b[key].toUpperCase() : b[key];
let comparison = 0;
if (varA > varB) {
comparison = 1;
} else if (varA < varB) {
comparison = -1;
}
return (
(order == 'desc') ? (comparison * -1) : comparison
);
};
}
function addCredit() {
var svg_root = d3.select('svg')
.append('g')
.attr('id', 'credit-wrapper')
.append('text')
.attr('id', 'credit')
.text('Source: ')
.append('tspan')
.append('a')
.attr('class', 'credit-link')
.attr('xlink:href', 'https://coinmarketcap.com/tokens/views/all/')
.attr('target', '_blank')
.text('Coin Market Cap');
}
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js