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

怎甘沉沦 提交于 2021-02-02 09:55:08

问题


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.


回答1:


This is quite easy with MSChart and the ChartType RangeBar.

Here is an example:

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");



回答2:


Here is an example with DevExpress.XtraCharts.ChartControl and ViewType RangeBar

First add a DevExpress.XtraCharts.ChartControl to the form. Here is How I fill the chart

        rangeBarChart.Series.Clear();

        // Create two range bar series.
        Series series1 = new Series("Task1", ViewType.RangeBar);
        Series series2 = new Series("Task2", ViewType.RangeBar);

        series1.CrosshairLabelPattern = "{S}:{V1:HH:mm}--{V2:HH:mm}";
        series2.CrosshairLabelPattern = "{S}:{V1:HH:mm}--{V2:HH:mm}";


        //Add values to series
        series1.ValueScaleType = ScaleType.DateTime;
        series2.ValueScaleType = ScaleType.DateTime;
        series1.Points.Add(new SeriesPoint("A", Convert.ToDateTime("2019-08-24 8:00"), Convert.ToDateTime("2019-08-24 17:00")));
        series2.Points.Add(new SeriesPoint("A", Convert.ToDateTime("2019-08-24 9:00"), Convert.ToDateTime("2019-08-24 10:00")));
        series2.Points.Add(new SeriesPoint("A", Convert.ToDateTime("2019-08-24 13:00"), Convert.ToDateTime("2019-08-24 14:00")));

        // Add both series to the chart.
        rangeBarChart.Series.AddRange(new Series[] { series1, series2 });

        ((XYDiagram)rangeBarChart.Diagram).Rotated = true;

The result shows like this:



来源:https://stackoverflow.com/questions/57623080/how-can-i-make-a-gannt-chart-with-overlapping-points-in-winforms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!