Stacked and grouped bar chart

Uses d3.layout.stack, d3.scale, computes (x, y, w, h), single column for now, data transform

HTML

<script src="http://mbostock.github.com/d3/d3.js"></script>

CSS

rect{
    fill:skyblue;
    stroke:blue;
}

JavaScript

var cVariant = ["stack", "group"];
var variant = 0; // Change the chart type here (0, 1)
var offsetVariants = ["zero", "expand", "silhouette", "wiggle"];
var offset = 0; // Change the stacked bar chart offset type here (0-3)

var data = [[1, 2, 3, 0.4],[5, 6, 7, 8],[9, 10, 11, 12]],
chartW = 300,
chartH = 200,
margin = [10, 10, 10, 10],
gap = 20;

var dataForStack = data.map(function(d, i){return d.map(function(d2, i2){return {x: i2, y: d2};});});
var stackedData = d3.layout.stack().offset(offsetVariants[offset])(dataForStack);
var stackedDataTransposed = d3.transpose(stackedData);

var maxForStack = d3.max(stackedDataTransposed.map(function(d, i){
    return d3.sum(d.map(function(d, i){return d.y;}));
}));
var maxForGroup = d3.max(d3.merge(stackedDataTransposed).map(function(d, i){return d.y;}));
var max = (chartVariant[variant] == "stack")?maxForStack:maxForGroup;
var scaleY = d3.scale.linear().domain([0, max]).range([0,chartH]);
var scaleX = d3.scale.ordinal().domain(d3.range(stackedDataTransposed.length)).rangeBands([0, chartW]);

var groupData = computeBarchart(chartW, chartH, margin, gap, scaleY, scaleX);
var stackData = computeStackedBarchart(chartW, chartH, margin, gap, scaleY, scaleX);
var barChart = (chartVariant[variant] == "stack")?stackData:groupData;

var groups = d3.select("body")
.append("svg")
.attr("width", chartW+20)
.attr("height", chartH+20)
.selectAll("g")
.data(d3.transpose(stackedData))
.enter().append("g")
.attr("transform", function(d, i){return "translate("+(i*scaleX.rangeBand()+margin[3])+","+margin[0]+")";});
groups.selectAll("rect")
    .data(function(d){return d;})
    .enter().append("rect")
    .attr("width", barChart.w)
    .attr("height", barChart.h)
    .attr("x", barChart.x)
    .attr("y", barChart.y);

/*===========================================================*/

function computeStackedBarchart(chartW, chartH, margin, gap, scaleY, scaleX){
    var gapW = scaleX.rangeBand()*(gap/100);

    var markX = function(d, i){return...