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

    File Name: stacked-to-grouped.js

    Description: D3 stacked to grouped chart

    ----------------------------------------------------------------------------------------

    Item Name: Modern Admin - Clean Bootstrap 4 Dashboard HTML Template

    Author: PIXINVENT

    Author URL: http://www.themeforest.net/user/pixinvent

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



// Stacked to grouped chart

// ------------------------------

$(window).on("load", function(){



    var ele = d3.select("#stacked-to-grouped"),

    margin = {top: 20, right: 20, bottom: 30, left: 50},

    width = ele.node().getBoundingClientRect().width - margin.left - margin.right,

    height = 500 - margin.top - margin.bottom;



    var n = 4, // number of layers

        m = 58, // number of samples per layer

        stack = d3.layout.stack(),

        layers = stack(d3.range(n).map(function() { return bumpLayer(m, .1); })),

        yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }),

        yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });





    // Initialize Scales

    // ------------------------------



    var x = d3.scale.ordinal()

        .domain(d3.range(m))

        .rangeRoundBands([0, width], .08);



    var y = d3.scale.linear()

        .domain([0, yStackMax])

        .range([height, 0]);



    // Initialize Colors

    // ------------------------------

    var color = d3.scale.linear()

        .domain([0, n - 1])

        .range(["#FECEA8", "#E84A5F"]);



    // Initialize Axis

    // ------------------------------

    var xAxis = d3.svg.axis()

        .scale(x)

        .tickSize(0)

        .tickPadding(6)

        .orient("bottom");



    // Chart

    var container = ele.append("svg");



    var svg = container

        .attr("width", width + margin.left + margin.right)

        .attr("height", height + margin.top + margin.bottom)

      .append("g")

        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");





    var layer = svg.selectAll(".layer")

        .data(layers)

    .enter().append("g")

        .attr("class", "layer")

        .style("fill", function(d, i) { return color(i); });



    var rect = layer.selectAll(".d3-bar")

        .data(function(d) { return d; })

    .enter().append("rect")

        .attr("class", "d3-bar")

        .attr("x", function(d) { return x(d.x); })

        .attr("y", height)

        .attr("width", x.rangeBand())

        .attr("height", 0);



    rect.transition()

        .delay(function(d, i) { return i * 10; })

        .attr("y", function(d) { return y(d.y0 + d.y); })

        .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); });



    svg.append("g")

        .attr("class", "d3-axis d3-xaxis")

        .attr("transform", "translate(0," + height + ")")

        .call(xAxis);



    d3.selectAll("input").on("change", change);



    var timeout = setTimeout(function() {

        d3.select("input[value=\"grouped\"]").property("checked", true).each(change);

    }, 2000);



    function change() {

        clearTimeout(timeout);

        if (this.value === "grouped") transitionGrouped();

        else transitionStacked();

    }



    function transitionGrouped() {

        y.domain([0, yGroupMax]);



        rect.transition()

            .duration(500)

            .delay(function(d, i) { return i * 10; })

            .attr("x", function(d, i, j) { return x(d.x) + x.rangeBand() / n * j; })

            .attr("width", x.rangeBand() / n)

        .transition()

            .attr("y", function(d) { return y(d.y); })

            .attr("height", function(d) { return height - y(d.y); });

    }



    function transitionStacked() {

        y.domain([0, yStackMax]);



        rect.transition()

            .duration(500)

            .delay(function(d, i) { return i * 10; })

            .attr("y", function(d) { return y(d.y0 + d.y); })

            .attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })

        .transition()

            .attr("x", function(d) { return x(d.x); })

            .attr("width", x.rangeBand());

    }



    // Inspired by Lee Byron's test data generator.

    function bumpLayer(n, o) {



        function bump(a) {

            var x = 1 / (.1 + Math.random()),

                y = 2 * Math.random() - .5,

                z = 10 / (.1 + Math.random());

            for (var i = 0; i < n; i++) {

                var w = (i / n - y) * z;

                a[i] += x * Math.exp(-w * w);

            }

        }



        var a = [], i;

        for (i = 0; i < n; ++i) a[i] = o + o * Math.random();

        for (i = 0; i < 5; ++i) bump(a);

        return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });

    }



    // Resize chart

    // ------------------------------



    // Call function on window resize

    $(window).on('resize', resize);



    // Call function on sidebar width change

    $('.menu-toggle').on('click', resize);



    // Resize function

    // ------------------------------

    function resize() {



        width = ele.node().getBoundingClientRect().width - margin.left - margin.right;



        // Main svg width

        container.attr("width", width + margin.left + margin.right);



        // Width of appended group

        svg.attr("width", width + margin.left + margin.right);





        // Axis

        // -------------------------

        x.rangeRoundBands([0, width], .08);

        svg.selectAll('.d3-xaxis').call(xAxis);





        svg.selectAll('.d3-bar').attr("x", function(d) { return x(d.x); });

    }

});