Horizontal Stacked Bar Chart for D3.js

by Igor Iris

HTML

<div id="linearGaugeContainer"></div>
<!--define svg gradients to be used in java script. make sure the svg tag takes no room on your page=> width and height = 0px-->
<svg xmlns="http://www.w3.org/2000/svg" style="height:0px;width:0px">
    <defs>
        <linearGradient id="NORMAL_COLOR" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
            <stop offset="0%" stop-color="#C1DC99" stop-opacity="1" />
            <stop offset="100%" stop-color="#669900" stop-opacity="1" />
        </linearGradient>
        <linearGradient id="WARNING_COLOR" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
            <stop offset="0%" stop-color="#84C6F6" stop-opacity="1" />
            <stop offset="100%" stop-color="#6FA7CF" stop-opacity="1" />
        </linearGradient>
        <linearGradient id="MINOR_COLOR" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
            <stop offset="0%" stop-color="#FFE537" stop-opacity="1" />
            <stop offset="100%" stop-color="#F9C328" stop-opacity="1" />
        </linearGradient>
        <linearGradient id="MAJOR_COLOR" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
            <stop offset="0%" stop-color="#FF9900" stop-opacity="1" />
            <stop offset="100%" stop-color="#FF6700" stop-opacity="1" />
        </linearGradient>
        <linearGradient id="CRITICAL_COLOR" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
            <stop offset="0%" stop-color="#E70030" stop-opacity="1" />
            <stop offset="100%" stop-color="#B30020" stop-opacity="1" />
        </linearGradient>
    </defs>
</svg>

JavaScript

//Linear gauge
//The way to implement it would be: 
// - To take a stacked bar graph as a basis
// - Ignore all the graph related attributes (like: axis, ticks and so on)
// - Define a single set of data 
// - Swap the x and y axis values
var margins = {
    top: 12,
    left: 48,
    right: 24,
    bottom: 24
},
width = 700 - margins.left - margins.right
    height = 15,
    dataset = [{
        data: [{
            barId: '1', // we assign some random value, the most important to keep it same for all the entries 
            percent: 0.1, // percentage that we want a specific value to occupy as a part of the gauge: values betwee 0-1
            severity: 'NORMAL_COLOR'// color id that we'll used to reference gradient value
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.4,
            severity: 'WARNING_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.22,
            severity: 'MINOR_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.2,
            severity: 'MAJOR_COLOR'
        }]
    }, {
        data: [{
            barId: '1',
            percent: 0.08,
            severity: 'CRITICAL_COLOR'
        }]
    }],
    dataset = dataset.map(function (d) {
        return d.data.map(function (o, i) {
            // Structure it so that your numeric
            // axis (the stacked amount) is y
            return {
                y: o.percent,
                x: o.barId,
                severity:o.severity
            };
        });
    }),
    stack = d3.layout.stack();

stack(dataset);

var dataset = dataset.map(function (group) {
    return group.map(function (d) {
        // Invert the x and y values, and y0 becomes x0
        return {
            x: d.y,
            y: d.x,
            x0: d.y0,
            severity:d.severity
            
        };
    });
}),
    svg = d3.select('#linearGaugeContainer')
        .append('svg')
       ...