Skip to content

Instantly share code, notes, and snippets.

@KevinRourke
Last active March 15, 2016 02:47
Show Gist options
  • Save KevinRourke/4da2516ba68940554c8c to your computer and use it in GitHub Desktop.
Save KevinRourke/4da2516ba68940554c8c to your computer and use it in GitHub Desktop.
progressBarManager
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<style>
progress-statement: {
}
</style>
</head>
<body>
<div id="chart" style="width:200px"></div>
<div id="pos"></div>
<script>
function responsivefy(svg) {
// get container + svg aspect ratio
var container = d3.select(svg.node().parentNode),
width = parseInt(svg.style("width")),
height = parseInt(svg.style("height")),
aspect = width / height;
// add viewBox and preserveAspectRatio properties,
// and call resize so that svg resizes on inital page load
svg.attr("viewBox", "0 0 " + width + " " + height)
.attr("perserveAspectRatio", "xMinYMid")
.call(resize);
// to register multiple listeners for same event type,
// you need to add namespace, i.e., 'click.foo'
// necessary if you call invoke this function for multiple svgs
// api docs: https://github.com/mbostock/d3/wiki/Selections#on
d3.select(window).on("resize." + container.attr("id"), resize);
// get width of container and resize svg to fit it
function resize() {
var targetWidth = parseInt(container.style("width"));
if (isNaN(targetWidth) ) targetWidth = 1;
svg.attr("width", targetWidth);
svg.attr("height", Math.round(targetWidth / aspect));
}
};
fadD3={};
fadD3.progressBarManager = function module() {
var _height = ".18em",
_svgHeight = "20px"
_ease = "bounce",
_barFontSize = "1.2em",
_barColorPosVal = "#fff",
_barColorNegVal = "rgb(255,91,87)",
_bkgrdColor = "#999",
_bkgOpacity = .33,
_statementY = 20,
_statementSize = "2.90em",
_barOpacity = 1,
_durationMs = 2500,
_textColor = "#fff";
var _better = "Better than prior month",
_worse = "Worse than prior month",
_infinity = "Unable to calculate diff.";
var _currentValue = 0;
var xScale,
elWidth,
percent,
barColor,
statement,
statementAnchor,
svg,
pre,
anchor,
xPos;
var dispatch = d3.dispatch("customHover", "barChartReady");
function exports(_selection) {
elWidth=_selection[0][0].clientWidth;
//if(elWidth === Infinity) elWidth = 0; //no comparison data
xScale = d3.scale.linear().domain([ 0, 100 ]).range([0, elWidth]);
_selection.each(function(_data) {
if (_data[0] === Infinity) _data[0] = 0;
/* --- clean date from str to number; convet neg to abs; evaluate pos/neg --- */
percent = parseInt( _data[0]);
//console.log(xScale(_data[0]) );
if( percent < 0) {
barColor = _barColorNegVal;
pre = "-";
statement = _worse;
_data[0] = Math.abs(_data[0]);
} else if (percent === 0) {
barColor = _barColorPosVal;
pre = "";
_data[0] = percent;
statement = _infinity;
} else if (percent > 0){
barColor = _barColorPosVal;
pre = "";
_data[0] = percent;
statement = _better;
}
if (!svg) {
svg = _selection.append("svg")
.classed("svg-chart", true)
.attr({
width :'100%',
height : _svgHeight
})
.call(responsivefy);
};
bkg = svg.append("g")
.attr("class" , "bkg")
.append("rect")
.attr({
"width" : elWidth,
"height" : _height,
"fill" : _bkgrdColor,
"opacity" : _bkgOpacity
});
statement_elm = svg.append("g")
.classed("progress-statement" , true)
.append("text")
.attr({
x : elWidth/2,
y : _statementY
})
.style({
"text-anchor": "middle",
"font-size" : _statementSize,
"font-weight" : "300",
"fill" : _textColor,
"text-anchor" : "middle",
"opacity" : 0
})
.text(statement)
.transition().delay(_durationMs).duration(800).style("opacity", 1);
update(_data);
function update(_data) {
bar = svg.selectAll("g.bar")
.data(_data)
.enter()
.append("g")
.classed("bar" , true);
bar.append("rect")
.attr({
"x": function(d){return percent <0?elWidth:0},
})
.attr({
"width" : function(d) {return percent <0? xScale(d):0},
"height" : _height,
"fill" : barColor,
"opacity": _barOpacity
})
.transition().duration(_durationMs)
.attr("x", function(d){return percent <0? elWidth-xScale(d) : 0} )
.attr("width", function(d){return percent <0? xScale(d) : xScale(d)} );
//percentage display
txt = svg.selectAll("g.txt")
.data(_data)
.enter()
.append("g")
.attr("class" , "txt");
txt.append("text")
.classed("percent-text", true)
.attr({
x : function(d){ return percent <0? elWidth+15 : -10; },
y : 23
})
.style({
"font-size" : _barFontSize,
"text-anchor" : "middle",
"fill" : _textColor
})
.text(function(d){ return (d) })
.transition()
.duration(_durationMs)
.attr("x", function(d){return percent <0?
_setNegPos(d) : _setPosPos(d)}
)
.tween("text",labelTween);
}//update
}); //_selection.each
//Dispatch
dispatch.barChartReady();
}//exports
function _setNegPos(d){
if (percent <= -93) {
return elWidth - xScale(d)+25;
}else {
return elWidth - xScale(d);
};
};
function _setPosPos(d){
//console.log(xScale(d));
if (xScale(d) < 12) {
return 13;
}else if (xScale(d) >= elWidth-15){
return elWidth-20;
}else {
return xScale(d);
};
};
function labelTween(a) {
var i = d3.interpolate(_currentValue, a);
_currentValue = i(0);
return function(t) {
_currentValue = i(t);
this.textContent = pre + Math.round(i(t)) + "%";
}
}
exports.height = function(_x) {
if (!arguments.length) return _height;
_height = _x;
return this;
};
exports.svgHeight = function(_x) {
if (!arguments.length) return _svgHeight;
_svgHeight = _x;
return this;
};
exports.barColorPosVal = function(_x) {
if (!arguments.length) return _barColorPosVal;
_barColorPosVal = _x;
return this;
};
exports.statementY = function(_x) {
if (!arguments.length) return _statementY;
_statementY = parseInt(_x);
return this;
};
exports.statementSize = function(_x) {
if (!arguments.length) return _statementSize;
_statementSize = _x;
// ".90em"
return this;
};
exports.barColorNegVal = function(_x) {
if (!arguments.length) return _barColorNegVal;
_barColorNegVal = _x;
return this;
};
exports.bkgrdColor = function(_x) {
if (!arguments.length) return _bkgrdColor;
_bkgrdColor = _x;
return this;
};
exports.bkgOpacity = function(_x) {
if (!arguments.length) return _bkgOpacity;
_bkgOpacity = _x;
return this;
};
exports.textColor = function(_x) {
if (!arguments.length) return _textColor;
_textColor = _x;
return this;
};
exports.barFontSize = function(_x) {
if (!arguments.length) return _barFontSize;
_barFontSize = _x;
return this;
//'1em'
};
exports.durationMs = function(_x) {
if (!arguments.length) return _durationMs;
_durationMs = parseInt(_x);
return this;
};
exports.ease = function(_x) {
if (!arguments.length) return _ease;
_ease = _x;
return this;
};
// exports.negValue = function(_x) {
// if (!arguments.length) return _negValue;
// _negValue = _x;
// return this;
// };
d3.rebind(exports, dispatch, "on");
return exports;
};//progressBarManager
var APP = {
answersProgress: fadD3.progressBarManager()
.barColorPosVal("#b3a945")
.svgHeight("44")
.height(".40em")
.bkgrdColor("#999")
.barColorNegVal("#b3454f")
.textColor("#3e434e")
.statementY(40)
.statementSize("1em")
.durationMs(3000),
};
d3.select("#chart")
.datum([-93])
.call(APP.answersProgress);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment