D3 Charts Composable

by jacobwsmith

HTML

<script src="http://misoproject.com/js/jquery.min.js"></script>
<script src="//misoproject.com/js/d3/d3.v3.min.js"></script>
<script src="http://misoproject.com/js/d3.chart.js"></script>
<h3>Circle Chart</h3>

<div id="vis1" class="chart"></div>

<h3>Label Chart</h3>

<div id="vis2" class="chart"></div>

<h3>Circle + Label Chart</h3>

<div id="vis3" class="chart"></div>

CSS

.chart {
    width: 200px;
    height: 200px;
    border: 1px solid #ccc;
}

JavaScript

// ==============================
// d3.Chart
// http://www.youtube.com/watch?v=TYgSc_S0lCw&list=SP055Epbe6d5avZGXwE5u039VQq_oQFgrc&index=2
// - Repeatable
// - Configuable
// - Extensible
// - Composable
// ==============================

// ==============================
// The test data
// ==============================
var data = [1, 3, 4, 6, 10];

// ==============================
// Chart Templates
// - Circle Chart
// - Label Chart
// - Circle + Label
// ==============================
d3.chart('CircleChart', {
    initialize: function () {
        this.layer('circles', this.base.append('g'), {
            dataBind: function () {
                return this.selectAll('circle').data(data);
            },
            insert: function () {
                return this.append('circle');
            },
            events: {
                enter: function () {
                    return this.attr('cy', 100)
                        .attr('cx', function (d) {
                        return d * 10;
                    })
                        .attr('r', 5)
                        .style('fill', this.chart().fill());
                }
            }
        });
    },
    fill: function (newFill) {
        if (arguments.length === 0) {
            return this._fill;
        }
        this._fill = newFill;
        return this;
    }
});
d3.chart('LabelsChart', {
    initialize: function () {
        this.layer('labels', this.base.append('g'), {
            dataBind: function () {
                return this.selectAll('text').data(data);
            },
            insert: function () {
                return this.append('text');
            },
            events: {
                enter: function () {
                    return this.attr('x', function (d) {
                        return d * 10;
                    })
                        .attr('y', 80)
                        .style('text-anchor', 'middle')
                        .style('fill', 'black')
         ...