block by timelyportfolio 6874932

6874932

Full Screen

script.js

d3.csv('edhec.csv',function (data) {
// CSV section
  var body = d3.select('body')
  var selectData = [ { "text" : "Annualized Return" },
                     { "text" : "Annualized Standard Deviation" },
                     { "text" : "Maximum Drawdown" },
                   ]

  // Select X-axis Variable
  var span = body.append('span')
    .text('Select X-Axis variable: ')
  var yInput = body.append('select')
      .attr('id','xSelect')
      .on('change',xChange)
    .selectAll('option')
      .data(selectData)
      .enter()
    .append('option')
      .attr('value', function (d) { return d.text })
      .text(function (d) { return d.text ;})
  body.append('br')

  // Select Y-axis Variable
  var span = body.append('span')
      .text('Select Y-Axis variable: ')
  var yInput = body.append('select')
      .attr('id','ySelect')
      .on('change',yChange)
    .selectAll('option')
      .data(selectData)
      .enter()
    .append('option')
      .attr('value', function (d) { return d.text })
      .text(function (d) { return d.text ;})
  body.append('br')

  // Variables
  var body = d3.select('body')
  var margin = { top: 50, right: 50, bottom: 50, left: 50 }
  var h = 500 - margin.top - margin.bottom
  var w = 500 - margin.left - margin.right
  var formatPercent = d3.format('.2%')
  // Scales
  var colorScale = d3.scale.category20()
  var xScale = d3.scale.linear()
    .domain([
      d3.min([0,d3.min(data,function (d) { return d['Annualized Return'] })]),
      d3.max([0,d3.max(data,function (d) { return d['Annualized Return'] })])
      ])
    .range([0,w])
  var yScale = d3.scale.linear()
    .domain([
      d3.min([0,d3.min(data,function (d) { return d['Annualized Return'] })]),
      d3.max([0,d3.max(data,function (d) { return d['Annualized Return'] })])
      ])
    .range([h,0])
  // SVG
  var svg = body.append('svg')
      .attr('height',h + margin.top + margin.bottom)
      .attr('width',w + margin.left + margin.right)
    .append('g')
      .attr('transform','translate(' + margin.left + ',' + margin.top + ')')
  // X-axis
  var xAxis = d3.svg.axis()
    .scale(xScale)
    .tickFormat(formatPercent)
    .ticks(5)
    .orient('bottom')
  // Y-axis
  var yAxis = d3.svg.axis()
    .scale(yScale)
    .tickFormat(formatPercent)
    .ticks(5)
    .orient('left')
  // Circles
  var circles = svg.selectAll('circle')
      .data(data)
      .enter()
    .append('circle')
      .attr('cx',function (d) { return xScale(d['Annualized Return']) })
      .attr('cy',function (d) { return yScale(d['Annualized Return']) })
      .attr('r','10')
      .attr('stroke','black')
      .attr('stroke-width',1)
      .attr('fill',function (d,i) { return colorScale(i) })
      .on('mouseover', function () {
        d3.select(this)
          .transition()
          .duration(500)
          .attr('r',20)
          .attr('stroke-width',3)
      })
      .on('mouseout', function () {
        d3.select(this)
          .transition()
          .duration(500)
          .attr('r',10)
          .attr('stroke-width',1)
      })
    .append('title') // Tooltip
      .text(function (d) { return d.variable +
                           '\nReturn: ' + formatPercent(d['Annualized Return']) +
                           '\nStd. Dev.: ' + formatPercent(d['Annualized Standard Deviation']) +
                           '\nMax Drawdown: ' + formatPercent(d['Maximum Drawdown']) })
  // X-axis
  svg.append('g')
      .attr('class','axis')
      .attr('id','xAxis')
      .attr('transform', 'translate(0,' + h + ')')
      .call(xAxis)
    .append('text') // X-axis Label
      .attr('id','xAxisLabel')
      .attr('y',-10)
      .attr('x',w)
      .attr('dy','.71em')
      .style('text-anchor','end')
      .text('Annualized Standard Deviation')
  // Y-axis
  svg.append('g')
      .attr('class','axis')
      .attr('id','yAxis')
      .call(yAxis)
    .append('text') // y-axis Label
      .attr('id', 'yAxisLabel')
      .attr('transform','rotate(-90)')
      .attr('x',0)
      .attr('y',5)
      .attr('dy','.71em')
      .style('text-anchor','end')
      .text('Annualized Return')

  function yChange() {
    var value = this.value // get the new y value
    yScale // change the yScale
      .domain([
        d3.min([0,d3.min(data,function (d) { return d[value] })]),
        d3.max([0,d3.max(data,function (d) { return d[value] })])
        ])
    yAxis.scale(yScale) // change the yScale
    d3.select('#yAxis') // redraw the yAxis
      .transition().duration(1000)
      .call(yAxis)
    d3.select('#yAxisLabel') // change the yAxisLabel
      .text(value)    
    d3.selectAll('circle') // move the circles
      .transition().duration(1000)
      .delay(function (d,i) { return i*100})
        .attr('cy',function (d) { return yScale(d[value]) })
  }

  function xChange() {
    var value = this.value // get the new x value
    xScale // change the xScale
      .domain([
        d3.min([0,d3.min(data,function (d) { return d[value] })]),
        d3.max([0,d3.max(data,function (d) { return d[value] })])
        ])
    xAxis.scale(xScale) // change the xScale
    d3.select('#xAxis') // redraw the xAxis
      .transition().duration(1000)
      .call(xAxis)
    d3.select('#xAxisLabel') // change the xAxisLabel
      .transition().duration(1000)
      .text(value)
    d3.selectAll('circle') // move the circles
      .transition().duration(1000)
      .delay(function (d,i) { return i*100})
        .attr('cx',function (d) { return xScale(d[value]) })
  }
})

index.html

<!DOCTYPE html>
<meta charset='utf-8'>
<html>
  <head>
    <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <link rel='stylesheet' href='style.css'>
  </head>
  <body>
    <script type='text/javascript' src='script.js'></script>
  </body>
</html>

edhec.csv

"variable","Annualized Return","Annualized Standard Deviation","Maximum Drawdown"
"Convertible Arbitrage",0.0770203710991655,0.0694461870173684,0.292688394529575
"CTA Global",0.0767109922711062,0.0870559916457339,0.11676813742079
"Distressed Securities",0.0975096216543971,0.0635590261337229,0.229232535454022
"Emerging Markets",0.0936124939942315,0.133615370977481,0.359789528051813
"Equity Market Neutral",0.0739359541312794,0.031197069331753,0.110823378150652
"Event Driven",0.093190424075422,0.0635679064016912,0.200817391305532
"Fixed Income Arbitrage",0.0506750901161104,0.0490908049045477,0.178792725850406
"Global Macro",0.0942083012167199,0.0589577044136273,0.0792292782044611
"Long Short Equity",0.0940147333764296,0.0768123568274029,0.218197216318131
"Merger Arbitrage",0.0837211944713991,0.0386880290509073,0.0563420437745007
"Relative Value",0.0823165777302135,0.0457077150038685,0.159407479811612
"Short Selling",0.0326542894911763,0.190869128421505,0.495619599274476
"Funds of Funds",0.0712702593390044,0.0630880736754868,0.20591447069347

style.css

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  position: relative;
  width: 960px;
}

.axis text {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.bar {
  fill: steelblue;
  fill-opacity: .9;
}

.bar:hover {
  fill: orange;
}

label {
  position: absolute;
  top: 10px;
  right: 10px;
}