JSFiddle - React, Tailwind, and code Playground

by jlaw

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<div id="test"></div>

CSS

#test rect.actual {
    fill: orange;
    stroke: #666666;
}
#test rect.projected {
    fill: url(#locked2);
    stroke: #666666;
}

Babel + JSX

class LayeredBarChart {
    constructor(selection) {
        // grab the selection and default a usable selection
        selection = selection || d3.select('body');
        
        // create the svg
        this.selection = selection.append("svg");

        // initialize bar chart
        this.yScale = d3.scale.linear().domain([0, 100]);
        this.xScale = d3.scale.ordinal();
        this.rects = this.selection.selectAll('g');
        this.selection.append("defs")
         .append('pattern')
         .attr('id', 'locked2')
         .attr('patternUnits', 'userSpaceOnUse')
         .attr('width', 8)
         .attr('height', 8)
         .append("image")
         .attr("xlink:href", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAPklEQVQYV43M2QkAIAwEUdPsFrXNKhEUj1zz/RhphQB0yZwikhLChXTmwhO58EUmtNAHPXTBCG2YoQkrSOEAMjYmPDpsXTEAAAAASUVORK5CYII=")
         .attr('width', 8)
         .attr('height', 8);

    }

    height(value) {
        if (arguments.length === 1) {
            this._height = value;
            this.yScale.range([0, value]);
            this.selection.attr("height", value);
            return this;
        }
        return this._height;
    }

    width(value) {
        if (arguments.length === 1) {
            this._width = value;
            this.selection.attr("width", value);
            return this;
        }
        return this._width;
    }
    
    barSpacing(value) {
        if (arguments.length === 1) {
            this._barSpacing = value;
            return this;
        }
        return this._barSpacing;
    }

    render(data) {
		// create the xScale with the domain mapped from the data
        // and the range bounds set to the width with a spacing
        // provided by the getter/setter
        this.xScale.domain(data.map(item => item.groupLabel))
    		.rangeRoundBands([0, this.width()], this.barSpacing());
		
        // create the bars with the data
        var bars = this.rects.data(data)
           ...