Icosahedron Chart main source: ··· Home

Notes:

  • No data bound to it, it could be to the speed, size, colors
  • Added color scale and the sinusoidal x velocity
  • Added the stop and move when clicked

Code:

  • icosahedron.ejs

    <%  demo = {category: "d3js", key: "icosahedron", files: files}; %>
    
    <script type="text/javascript">$(document).ready(function() {
        window.Charts['<%= demo.category %>']['<%= demo.key %>'].ready();
    })</script>
    
    <%- partial("../mixins/_demo_title", demo) %>
    
    <div id="chart" class="<%= demo.key %>-chart"></div>
    <script type="text/javascript" src="/vendors/bower/d3/d3.min.js"></script>
    <script type="text/javascript" src="/js/d3js/<%= demo.key %>.js"></script>
    <%- partial("../mixins/_notes", demo) %>
    <%- partial("../mixins/_sources_data", demo) %>
    <%- partial("../mixins/_code", demo) %>
  • icosahedron.coffee

    window.Charts = window.Charts || {}
    window.Charts.d3js = window.Charts.d3js || {}
    window.Charts.d3js.icosahedron = window.Charts.d3js.icosahedron || {}
    
    ch = window.Charts.d3js.icosahedron
    
    ch.setCg = -> ch.cg =
      width: $('#chart').innerWidth()
      height: 500
      defaultVelocity: [1, .4, .07]
      zeroVelocity: [0,0,0]
      t0: Date.now()
      color: d3.scale.category20()
      rotationFactor1: 1 / 1000
      rotationFactor2: 4
    
    ch.setDom = -> ch.dom =
      projection: d3.geo.orthographic().scale(ch.cg.height / 2 - 10)
      svg: d3.select('#chart').append('svg')
        .attr('width', ch.cg.width).attr('height', ch.cg.height)
      faces: ''
    
    ch.setVars = -> ch.vars =
      velocity: ''
    
    ch.icosahedronFaces = ->
      faces = []
      y = Math.atan2(1, 2) * 180 / Math.PI
    
      for x in [0...360] by 72
        faces.push(
          [[x +  0, -90], [x +  0,  -y], [x + 72,  -y]],
          [[x + 36,   y], [x + 72,  -y], [x +  0,  -y]],
          [[x + 36,   y], [x +  0,  -y], [x - 36,   y]],
          [[x + 36,   y], [x - 36,   y], [x - 36,  90]]
        )
    
      faces
    
    # Calculates a 3D rotation (sinusoidal in x)
    ch.calcNewPosition = (velocity, time, position)->
      [
        velocity[0] * Math.abs(Math.sin(time * ch.cg.rotationFactor1) * ch.cg.rotationFactor2) + \
          position[0],
        velocity[1] + position[1],
        position[2] + velocity[2]
      ]
    
    ch.timer = ->
      time = Date.now() - ch.cg.t0
      originalPos = ch.dom.projection.rotate()
      
      ch.dom.projection.rotate(ch.calcNewPosition(ch.vars.velocity, time, originalPos))
      
      ch.dom.faces.each((d)-> d.forEach((p, i)-> d.polygon[i] = ch.dom.projection(p); null))
        .style('display', (d)-> if d.polygon.area() > 0 then return null else return 'none')
        .attr('d', (d)-> 'M' + d.polygon.join('L') + 'Z')
        .on('click', ->
          if String(ch.vars.velocity) == String(ch.cg.zeroVelocity)
            ch.vars.velocity = ch.cg.defaultVelocity
          else ch.vars.velocity = ch.cg.zeroVelocity
        )
    
      null
    
    ch.ready =  ->
      ch.setCg()
      ch.setDom()
      ch.setVars()
       
      ch.dom.faces = ch.dom.svg.selectAll('path').data(ch.icosahedronFaces).enter()
        .append('path').each((d)->
          d.polygon = d3.geom.polygon(d.map(ch.dom.projection))
        ).style({fill: (d, index)-> ch.cg.color(index) })
      
      ch.vars.velocity = ch.cg.defaultVelocity
      d3.timer(ch.timer)
    
    # Necessary for testing
    window.Charts.d3js.icosahedron.refreshAlias = ->
      ch = window.Charts.d3js.icosahedron
  • _icosahedron.styl

    .icosahedron-chart
        path 
          fill: #f88e22;
          stroke: #fff;
          stroke-width: 2px; 

Home