Skip to content

Instantly share code, notes, and snippets.

@iexviz
Last active March 29, 2017 01:45
Show Gist options
  • Save iexviz/82dfa10db7b2fc6c1ad54cc4cfd1c243 to your computer and use it in GitHub Desktop.
Save iexviz/82dfa10db7b2fc6c1ad54cc4cfd1c243 to your computer and use it in GitHub Desktop.
IEX Market - Olympics Sprint
license: gpl-3.0
height: 960
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: #020202;
margin: auto;
width: 960px;
}
.tracks {
fill: none;
stroke: #494949;
stroke-width: 1.5px;
}
.bodies path {
stroke: #666666;
stroke-width: 1.5px;
}
.bodies .text-path {
stroke: none;
}
.bodies text {
fill: #424242;
font: 500 16px "Helvetica Neue";
}
</style>
<body align=center bgcolor=white>
<div class=dropdown></div>
<svg width="960" height="960"></svg>
<script src="//d3js.org/d3.v4.0.0-alpha.21.min.js"></script>
<script src="karthiviz.js"></script>
<script>
function updateviz(key){
d3.select("body").selectAll("svg").remove();
var svg = d3.select("body").append("svg")
.attr('width',650)
.attr('height',650),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = Math.min(width, height) / 1.9,
bodyRadius = radius / 33,
dotRadius = bodyRadius - 8;
var pi = Math.PI*50;
var fields = data
var color = d3.scaleRainbow()
.domain([0, 360]);
var arcBody = d3.arc()
.startAngle(function(d) { return bodyRadius / d.radius; })
.endAngle(function(d) { return -pi*d.value/3000 - bodyRadius / d.radius; })
.innerRadius(function(d) { return d.radius/2 - bodyRadius; })
.outerRadius(function(d) { return d.radius/2 + bodyRadius; })
.cornerRadius(bodyRadius);
var arcTextPath = d3.arc()
.startAngle(function(d) { return -bodyRadius / d.radius; })
.endAngle(function(d) { return -pi; }) .innerRadius(function(d) { return d.radius/2; })
.outerRadius(function(d) { return d.radius/2 });
var g = svg.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
g.append("g")
.attr("class", "tracks")
.selectAll("circle")
.data(fields)
.enter().append("circle")
.attr("r", function(d) { return d.radius/2; });
var body = g.append("g")
.attr("class", "bodies")
.selectAll("g")
.data(fields)
.enter().append("g");
body.append("path")
.attr("d", function(d) {
return arcBody(d)
+ "M0," + (dotRadius - d.radius)
// + "a" + dotRadius + "," + dotRadius + " 0 0,1 0," + -dotRadius * 2
// + "a" + dotRadius + "," + dotRadius + " 0 0,1 0," + dotRadius * 2;
});
body.append("path")
.attr("class", "text-path")
.attr("id", function(d, i) { return "body-text-path-" + i; })
.attr("d", arcTextPath);
var bodyText = body.append("text")
.attr("dy", ".35em")
.append("textPath")
.attr("xlink:href", function(d, i) { return "#body-text-path-" + i; });
tick();
d3.timer(tick);
function tick() {
var now = Date.now();
fields.forEach(function(d,i) {
var start = d.interval(now),
end = d.interval.offset(start, 6);
d.angle = Math.round((now - start) / (end - start) * 360 * 100) / 100*i;
});
body
.style("fill", function(d) { return color(d.angle); })
.attr("transform", function(d) { return "rotate(" + d.angle + ")"; });
bodyText
.attr("startOffset", function(d, i) { return d.angle <= 90 || d.angle > 270 ? "100%" : "0%"; })
.attr("text-anchor", function(d, i) { return d.angle <= 90 || d.angle > 270 ? "end" : "start"; })
.text(function(d) { return d.name
+' ('+formatAbbreviation(d[key])+')';
});
}
function formatDate(d) {
d = new Date(d).getDate();
switch (10 <= d && d <= 19 ? 10 : d % 10) {
case 1: d += "st"; break;
case 2: d += "nd"; break;
case 3: d += "rd"; break;
default: d += "th"; break;
}
return d;
}
}
</script>
d3.jsonp = function (url, callback) {
function rand() {
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
c = '', i = -1;
while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
return c;
}
function create(url) {
var e = url.match(/callback=d3.jsonp.(\w+)/),
c = e ? e[1] : rand();
d3.jsonp[c] = function(data) {
callback(data);
delete d3.jsonp[c];
script.remove();
};
return 'd3.jsonp.' + c;
}
var cb = create(url),
script = d3.select('head')
.append('script')
.attr('type', 'text/javascript')
.attr('src', url.replace(/(\{|%7B)callback(\{|%7D)/, cb));
};
d3.jsonp("https://api.iextrading.com/1.0/market?callback=visualise");
function visualise(data){
window.data = data;
var option = [ "marketPercent", "volume", "tapeA", "tapeB", "tapeC"]
var key = option[0]
var select = d3.select('.dropdown')
.append('select')
.style('font-size', '20px')
.attr('class','select')
.on('change',onchange);
var options = select
.selectAll('option')
.data(option).enter()
.append('option')
.text(function (d) { return d; });
function onchange() {
renderviz(d3.select('select').property('value'))
}
data.forEach(function(d,i) {
d.marketPercent = (d.marketPercent*100).toFixed(2);
});
renderviz(key)
};
function renderviz(key) {
var circs = []
data.forEach(function(d){ circs.push(d[key])})
//console.log(d3.sum(circs).toFixed(0))
var rscale = d3.scaleSqrt()
.domain([0,(d3.sum(circs)).toFixed(0)])
.range([0,100])
data.forEach(function(d,i) {
d.name = d.venueName;
d.value = rscale(d[key]).toFixed(2);
d.interval = d3.timeMinute;
d.format = d3.format(",");
});
data = sanitize(data)
data.forEach(function(d,i) {
d.radius = i*2*20;
});
console.log(data)
var color = d3.scaleOrdinal(d3.schemeCategory20c);;
color = function(d) {
if(d.name == "IEX"){return "orange"}
return "darkcyan";
}
window.color = color;
updateviz(key);
//setuptip(key);
}
function setuptip(key) {
var format = d3.format(",")
tip = d3.tip()
.attr('class', 'd3-tip')
.html(function(d) { return d.name + ": " + format(d[key]) });
d3.selectAll(".arc").call(tip)
d3.selectAll('.arc')
.data(data)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
}
function sanitize(data) {
data.sort(function (a, b) {
var v1 = a.value;
var v2 = b.value;
return (v1 - v2 )
});
return data;
}
formatAbbreviation = function(x) {
var formatNumber = d3.format(".0f"),
formatPercent = d3.format(".2f"),
formatBillion = function(x) { return "$" + formatNumber(x / 1e9) + "B"; },
formatMillion = function(x) { return "$" + formatNumber(x / 1e6) + "M"; },
formatThousand = function(x) { return "$" + formatNumber(x / 1e3) + "k"; };
var v = Math.abs(x);
return (v >= .9995e9 ? formatBillion
: v >= .9995e6 ? formatMillion
: v >= .9995e3 ? formatThousand
: formatPercent)(x);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment