Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="KotoJS Example">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>KotoBarChart</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://npmcdn.com/koto@0.1.6/dist/koto.js"></script>
</head>
<body>
<svg width="100%" height="100%" viewBox="0 0 800 500">
  <g id="chart"></g>
</svg>
</body>
</html>
 
var KotoBarChart = Koto.extend({
  initialize: function() {
    // Setup
    var chart = this;
    // define configs
    this.configs = {
      height: {
        name: 'height',
        description: 'The height of the chart.',
        value: 500,
        type: 'number',
        units: 'px',
        category: 'Size',
        getter: function() {
          // get value
          return this.value;
        },
        setter: function(newValue) {
          // Set value
          return newValue;
        }
      },
      width: {
        name: 'width',
        description: 'The widthj of the chart.',
        value: 800,
        units: 'px',
        type: 'number',
        category: 'Size'
      }
    };
    // Scales
    this.x = d3.scale.linear()
      .range([0, this.config('width')]);
    this.y = d3.scale.linear()
      .domain([0, 100])
      .rangeRound([0, this.config('height')]);
    // add a layer
    this.layer('bars', this.base.append('g'), {
        // destructuring ftw
        dataBind(data) {
          return this.selectAll('rect')
            .data(data, d => d.time);
        },
        insert() {
          return this.append('rect');
        }
      })
      // lifecycle events (Arrow function syntax)
      .on('enter', function() {
        var length = chart._length = this.data().length;
        this.attr('x', function(d, i) {
            return chart.x(i + 1) - 0.5;
          })
          .attr('y', function(d) {
            return chart.config('height') - chart.y(d.value) - 0.5;
          })
          .attr('width', chart.config('width') / length)
          .style('fill', 'steelBlue')
          .attr('height', function(d) {
            return chart.y(d.value);
          });
      })
      .on('merge:transition', function() {
        this.duration(1000)
          .attr('x', function(d, i) {
            return chart.x(i) - 0.5;
          });
      })
      .on('exit:transition', function() {
        this.duration(1000)
          .attr('x', function(d, i) {
            return chart.x(i - 1) - 0.5;
          })
          .remove();
      });
    // add another layer 
    this.layer('labels', this.base.append('g'), {
        dataBind(data) {
          return this.selectAll('text')
            .data(data, d => d.time);
        },
        insert() {
          return this.append('text');
        }
      })
      // non arrow function syntax
      .on('enter', function() {
        var length = this.data().length;
        this
          .attr('x', function(d, i) {
            return chart.x(i + 1) + ((chart.config('width') / length) / 2);
          })
          .attr('y', function(d) {
            return chart.config('height') - chart.y(d.value) - 15;
          })
          .style('fill', 'steelBlue')
          .style('text-anchor', 'middle')
          .text(function(d) {
            return d.value;
          });
      })
      .on('merge:transition', function() {
        this.duration(1000)
          .attr('x', function(d, i) {
            return chart.x(i) + ((chart.config('width') / chart._length) / 2);
          });
      })
      .on('exit:transition', function() {
        this.duration(1000)
          .attr('x', function(d, i) {
            return chart.x(i - 1) - 0.5;
          })
          .remove();
      });
  },
  //override methods
  preDraw: function(data) {
    this.x.domain([0, data.length]);
  }
});
// datasrc.js
// A simple data source to feed the bar chart visualization. Based on the
// implementation in "A Bar Chart, part 2":
// http://mbostock.github.com/d3/tutorial/bar-2.html
(function(global) {
  "use strict";
  var DataSrc = global.DataSrc = function() {
    var self = this;
    this.time = 1297110663; // start time (seconds since epoch)
    this.value = 70;
    this.data = d3.range(33).map(function() {
      return self.next();
    });
  };
  DataSrc.prototype.next = function() {
    this.time += 1;
    this.value = ~~Math.max(10, Math.min(90, this.value + 10 * (Math.random() - .5)));
    return {
      time: this.time,
      value: this.value
    };
  };
  DataSrc.prototype.fetch = function() {
    this.data.shift();
    this.data.push(this.next());
  };
}(window));
var dataSrc = new DataSrc();
var barChart = new KotoBarChart(d3.select('#chart'));
barChart.draw(dataSrc.data);
setInterval(function() {
  dataSrc.fetch();
  barChart.draw(dataSrc.data);
}, 1500);
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
nicksrandallpro
0viewers