D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
KevinRourke
Full window
Github gist
progressBarManager
Built with
blockbuilder.org
<!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>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js