为什么 Chart Stacked Columns 显示为细线?
Why do Chart Stacked Columns show up as thin lines?
我正在尝试创建一个包含 4 个系列的堆积柱形图。但不知何故,在填充系列并确保它们对齐后,出现细线而不是列。代码如下。
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
}
}
你的目的可能有误X-Values
。
请注意,您的 Series
只能堆叠在 DataPoints
与 相同 X-Value
的位置。 DateTimes
包括精确到几分之一秒的时间,因此它们永远不会叠加,除非您扭曲它们以达到您的目标..
你的代码没有抓住要点:
xVal = Math.Round(Convert.ToDateTime(dr["XValue"].ToString()).ToOADate(), 6);
不幸的是,将 DateTime
/ OADate double
舍入到 6 位数字将 而不是 trim 时间部分。为此,您只需编写 XValue = someDateTimeVariable.Date;
对于其他时间间隔,您必须决定时间间隔,例如天、分钟、小时等。并且trim数据为该间隔的倍数。
有几种方法可以做到这一点,这里是一种:
// 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
现在可以使用了:
string so = ((DateTime) dr["XValue"]).ToString(yourFormat );
xVal = Math.Round(Convert.ToDateTime(so).ToOADate(), 6);
这里有两个结果,都是一样的数据,一个是分钟间隔,另一个是天数。:
我建议考虑将 X-Axis
和 X-Values
设置为使用 DateTime
数据类型!
请忽略我并没有真正创建令人信服的堆积柱形图,我只是没有创建好的测试数据..
我正在尝试创建一个包含 4 个系列的堆积柱形图。但不知何故,在填充系列并确保它们对齐后,出现细线而不是列。代码如下。
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
}
}
你的目的可能有误X-Values
。
请注意,您的 Series
只能堆叠在 DataPoints
与 相同 X-Value
的位置。 DateTimes
包括精确到几分之一秒的时间,因此它们永远不会叠加,除非您扭曲它们以达到您的目标..
你的代码没有抓住要点:
xVal = Math.Round(Convert.ToDateTime(dr["XValue"].ToString()).ToOADate(), 6);
不幸的是,将 DateTime
/ OADate double
舍入到 6 位数字将 而不是 trim 时间部分。为此,您只需编写 XValue = someDateTimeVariable.Date;
对于其他时间间隔,您必须决定时间间隔,例如天、分钟、小时等。并且trim数据为该间隔的倍数。
有几种方法可以做到这一点,这里是一种:
// 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
现在可以使用了:
string so = ((DateTime) dr["XValue"]).ToString(yourFormat );
xVal = Math.Round(Convert.ToDateTime(so).ToOADate(), 6);
这里有两个结果,都是一样的数据,一个是分钟间隔,另一个是天数。:
我建议考虑将 X-Axis
和 X-Values
设置为使用 DateTime
数据类型!
请忽略我并没有真正创建令人信服的堆积柱形图,我只是没有创建好的测试数据..