ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Waterfall chart with connector lines
Posted by Darryl Lyons on Oct-04-2023 10:15
Attachments:
Hi

Does anyone know if it possible to create a waterfall chart with connector lines between each of the boxes? It is a common practice to show a dashed line connecting start/end values of each box in the waterfall. I have attached an example of how I would like this to look.

Additionally, is it possible to overlay a condensed format data label, where the positive values are on the top and negative values on the bottom? I would be able to separately provide the custom formats of these data labels.

Thanks.
2023-10-04_11-57-20.png

  Re: Waterfall chart with connector lines
Posted by Peter Kwan on Oct-04-2023 17:51
Attachments:
Hi Darryl,

Yes, you can definitely make the same chart with ChartDirector.

In the attached chart image, I started from the "Waterfall Chart" sample code included in ChartDirector. I used Layer.addCustomDataLabel to add the labels on top/bottom of the bars, and I use line layers to add the dash lines.

The exact code depends on which programming language you are using. The following is my test code in C#. If you need to translate the code to another programming language, please let me know.


// 4 data points to represent the cash flow for the 5 products
double[] data = { 230, 140, -600, 330, 150 };

// We want to plot a waterfall chart showing the 5 products as well as the total
string[] labels = {"Product 1", "Product 2", "Product 3", "Product 4", "Product 5",
"Total"};

// The top side of the bars in a waterfall chart is the accumulated data. We use the
// ChartDirector ArrayMath utility to accumulate the data. The "total" is handled by
// inserting a zero point at the end before accumulation (after accumulation it will
// become the total).
double[] boxTop = new ArrayMath(data).insert2(0, 1).acc().result();

// The botom side of the bars is just the top side of the previous bar. So we shifted
// the top side data to obtain the bottom side data.
double[] boxBottom = new ArrayMath(boxTop).shift(1, 0).result();

// The last point (total) is different. Its bottom side is always 0.
boxBottom[boxBottom.Length - 1] = 0;

// Create a XYChart object of size 500 x 280 pixels. Set background color to light blue
// (ccccff), with 1 pixel 3D border effect.
XYChart c = new XYChart(500, 290, 0xccccff, 0x000000, 1);

// Add a title to the chart using 13 points Arial Bold Itatic font, with white (ffffff)
// text on a deep blue (0x80) background
c.addTitle("Product Revenue - Year 2004", "Arial Bold Italic", 13, 0xffffff
).setBackground(0x000080);

// Set the plotarea at (55, 50) and of size 430 x 215 pixels. Use alternative white/grey
// background.
c.setPlotArea(55, 45, 430, 215, 0xffffff, 0xeeeeee);

// Set the labels on the x axis using Arial Bold font
c.xAxis().setLabels(labels).setFontStyle("Arial Bold");

// Set the x-axis ticks and grid lines to be between the bars
c.xAxis().setTickOffset(0.5);

// Use Arial Bold as the y axis label font
c.yAxis().setLabelStyle("Arial Bold");

// Add a title to the y axis
c.yAxis().setTitle("USD (in millions)");

// Add the join lines
for (int i = 0; i < boxTop.Length - 1; ++i) {
LineLayer joinLine = c.addLineLayer(new double[] { boxTop[i], boxTop[i] }, c.dashLineColor(0xff6600));
joinLine.setLineWidth(3);
joinLine.setXData(i, i + 1);
}

// Add a multi-color box-whisker layer to represent the waterfall bars
BoxWhiskerLayer layer = c.addBoxWhiskerLayer2(boxTop, boxBottom);
layer.setBorderColor(Chart.SameAsMainColor);

// Add the labels
for (int i = 0; i < boxTop.Length; ++i)
{
double datum = boxTop[i] - boxBottom[i];
string label = ((datum >= 0) ? "$" : "-$") + Math.Abs(datum);
int alignment = (datum >= 0) ? Chart.Bottom : Chart.Top;
layer.addCustomDataLabel(0, i, label, "Arial Bold", 8).setAlignment(alignment);
}

// Output the chart
viewer.Chart = c;

//include tool tip for the chart
viewer.ImageMap = c.getHTMLImageMap("clickable", "",
"title='{xLabel}: {={top}-{bottom}} millions'");


Regards
Peter Kwan
test.png

  Re: Waterfall chart with connector lines
Posted by Darryl Lyons on Oct-05-2023 07:44
You are a legend. That's exactly what we need. Thanks Peter!

  Re: Waterfall chart with connector lines
Posted by Darryl Lyons on Oct-05-2023 14:26
Hi Peter

Is there anyway that you can add a 1 or 2 pixel gap between the top/bottom of the box and the data label?

Many thanks

Darryl

  Re: Waterfall chart with connector lines
Posted by Peter Kwan on Oct-06-2023 00:40
Hi Darryl,

One way to increase the gap is to set a bigger textbox margin for the labels. To do this, you may change the following line:

layer.addCustomDataLabel(0, i, label, "Arial Bold", 8).setAlignment(alignment);

to:

ChartDirector.TextBox t = layer.addCustomDataLabel(0, i, label, "Arial Bold", 8);
t.setAlignment(alignment);
t.setMargin(3);   // Set the margin to 3 pixels

Best Regards
Peter Kwan

  Re: Waterfall chart with connector lines
Posted by Darryl Lyons on Oct-06-2023 06:47
Hi Peter

That's exactly what we wanted. Again, thanks for your help.

Regards

Darryl