c# - 如何在 .NET 图表的 Y 轴上对数据进行分组?

标签 c# asp.net .net charts

我有一个 .NET 图表,目前看起来像这样:

enter image description here

这是用于生成它的代码:

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 轴分组。它最终看起来像这样:

enter image description here

我需要的是一种快乐的媒介,其中分组就像第一张图片,标签就像第二张图片。我怎样才能做到这一点?

最佳答案

我的问题的解决方案不是依赖 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)要轻松得多。希望这对您有所帮助!

关于c# - 如何在 .NET 图表的 Y 轴上对数据进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33282600/

相关文章:

c# - HttpContext.User 设置正确,然后被下一个请求丢失/替换

c# - bool 的 MVC 4 自定义模板( Razor )

c# - 如何跟踪我在其他网站上作为链接提供的软件

ASP.NET Core - TagHelper、部分 View 和属性名称冲突

c# - 如何通过 LINQ 在二维数组中进行搜索?

c# - LINQ to SQL Basic 插入引发 : Attach or Add not new entity related exception

c# - 是否可以设置 Entity Framework 提供程序将执行的实际 SQL?

c# - 这是避免回发的好方法吗?

c# - Entity Framework 代码优先 : CASCADE DELETE for same table many-to-many relationship

c# - 从 C# 代码内部访问 F# 映射