Skip to content

Instantly share code, notes, and snippets.

@emepyc
Created November 29, 2012 16:43
Show Gist options
  • Save emepyc/4170253 to your computer and use it in GitHub Desktop.
Save emepyc/4170253 to your computer and use it in GitHub Desktop.
Horizontal bar charts with update
{"description":"Horizontal bar charts with update","endpoint":"","display":"svg","public":true,"require":[],"tab":"edit","display_percent":0.7,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01}
var data1 = [
{total_job_counts : 8,
job_counts : [2,3,2,1],
logic_name : "analysis1"},
{total_job_counts : 6,
job_counts : [2,1,1,2],
logic_name : "analysis2"},
{total_job_counts : 12,
job_counts : [1,1,2,8],
logic_name : "analysis3"},
{total_job_counts : 4,
job_counts : [1,1,1,1],
logic_name : "analysis4"}
];
var barsmargin = 80;
var countmargin = 80;
var n = 4;
var m = 4;
var stack = d3.layout.stack();
var data = transformData(data1);
//var data = d3.range(n).map(function() { return bumpLayer(m, .1); });
var layers = stack(data);
var svg = initialize_overview(layers);
live_overview(svg, layers);
//setInterval(function() {
// live_overview(svg, stack(d3.range(n).map(function() { return bumpLayer(m, .1); })));
//live_overview(svg, stack(transformData(data2)));
//}, 4500);
function transformData(data) {
    var transfData = [];
    for (var i=0; i<data[0].job_counts.length; i++) {
       transfData[i] = [];   
    }
    for (var i=0; i<data.length; i++) {
        for (var j=0; j<data[0].job_counts.length; j++) {
            transfData[j].push({x:i, y:data[i].job_counts[j]})
        }
    }
    console.log(transfData);
    return transfData;
}
function new_scale(svg, layers) {
    var yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });
    console.log("MAXY: " + yStackMax);    
    var width = d3.select("svg").attr("width");
    
    var y = d3.scale.linear()
          .domain([0, yStackMax])
          .range([0,width-barsmargin-countmargin]);
    return y;
}
function initialize_overview(layers) {
    var margin = {top: 10, right: 10, bottom: 10, left: 10},
        width = 460 - margin.left - margin.right,
        height = 200 - margin.top - margin.bottom;
    var fontsize = 16;
    x = d3.scale.ordinal()
                    .domain(d3.range(m))
                    .rangeRoundBands([0, height], .08);
var svg = d3.select("svg")
                  .attr("width", width + margin.left + margin.right)
                  .attr("height", height + margin.top + margin.bottom)
                  .attr("class", "chart")
                .append("g")
                  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    var color = d3.scale.linear()
                  .domain([0, n - 1])
                  .range(["#aad", "#556"]);
    var gLayer = svg.selectAll(".layer")
                   .data(layers)
                   .enter().append("svg:g")
                   .attr("class", "layer")
                   .style("fill", function(d, i) { return color(i) })
        
    var gRects = gLayer.selectAll("g")
        .data(function(d) {return d})
        .enter().append("g")
        .attr("x", barsmargin)
        .attr("y", function(d) { return x(d.x) })
        .attr("class", function(d,i){return "analysis" + (i+1)})
        .classed("bar", true)
        //.attr("class", "bar")
//        .each(function(d,i){this._type = "stacked"});
        
    gRects.append("svg:rect")
        .attr("x", barsmargin)
        .attr("y", function(d) {return x(d.x)})
        .attr("height", x.rangeBand())
        .attr("width", 20)
        .each(function(d,i){this._type = "stacked"});
        
    gRects.append("svg:text")          
        // "this" is still the layers
        .attr("x", barsmargin)
        .attr("y", function(d,i) {return x(d.x)})
        .attr("font-size", 10)
        .attr("fill", "red")
        .text(0)
        .each(function(d,i){this._type = "stacked"});
         
    svg.selectAll(".counts_label")
        .data(layers)
        .enter().append("svg:g")
        .attr("class", "gcounts_label")
        .append("svg:text")
        .attr("class", "counts_label")
        .attr("x", function(d,i){var l=layers.slice(-1)[0][i]; return(barsmargin + 10)}) // l is not used!
        .attr("y", function(d,i){return (x(i) + x.rangeBand()/2+fontsize/2)})
        .attr("fill", "black")
        .attr("font-size", fontsize)
        .text("0")
                                                                            
    svg.selectAll(".analysis_label")
                    .data(layers)
                    .enter().append("svg:g")
                    .each(function(){this._type = "stacked"})
                    .attr("class", "analysis_label")
                    .attr("to_id", function(d,i){return data1[i].logic_name})
                    .append("svg:text")
                    .attr("x", 0)
                    .attr("y", function(d, i) {return (x(i) + x.rangeBand()/2 + fontsize/2)})
                    .attr("fill", "black")
                    .attr("font-size", fontsize)
                    .text(function(d,i){return data1[i].logic_name})
    d3.selectAll(".analysis_label").on("click", function(){
    console.log(d3.select(this).attr("to_id"));
      d3.selectAll("." + d3.select(this).attr("to_id")) // these are g with rects
        //  .each(function() {$(this).children("rect")[0]._type="grouped"})
          .each(function(d,i) { if($(this).children("rect")[0]._type=="grouped"){   
               $(this).children("rect")[0]._type="stacked";
               $(this).children("text")[0]._type="stacked";
             } else {
               $(this).children("rect")[0]._type="grouped";
               $(this).children("text")[0]._type="grouped";
             }
             $(this).children("rect")[0]._column=i;
             $(this).children("text")[0]._column=i })
          .call(redrawBars, 300, 10)
            });              
    return svg;
}
function redrawBars(bar, time, delay) {
    var rect = bar.selectAll("rect")
    rect
        .transition()
        .delay(function(d,i) {return i*delay})
        .duration(time)
            .attr("x",function(d) {if (this._type == "stacked") {console.log("STACKED"); return barsmargin+y(d.y0)} else {console.log("ON_BASE"); return barsmargin}})
            .attr("y",function(d,i) {if (this._type == "stacked") {return x(d.x)} else {return (x(d.x)+this._column*x.rangeBand()/4)}})
            .attr("width", function(d) {return y(d.y)})
            .attr("height", function() {if (this._type == "stacked") {return x.rangeBand()} else {return x.rangeBand()/4}})
    var counts_labels = bar.selectAll("text")
    counts_labels
        .transition()
        .delay(function(d,i) {return i*delay})
        .duration(time)
            .attr("x", function(d) {if (this._type == "stacked") {return barsmargin+y(d.y0+d.y)} else {return barsmargin+y(d.y)}})
            .attr("y", function(d,i) {if (this._type == "stacked") {return x(d.x)} else {return (x(d.x)+this._column*x.rangeBand()/4+x.rangeBand()/8+5)}}) // the last 5 is because fontsize is 10
            .text(function(d){return (d.y)})
}
function live_overview(svg, layers) {
//    y.domain([0, yStackMax]);
    y = new_scale(svg, layers);
    var layer = svg.selectAll(".layer")
                   .data(layers);
    var rect = layer.selectAll("rect")
        .data(function(d) {return d})
            console.log(rect);
    var text = layer.selectAll("text")
        .data(function(d) {return d})
            console.log(text);
   layer.selectAll(".bar").call(redrawBars, 1000, 300)
  svg.selectAll(".counts_label")
       .data(layers)
       .transition()
        .delay(function(d,i){return i*300})
       .duration(1000)
       .attr("x", function(d,i){var l=layers.slice(-1)[0][i]; return(y(l.y0+l.y) + barsmargin + 10)})
       .text(function(d,i){var l=layers.slice(-1)[0][i]; return (l.y0 + l.y)})
}
function getRandomData() {
var data = [];
for (var i=0; i<4; i++) {
data[i] = Math.floor(Math.random()*20);
}
return(data);
}
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)}; });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment