问题
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
}
}
回答1:
You probably have wrong X-Values
for the purpose.
Note that your Series
can only stack where DataPoints
have the same X-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:
xVal = Math.Round(Convert.ToDateTime(dr["XValue"].ToString()).ToOADate(), 6);
Rounding a DateTime
/ OADate double
to 6 digits unfortunately will not trim the time portion. For this you would instead simply write XValue = 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:
// define a suitable format string:
string myIntervalMonthFormat = "yyyy-MM-01 00:00:00";
string myIntervalDayFormat = "yyyy-MM-dd 00:00:00";
string myIntervalHourFormat = "yyyy-MM-dd hh:00:00";
string myIntervalMinuteFormat = "yyyy-MM-dd hh:mm:00";
// etc
Now you can use it:
string so = ((DateTime) dr["XValue"]).ToString(yourFormat );
xVal = Math.Round(Convert.ToDateTime(so).ToOADate(), 6);
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
and X-Values
to use DateTime
datatype!
Please ignore the fact that I'm not really creating a convincing stacked column chart, I simply didn't create good test data..
来源:https://stackoverflow.com/questions/30816395/why-do-chart-stacked-columns-show-up-as-thin-lines