Skip to content

Instantly share code, notes, and snippets.

@erikhazzard
Created May 2, 2013 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erikhazzard/5504818 to your computer and use it in GitHub Desktop.
Save erikhazzard/5504818 to your computer and use it in GitHub Desktop.
stacked bars updating with set width
{"description":"stacked bars updating with set width","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"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}
//---------------------------------------
//Some config vars
//---------------------------------------
var DURATION = 1500;
var width = 890,
height = 460;
//---------------------------------------
//Setup svg
//---------------------------------------
var svg = d3.select('svg')
.attr('width', width)
.attr('height', height)
.append('g');
//---------------------------------------
//setup total bar width / height scale
//---------------------------------------
var totalXScale = d3.scale.linear()
.domain([0, 1000])
.rangeRound([0,width]);
var totalYScale = d3.scale.linear()
.domain([0, 1000])
.rangeRound([0, height - 10])
.clamp(true);
//---------------------------------------
//Setup stack objects
//---------------------------------------
var stackObject1 = {
group: svg.append('svg:g').attr({
'class': 'group1'
}),
yIndex: 0,
//Position / size properties
//height
height: 400,
getHeight: function(){
return totalYScale(this.height);
},
getY: function(){
return 0;
},
//width
width: 400,
getWidth: function(){
return totalXScale(this.width);
},
getX: function(){
return 0;
}
};
var stackObject2 = {
group: svg.append('svg:g').attr({
'class': 'group2',
transform: 'translate(0, 205)'
}),
yIndex: 1,
//Position / size properties
//height
height: 600,
getHeight: function(){
return totalYScale(this.height);
},
getY: function(){
console.log('______', stackObject1.getHeight() + 5);
return stackObject1.getHeight() + 5;
},
//width
width: 600,
getWidth: function(){
return totalXScale(this.width);
},
getX: function(){
return 0;
}
};
//=======================================
//
//Update / Draw stacked bar
//
//=======================================
function update(stackObject, data) {
//Draws or updates the stacked bars
// parameters:
// stackObject: {Object} containing properties of the stack bar
// data: {Object} data for the stacked bar
//setup scales
var yScale = d3.scale.linear()
.rangeRound([stackObject.getWidth(), 0]);
var color = d3.scale.category20c();
var stackGroup = stackObject.group;
//set color domain
color.domain(d3.keys(data[0]));
//Setup stacked data
data.forEach(function(d) {
var y0 = 0;
d.policies = color.domain().map(function(name) {
return {
name: name,
y0: y0,
y1: y0 += +d[name]
};
});
d.total = d.policies[d.policies.length - 1].y1;
});
data.sort(function(a, b) { return b.total - a.total; });
//Setup scale domains
yScale.domain([0, d3.max(data, function(d) { return d.total; })]);
//get height of the bars (based on spending - taxes)
var barHeight = stackObject.getHeight();
//update y position of group
stackObject.group.transition().duration(DURATION).attr({
transform: 'translate(' + [
0, stackObject.getY()
] + ')'
});
// DATA JOIN
// Join new data with old elements, if any.
var policy = stackGroup.selectAll('.policy')
.data(data[0].policies);
//flip it
//stackGroup.attr({ transform: 'translate(' + [width, 0] + ') scale(-1 1)' });
//enter
policy.enter().append('rect').attr({
'class': 'policy',
'y': 0,
'height': barHeight
}).style({
opacity: 1
}).on('mouseover', function(d,i){
d3.select(this).style({
fill: '#336699'
});
console.log(d, i);
}).on('mouseout', function(d,i){
d3.select(this).style({
fill: color(d.name)
});
});
//update
policy.style({
opacity: 1,
'fill': function(d,i) { return color(d.name); }
})
.transition()
.duration(DURATION)
.attr({
'height': barHeight,
'x': function(d) { return yScale(d.y1); },
'width': function(d) { return yScale(d.y0) - yScale(d.y1); }
});
//EXIT
policy.exit()
.transition()
.duration(DURATION)
.attr({
'height': 0,
'width': function(d) {
return 0;
},
'x': function(d) {
return 0;
}
}).style({
opacity: 0.1
})
.remove();
}
// The initial display.
update(stackObject1,
[{
a: 310504,
b: 552339,
d: 259034,
e: 450818,
f: 1231572,
g: 1215966
}]
);
update(stackObject2,
[{
a: 310504,
b: 552339,
d: 259034,
e: 450818,
f: 1231572,
g: 1215966
}]
);
//Draw and update two bars
setInterval(function(){
var data = [{}];
var alphabet = 'abcdefghijklmnopqrstuvwxyz';
var num = 1000 - Math.random() * 1000 | 0;
stackObject1.height = num;
stackObject2.height = (1000 - num);
for(i=0; i < Math.random() * 26 | 0;i++){
data[0][alphabet[i]] = Math.random() * 1000 | 0;
}
update(
stackObject2,
_.clone(data)
);
data = [{}];
alphabet = 'abcdefghijklmnopqrstuvwxyz';
for(i=0; i < Math.random() * 26 | 0;i++){
data[0][alphabet[i]] = Math.random() * 1000 | 0;
}
update(
stackObject1,
_.clone(data)
);
}, DURATION + 300);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment