block by 1wheel 5f0913c88cf80c6a3b00afb7b4f832db

regl-tax-scatter

Full Screen

Sketch for Tax Bill Calculator: Will Your Taxes Go Up or Down?.

To dev:

yarn && yarn run start

Edit script.js and the page will update without a full reload.

_script.js

try { window.regltick.cancel() } catch(e){}
console.clear()

d3.loadData('data-2.csv', (err, res) => {
  window.data = res[0]

  data.forEach(d =>{
    d.combinedtaxchg = +d.combinedtaxchg
    d.combinedtaxchg27 = +d.combinedtaxchg27
    d.expanded_income = +d.expanded_income

  })

  var sel = d3.select('#graph').html('')

  c = d3.conventions({sel, layers: 'ds', margin: {left: 60, bottom: 30}, totalHeight: innerHeight})

  c.x.domain([-10000, 10000]).range([-1, 1])
  c.y.domain([10000, 200000]).range([-1, 1])
  c.yl = d3.scaleLog().domain([10000, 2000000]).range([-1, 1])

  data.forEach(d => {
    d.linearAll = [
      c.x(d.combinedtaxchg), 
      c.y(d.expanded_income),
      2
    ]
    d.logAll = [
      c.x(d.combinedtaxchg), 
      c.yl(d.expanded_income),
      2
    ]

    d.logAll = [
      c.x(d.combinedtaxchg), 
      c.yl(d.expanded_income),
      2
    ]
    d.logStandard = [
      c.x(d.combinedtaxchg), 
      c.yl(d.expanded_income),
      d.standard == 1 ? 2 : 0
    ]
    d.logNoStandard = [
      c.x(d.combinedtaxchg), 
      c.yl(d.expanded_income),
      d.standard == 1 ? 0 : 1
    ]
    

    d.posR = [Math.random()*2 - 1, Math.random()*2 - 1]
    d.color = 1
  })

  c.x.range([0, c.width])
  c.y.range([c.height, 0])
  c.yl.range([c.height, 0])
  
  c.yAxis.tickFormat(d3.format(',')).tickValues([10000, 50000, 100000, 500000, 1000000])
  d3.drawAxis(c)


  // var canvas = c.layers[0].append('canvas').st({width: c.width, height: c.height}).node()
  // canvas = document.getElementsByTagName('canvas')[0]
  // canvas = null

  // window.regl ? onDone(null, regl) : reglLib({onDone, container: c.layers[0].node()})

  reglLib({onDone, container: c.layers[0].node()})
})


function onDone(err, regl){
  if (err){
    // throw 'up'
    return console.log(err)
  }
  window.regl = regl

  var count = data.length
  var curIndex = 0
  var datasets = ['linearAll', 'logAll'].map(str => {
    var pos = data.map(d => d[str])
    return {str, pos}
  })



  var drawPoints = regl({
    vert: `
      precision mediump float;
      attribute vec3 xyz0, xyz1;
      attribute float basis;
      varying float c;
      uniform float interp, radius;      
      void main() {
        vec3 pos = mix(xyz0, xyz1, interp);
        gl_Position = vec4(pos.xy, 0, 1);

        // gl_PointSize = pos.z;
        // c = .2;
        
        gl_PointSize = 3.0;
        c = pos.z/20.0;
      }`,

    frag: `
      precision mediump float;
      varying float c;
      void main() {
        gl_FragColor = vec4(255, 0, 255, c);
      }`,

    lineWidth: 1,
    attributes: {
      xyz0: () => datasets[curIndex % datasets.length].pos,
      xyz1: () => datasets[(curIndex + 1) % datasets.length].pos,
      basis: data.map(d => d.color),
    },
    uniforms: {
      radius: () => 2,
      interp: (ctx, props) => Math.max(0, Math.min(1, props.interp))
    },
    primitive: 'point',
    count: count,

    depth: {
      enable: false
    },

    blend: {
      enable: true,
      func: {
        srcRGB: 'src alpha',
        srcAlpha: 1,
        dstRGB: 'one minus src alpha',
        dstAlpha: 1
      },
      equation: {
        rgb: 'add',
        alpha: 'add'
      },
      color: [0, 0, 0, 0]
    },

  })

  var lastSwitchTime = 0
  var switchInterval = 3
  var switchDuration = 2

  window.regltick = regl.frame(({time}) => {
    if ((time - lastSwitchTime) > switchInterval) {
      lastSwitchTime = time
      curIndex = (curIndex + 1) % datasets.length

      c.svg.selectAll('.y')
        .transition()
        .duration(switchDuration*1000)
        .call(c.yAxis.scale(curIndex ? c.y : c.yl))
    }

    drawPoints({interp: d3.easeBackOut((time - lastSwitchTime) / switchDuration)})
  })


}


index.html

<!DOCTYPE html>
<html>
<head>
<body>
	<div id='graph'></div>
</body>

<script src='d3+_.js'></script>
<script src='lib-build.js'></script>
<script src='_script.js'></script>
</html>

lib-src.js

var libs = {
  reglLib: require('regl'),
}



for (key in libs) window[key] = libs[key]

package.json

{
  "version": "1.0.0",
  "description": "watchify and hot-server",
  "scripts": {
    "start": "watchify -t glslify lib-src.js -o lib-build.js & hot-server"
  },
  "dependencies": {
    "browserify": "^14.1.0",
    "budo": "^9.4.7",
    "control-panel": "^1.2.0",
    "d3": "^4.10.2",
    "eases": "^1.0.8",
    "es2040": "^1.2.5",
    "fail-nicely": "^2.0.0",
    "github-cornerify": "^1.0.7",
    "glsl-colormap": "^1.0.1",
    "glsl-noise": "^0.0.0",
    "glslify": "^6.0.1",
    "hot-server": "^0.0.13",
    "indexhtmlify": "^1.3.1",
    "metadataify": "^1.0.3",
    "ndarray": "^1.0.18",
    "ndarray-linspace": "^2.0.3",
    "ndarray-vector-fill": "^1.0.0",
    "regl": "^1.3.0",
    "standard": "^9.0.1",
    "uglify-js": "^2.8.13",
    "watchify": "^3.9.0"
  }
}