我有一个 .NET 图表,目前看起来像这样:
这是用于生成它的代码:
protected void Page_Load(object sender, EventArgs e)
{
// Set Chart properties
ganttChart.Width = 800;
ganttChart.Height = 500;
// Create Chart Area
var area = new ChartArea();
ganttChart.ChartAreas.Add(area);
ganttChart.ChartAreas[0].AxisY.LabelStyle.Angle = 30; // For some unknown reason Y-Axis is actually the X-Axis
ganttChart.ChartAreas[0].AxisY.LabelStyle.Format = "HH:mm dd/MMM";;
// Set up some data
var dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("SeriesID", typeof(double));
dt.Columns.Add("y", typeof(DateTime));
dt.Columns.Add("y2", typeof(DateTime));
dt.Rows.Add("A", 1, new DateTime(2015, 10, 22, 8, 0, 0), new DateTime(2015, 10, 22, 9, 0, 0));
dt.Rows.Add("A", 1, new DateTime(2015, 10, 22, 10, 0, 0), new DateTime(2015, 10, 22, 12, 0, 0));
dt.Rows.Add("A", 1, new DateTime(2015, 10, 22, 18, 0, 0), new DateTime(2015, 10, 22, 20, 0, 0));
dt.Rows.Add("B", 2, new DateTime(2015, 10, 22, 8, 30, 0), new DateTime(2015, 10, 22, 9, 13, 0));
dt.Rows.Add("B", 2, new DateTime(2015, 10, 22, 17, 0, 0), new DateTime(2015, 10, 22, 18, 43, 0));
dt.Rows.Add("C", 3, new DateTime(2015, 10, 22, 13, 0, 0), new DateTime(2015, 10, 22, 14, 0, 0));
dt.Rows.Add("C", 3, new DateTime(2015, 10, 22, 14, 22, 0), new DateTime(2015, 10, 22, 14, 32, 0));
var series = new Series();
series.Name = "Series1";
series.ChartType = SeriesChartType.RangeBar;
series.YValueType = ChartValueType.DateTime;
// Add the series to the chart
ganttChart.Series.Add(series);
ganttChart.Series[series.Name].Points.DataBind(dt.Select(), "SeriesID", "y,y2", "Label=Name");
ganttChart.Series[series.Name].Label = "Y = Name";
}
我想要实现的是将数据表的名称字段作为 Y 轴上的标签,这样您就可以在图表的左侧看到 A、B 和 C,而不是 0、1、2, 3,4。
如果我使用 Name 而不是系列 ID 更改 DataBind 方法,那么我会得到我想要的效果,但随后我会丢失 Y 轴分组。它最终看起来像这样:
我需要的是一种快乐的媒介,其中分组就像第一张图片,标签就像第二张图片。我怎样才能做到这一点?
我的问题的解决方案不是依赖 DataBinding,而是手动创建每个点并将其添加到系列中。这样我就可以更好地控制每个点的属性。
我创建了一个名为 MapDataRowToDataPoint 的方法,如下所示:
private DataPoint MapDataRowToDataPoint(DataRow row)
{
try{
var point = new DataPoint();
point.XValue = double.Parse(row["SeriesID"].ToString());
point.YValues = new double[]{
Convert.ToDateTime(row["Y1"].ToString()).ToOADate(),
Convert.ToDateTime(row["Y2"].ToString()).ToOADate()
};
point.AxisLabel = row["SeriesName"].ToString();
point.Color = ColorTranslator.FromHtml("#" + row["Colour"].ToString());
point.BorderWidth = 1;
point.BorderColor = Color.Black;
point.ToolTip = row["ToolTip"].ToString()
+ ((!string.IsNullOrEmpty(row["ToolTip"].ToString()))?"\n":"")
+ "Start Date Time: #VALY{"+toolTipDateTimeFormat+"}\n"
+"End Date Time: #VALY2{"+toolTipDateTimeFormat+"}";
point.IsValueShownAsLabel = false;
point.PostBackValue = row["PostBackValue"].ToString();
return point;
}
catch
{
//Log the error
return null;
}
}
在这里你可以看到我将我的数据表的一行映射到一个 DataPoint 对象,并且可以非常详细地控制数据点的每个属性。
现在,我不再进行数据绑定(bind),而是遍历数据源的每一行并调用上述方法,然后将点添加到图表的系列:
// For each row of the DataSource, create a data point and add it to the chart
foreach(DataRow row in data.Rows)
{
var point = MapDataRowToDataPoint(row);
if(point != null)
ganttChart.Series[0].Points.Add(point);
}
事实证明,这种方法比依赖数据绑定(bind)要轻松得多。希望这对您有所帮助!
我是一名优秀的程序员,十分优秀!