Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
492 views
in Technique[技术] by (71.8m points)

c# - How can I make a gannt chart with overlapping points in winforms

There is a time interval like 8:00-17:00.In this time interval happens a task several times for example 9:00-9:20 , 11:00-12:00, 13:00-13:20.I want to make a chart in winforms to show when the task happens like this. So can I do this with DEV gannt chart? Or is there any Control I can use to make it?

I want to do this in winforms.enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is quite easy with MSChart and the ChartType RangeBar.

Here is an example:

enter image description here

To get this result you need to

  • Add an MSChart control from the data toolbox
  • Add the using clause: using System.Windows.Forms.DataVisualization.Charting;
  • Then you can style the chart..
  • ..and maybe set a size limit

Here is the code for setting it up:

void setUpGantt(Chart chart)
{
    chart.Series.Clear();
    Series s = chart.Series.Add("gantt");
    s.ChartType = SeriesChartType.RangeBar;
    s.YValueType = ChartValueType.DateTime;
    s.AxisLabel = "";
    s.IsVisibleInLegend = false;
    Axis ax = chart.ChartAreas[0].AxisX;
    Axis ay = chart.ChartAreas[0].AxisY;
    ax.MajorGrid.Enabled = false;
    ax.MajorTickMark.Enabled = false;
    ax.LabelStyle.Format = " ";
    ax.Enabled = AxisEnabled.False;
    ay.LabelStyle.Format = "HH:mm";
    ay.MajorGrid.Enabled = false;
    ay.MajorTickMark.Enabled = false;
    ay.LineColor = chart.BackColor;
    limitGantt(chart, "8:00", "17:00");
}

void limitGantt(Chart chart, string start, string end)
{
    Axis ax = chart.ChartAreas[0].AxisX;
    ax.Minimum = 0.5;  // we have only one slot
    ax.Maximum = 1.5;  // the bar is centered on its value (1)

    Axis ay = chart.ChartAreas[0].AxisY;
    ay.Minimum = fromTimeString(start).ToOADate();  // we exclude all times..
    ay.Maximum = fromTimeString(end).ToOADate();    // ..outside a given range
}

Note that I used time strings for convenience. Of course you can change to using DateTimes directly. For the conversion of a time string to a DateTime of the current day this function is used:

DateTime fromTimeString(string time)
{
    var p = time.Split(':');
    int sec = p.Length == 3 ? Convert.ToInt16(p[2]) : 0;
    TimeSpan t = new TimeSpan(Convert.ToInt16(p[0]), Convert.ToInt16(p[1]), sec);
    return DateTime.Today.Add(t);
}

Note that all the code is lacking any checks!

To add a task this method is used:

void addGanttTask(Series s, string start, string end, Color c, int slot )
{
    DateTime start_ = fromTimeString(start);
    DateTime end_ = fromTimeString(end);
    int pt = s.Points.AddXY(slot, start_, end_);
    s.Points[pt].Color = c;
}

Note that it contains both a Series and a 'slot'. The slots are used for the x-values, which in your case all are the same. But one can easily image a more comples planner with several bars for several resources, like various rooms or teams..

The Series parameter would allow to overlay a second series like you can see in this nice example from MSDN..

Here is how I filled the chart:

setUpGantt(chart1);

Series s = chart1.Series[0];
addGanttTask(s, "8:00", "17:00", Color.LimeGreen, 1);
addGanttTask(s, "9:00", "9:20", Color.DarkSlateBlue, 1);
addGanttTask(s, "11:00", "12:00", Color.DarkSlateBlue, 1);
addGanttTask(s, "13:00", "13:20", Color.DarkSlateBlue, 1);

Note that different ranges may overlap and might hide each other. In our example the green bar is added first and the others lie on top. In the MSDN example you see how the yellow bars are narrower to keep the bars under them visible. They belong to a 2nd series.

To change the bars' widths use

series.SetCustomProperty("PixelPointWidth",  "15");

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...