# Creating a highly customized BarChart

I am trying to create a BarChart visualization for multi-step data filtering. Think of a traditional sales funnel: many leads, fewer prospects, few customers, very few return customers. The only kicker is, I want to show the percentage of data being lost by using Percentile layout for the BarChart, and I want to show that the slice of previous bar is the entirety of the content of the next bar using lines similar to Joined option, and if possible, fill the joining lines with color similar to the one used for selection. Lastly,for my data content, there are 2 types of filters: binary (e.g. lead becomes prospect or not) and slice-of-pie (e.g. customers who spent between X and Y, where the slice would appear in the middle of the column, with rest of sales with lower amount appearing below, and higher amount appearing above). I can draw this using Graphics and basic primitives, but was really hoping that there's a clever way to adapt BarChart, so that I could use the built-in labeling or legending features, as well as the vertical axis. Or even go from Percentile to Stacked, as needed.

Here's a simple drawing of what I envision this could look like:

And if anyone can suggest an alternate visualization which will serve the purpose, I'd really appreciate it. I thought of using TreeGraph with VertexSize option, but it's less than trivial to visualize not only what made it into the filter, but also how much are you losing and where the loss occurs.

UPDATE:

Thanks to @Verbeia's clever solution, and a little bit of additional engineering, this is what I came up with. Clearly there's endless room for improvement, but the automation works great.

data = {{4, 3, 4.5, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 3, 5, 6, 0,
0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0}, {0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1}};
lines = Flatten[Table[{
{{1.501 n,
100 data[[n, 3 n - 2]]/Total@data[[n]]}, {1.5 n + .499,
0}}, {{1.501 n,
100 (data[[n, 3 n - 2]] + data[[n, 3 n - 1]])/
Total@data[[n]]}, {1.5 n + .499, 100}}}
, {n, 1, 3}], 1];

Show[
BarChart[data, ChartLayout -> "Percentile",
BarSpacing -> {None, .5}, ChartStyle -> "Pastel"],
ListLinePlot[lines,
Filling ->
Table[(2 n - 1) -> {{2 n},
Directive[Opacity@0.75,
ColorData["Pastel"][(3 n - 2)/(3 4)]]}, {n, 1, 3}],
PlotStyle -> Directive[Dashed, Gray]]
, ImageSize -> 850]


And the result:

-

The built-in Joined option to BarChart doesn't really do what you want. So what I'd suggest is overlaying a BarChart on a ListLinePlot that creates the lines. Here is a simplified two-stacks-of-bars version.

data = {{4, 3, 0, 0, 4.5}, {0, 3, 5, 6, 0}};


The first point is that you will need to have zero-value elements in the bar chart data to ensure you get different coloring in the different stacks, or else use Style explicitly to customise the coloring in each stack.

Then you need to come up with lines that draw between the bars. This might be able to be automated, but it would require knowledge of which bar segments are the ones that "expand" to the next stack, as well as the BarSpacing option value in the BarChart, which determines the horizontal coordinates of the bars.

lines = {{{1, 100 data[[1, 1]]/Total[data[[1]] ]}, {1.5,
100 data[[1, 1]]/Total[data[[1]] ]}, {1.7, 0}},
{{1, 100 (data[[1, 1]] + data[[1, 2]])/Total[data[[1]] ]},
{1.5, 100 (data[[1, 1]] + data[[1, 2]])/Total[data[[1]] ]}, {1.7,  100}}};


Putting them together is fairly straightforward, but watch the PlotRange and Filling options in the ListLinePlot function:

Show[ListLinePlot[lines, PlotRange -> {{0, 3}, {0, 101}}, Filling -> {2 -> {1}}],
BarChart[data, ChartLayout -> "Percentile"]]


-
+1 Maybe with PlotStyle -> None in ListLinePlot[ ]. –  Silvia Jun 27 '13 at 7:36
Or PlotStyle -> Dashed in ListLinePlot. –  David Carraher Jun 27 '13 at 7:59
Or even using arrows instead of lines: data = {{4, 3, 0, 0, 4.5}, {0, 3, 5, 6, 0}}; arrows = {Dashed, Arrow[{{1.5, 100 data[[1, 1]]/Total[data[[1]]]}, {1.7, 0}}], Arrow[{{1.5, 100 (data[[1, 1]] + data[[1, 2]])/Total[data[[1]]]}, {1.7, 100}}]}; Show[BarChart[data, ChartLayout -> "Percentile"], Graphics[arrows, PlotRange -> {{0, 3}, {0, 101}}]] –  David Carraher Jun 27 '13 at 8:16
@Verbeia: clever use of 0s in the BarChart, to hide slices of color!!! Very nice! Issue that I have with your solution, and perhaps you can enlighten me... your 1.5 number is hard-coded. As I add a custom number of bars to the plot, or as BarChart options change, I really don't know what that distance between bars will be. I can have anywhere from 1 bar (no lines) to a dozen bars or more (rare), with 4-6 bars being a very common scenario. –  Gregory Klopper Jun 27 '13 at 22:58
Nevermind, I actually see that any number of columns is created using the same spacing: 0.5 + (1+0.2)x#bars. I can now create a function to convert a list of any number of filters (2 or 3 elements) into lines and bars. and if I stack their order: {1,2,0,0,0,0,0},{0,0,3,4,5,0,0},{0,0,0,0,0,6,7}, I can apply any number of colors I want. Same with the lines, if I make them all separate lines, I can control colors with FillingStyle. WIN! Thank you! –  Gregory Klopper Jun 27 '13 at 23:05