I am trying to create a stacked column chart with 4 series in it. But somehow, after populating the series and making sure they are aligned, instead of columns, thin lines appears. Code is as below.
foreach (Series s in chartEvents.Series)
s.Points.Clear();
foreach (DataRow dr in data.Rows)
{
string reason = "";
double xVal = 0;
double yVal = 0;
double overFlow = 0;
double existFlow = 0;
try
{
reason = dr["reasonID"].ToString();
xVal = Math.Round(Convert.ToDateTime(dr["XValue"].ToString()).ToOADate(), 6);
yVal = Math.Round(Convert.ToDouble(dr["duration"].ToString()) / 60, 3);
overFlow = 0;
// assume tooltip prepared and format length here
do
{
overFlow = 0;
#region check if duration at x value will exceed 60 mins
foreach (Series s in chartEvents.Series)
{
if (s.Points.Count > 0)
{
foreach (DataPoint exist in s.Points)
{
// if point found, add up.
if (exist.XValue == xVal)
{
existFlow += exist.YValues[0];
}
}
}
}
// if added up + new > 60, set current y to 60 and calculate for overflow
if (existFlow + yVal > 60)
{
overFlow += yVal - (60 - existFlow);
yVal = 60 - (existFlow);
}
#endregion
DataPoint dp = new DataPoint(xVal, yVal);
DataPoint dpEmpty = new DataPoint(xVal, 0);
dpEmpty.IsEmpty = true;
#region Check series type and add to series.
if (reason.Contains("|"))
{
if (reason.Split('|')[3] == "SCHEDULED DOWN")
{
if (reason.Split('|')[4].Contains("SETUP"))
{
dp.ToolTip = Convert.ToDateTime(dr["dateStart"].ToString()).ToString("yyyy-MM-dd HH:mm:ss").PadRight(25) + "SETUP: " + actionDone;
dp.Color = Color.Goldenrod;
chartEvents.Series["SETUP"].Points.Add(dp);
chartEvents.Series["CLEAR"].Points.Add(dpEmpty);
chartEvents.Series["DOWN"].Points.Add(dpEmpty);
chartEvents.Series["OTHERS"].Points.Add(dpEmpty);
}
else
{
dp.ToolTip = Convert.ToDateTime(dr["dateStart"].ToString()).ToString("yyyy-MM-dd HH:mm:ss").PadRight(25) + "OTHERS: " + actionDone;
dp.Color = Color.Orange;
chartEvents.Series["OTHERS"].Points.Add(dp);
chartEvents.Series["CLEAR"].Points.Add(dpEmpty);
chartEvents.Series["DOWN"].Points.Add(dpEmpty);
chartEvents.Series["SETUP"].Points.Add(dpEmpty);
}
}
else if (reason.Split('|')[3] == "UNSCHEDULED DOWN")
{
dp.ToolTip = Convert.ToDateTime(dr["dateStart"].ToString()).ToString("yyyy-MM-dd HH:mm:ss").PadRight(25) + "DOWN: " + actionDone;
dp.Color = Color.Red;
chartEvents.Series["DOWN"].Points.Add(dp);
chartEvents.Series["CLEAR"].Points.Add(dpEmpty);
chartEvents.Series["OTHERS"].Points.Add(dpEmpty);
chartEvents.Series["SETUP"].Points.Add(dpEmpty);
}
else
{
// do something
}
}
else
{
dp.ToolTip = actionDone;
dp.Color = Color.Orange;
chartEvents.Series["CLEAR"].Points.Add(dp);
chartEvents.Series["DOWN"].Points.Add(dpEmpty);
chartEvents.Series["OTHERS"].Points.Add(dpEmpty);
chartEvents.Series["SETUP"].Points.Add(dpEmpty);
}
#endregion
if (overFlow > 0)
{
yVal = overFlow;
xVal = DateTime.FromOADate(xVal).AddHours(1).ToOADate();
existFlow = 0;
}
} while (overFlow != 0);
}
catch (Exception ex)
{
// do something
}
}
You probably have wrong
X-Values
for the purpose.Note that your
Series
can only stack whereDataPoints
have the sameX-Value
.DateTimes
include times downto fractions of a second, so they will never stack unless you twist them to meet your goal..You code is closely missing the point here:
Rounding a
DateTime
/OADate double
to 6 digits unfortunately will not trim the time portion. For this you would instead simply writeXValue = someDateTimeVariable.Date;
For other time intervals you must decide on the time interval, like days, minutes, hours etc.. and trim the data to multiples of that interval.
There are several ways to do that, here is one:
Now you can use it:
Here are two results, all the same data, just one with the minute interval, and the other with days.:
I suggest considering to set the
X-Axis
andX-Values
to useDateTime
datatype!Please ignore the fact that I'm not really creating a convincing stacked column chart, I simply didn't create good test data..