In case anyone ever needs this, I came up with my own solution. It
looks like this:
function render_waterfall_plot (shrinkage) {
var data = [],
range = [],
data1 = [],
data2 = [],
data3 = [];
// Sort data numerically (ascending)
data = shrinkage.sort(function sortfunction(a, b){
return (b - a) //causes an array to be sorted numerically and
ascending
});
// Get the highest and lowest values
range = [ Math.abs(data[0]),
Math.abs(data[data.length-1]) ].sort(function sortfunction(a, b){
return (b - a) //causes an array to be sorted numerically and
ascending
})[0];
// Push values into the first dataset
data1 = map(data, function(value, index) {
if (value > 0) {
return range;
} else {
return range - Math.abs(value);
}
});
// Push values into the second dataset
data2 = map(data, function(value, index) {
if (value > 0) {
return parseFloat(value,2);
} else {
return range - data1[index];
}
});
// Push values ion the third dataset
data3 = map(data1, function(value, index) {
return (range * 2) - value - data2[index];
});
wp.r.g.barchart(50, -9, 450, 339, [data1, data2, data3], {
stacked: true,
colors:['#fff','#000', '#fff']
});
axis = wp.r.g.axis(50,310,300,-range, range, 10, 1);
}
function updateWaterfall() {
wp.r.g.txtattr.font = "14px Helvetica, Arial";
wp.r.g.text(10, 180, "% Change from baseline").rotate(-90, true);
wp.r.g.text(280, 320, "Patients");
if ($('.shrinkage_input_0').exists) {
$('.shrinkage_input_0').each(function() {
wp.data.push($(this).val());
});
} else {
wp.data = [0]
}
render_waterfall_plot(wp.data);
axis.text.attr({font:"12px Arial", "font-weight": "regular",
"fill": "#333333"});
wp.r.path("M50 160L500 160");
}
function map(collection, func) {
var mapped = [],
m = 0.
len = collection.length;
for (m; m < len; m += 1) {
mapped.push( func(collection[m], m) );
}
return mapped;
}
Basically it renders 3 overlapping bar charts, the first one is white
and covers up the bottom portion of the 2nd black bar. The 3rd one is
also white and covers up any remaining area above the black bar. So
the black bar can be positioned above or below a middle axis. The
render_waterfall_plot function takes an array that can be pulled from
text inputs. The array is made up of positive or negative numbers
(percentages). Then the range is calculated (max absolute value) so
that the axis can be plotted. The 3 data sets are for the 3 bar charts
that together create the waterfall plot. The map function is to invoke
a function on every element of an array.
Hope this helps someone.