This answer is not very elegant, but it should give you what you need. You already had the idea of using chart.SeriesCollection[i].Values
. If the address contained in chart.SeriesCollection[i].Values
is used, you can get the value from the same data that the chart is getting the value from to create the column.
Replace the line code where you define the string label.
string label = chart.SeriesCollection[i].Points[j].DataLabel.Text;
With this line.
string label = chart.Sheet.Workbook.Worksheets[chart.Sheet.Name].Cells[chart.SeriesCollection[i].Values.ToString().Replace("=" + chart.Sheet.Name + "!", "")][0, j].Value.ToString();
This way the value is not controlled by the way the label is formatted.
If the cell value is null, this will throw an exception when ToString()
is added.
Here is another version with the changed line separated out more so it is less confusing. Also there is a check for null value before using ToString()
.
//if you do not have direct access to the worksheet object.
SpreadsheetGear.IWorksheet worksheet1 = chart.Sheet.Workbook.Worksheets[chart.Sheet.Name];
for (int i = 0; i < chart.SeriesCollection.Count; i++)
{
Color positiveColor = Color.FromArgb(79, 129, 189); // blue
Color negativeColor = Color.FromArgb(192, 80, 77); // red
chart.SeriesCollection[i].HasDataLabels = true;
//Get the address of the series
string address = chart.SeriesCollection[i].Values.ToString().Replace("=" + chart.Sheet.Name + "!", "");
for (int j = 0; j < chart.SeriesCollection[i].Points.Count; j++)
{
double pointValue;
//bool usePositiveValueColor = false;
// If the point is -0.004 but the number format is "0.00",
// label will be "0.00"
//string label = chart.SeriesCollection[i].Points[j].DataLabel.Text;
string label = (worksheet1.Cells[address][0, j].Value != null)
? worksheet1.Cells[address][0, j].Value.ToString() : "0";
chart.SeriesCollection[i].Points[j].Format.Fill.ForeColor.RGB =
(System.Double.TryParse(label, out pointValue) && pointValue >= 0)
? positiveColor
: negativeColor;
}
}