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
349 views
in Technique[技术] by (71.8m points)

chart does not read correctly seconds from datetime variable c#

below a piece of code it keeps me in trouble:

 private void ShowDatainChart()
    {
        Chart chart = this.chart1;
        chart.Series.Clear();
        int[] ser = { 1, 2, 3 };
        foreach (int s in ser)
        {
           chart.Series.Add(s.ToString());
           chart.Series[s - 1].XValueType = ChartValueType.Time;
           chart.Series[s - 1].YValueType = ChartValueType.Time;
           chart.Series[s - 1].ChartType = SeriesChartType.RangeBar;
        }
        string ser;
        foreach (DataRow row in dt.Rows)
        {
            ser = row["BAT_QUEUE"].ToString();
            chart1.ChartAreas[0].AxisY.LabelStyle.Format = "MMM:dd HH:mm:ss";
            chart.Series[ser].Points.AddXY(row["BATCH_NAME"],row["BEGIN"],row["END"]);
        }
    }

it takes data from datatable which contains for columns: BAT_QUEUE string, BATCH_NAME string and two datetimes BEGIN and END. Generally three queues starts several batches every day and each of such batches takes a few seconds/minutes/hours. The result I expect is something similar to "gantt chart" so it could gives me a tool to make some analyses. As far as I searched the best choice for this task is RangeBar - unfortunately the type of chart used not so often. The code above works perfect until I draw only one of three series ( doesn't metter which one). It draws several horizontal bars, one by one on different levels with different names. But when more series is choosen many bars is connected with wrong names.
It looks like the chart does not read seconds from BEGIN/END fields so if two batches from different queues starts at the same hour and minute but different second they are wrongly interpreted.

... it is pretty difficult to explain but I hope some of you understand what I mean and give me some hints what is wrong and how repair/solve my problem

thanks for any help in advance

ok, following Sinatr suggestions below the code which allows to show my problem. Right now, after a time spent on analyzes I see the problem is not with datetime format . It looks like a deeper one. Every series starts from the same object created by the first series - and this in wrong. Anyway look at code . Of course it expects chart object created on windows form

private void ShowDatainChart()
    {
        DateTime a1 = new DateTime(2014, 07, 01, 00, 03, 00);
        DateTime a2 = new DateTime(2014, 07, 01, 01, 17, 10);
        DateTime b1 = new DateTime(2014, 07, 01, 00, 02, 33);
        DateTime b2 = new DateTime(2014, 07, 01, 00, 44, 13);
        DateTime a12 = new DateTime(2014, 07, 01, 01, 18, 00);
        DateTime a22 = new DateTime(2014, 07, 01, 02, 22, 10);

        chart1.Series.Clear();
        string[] ser = { "1", "2" };
        foreach (string s in ser)
        {
            chart1.Series.Add(s);
            chart1.Series[s].ChartType = SeriesChartType.RangeBar;
            chart1.Series[s].XValueType = ChartValueType.DateTime;
            chart1.Series[s].YValueType = ChartValueType.DateTime;
        }
        chart1.Series["1"].Points.AddXY("A", a1, a2);
        chart1.Series["1"].Points.AddXY("A1", a12, a22);
        chart1.Series["2"].Points.AddXY("B", b1, b2);
    }

Batches A and A1 from first series are displayed correct, but B from second series are displayed as A :(

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

The reason you don't see your "B" X-value is that you don't use the AddPointXY method right.

For RangeBar the XValueType should not be ChartValueType.DateTime but either Int32 or Auto.

With these settings the X-values will work as expected and create a new row of data points fo each distinct value, spaced as expected.

It is very helpful to think of the RangeBar chart type basically as a specialized chart made for task management. Look at the example at MSDN: Here you see that there are just two series, namely Task and Progress but there are both several tasks and subtask datapoints visible in the chart..:

MSDN range chart

So setting the XValueType to ChartValueType.DateTime makes no sense at all, even if you would actually feed in dates..

Note: Setting it to ChartValueType.String doesn't work either since the strings don't evaluate to a position on the X-Axis; instead, as with ChartValueType.DateTime, each series maps its points onto the rows that are there already without creating new labels until it runs out of rows. Only then it will create a new row and put its label on it. Not recommended!!

Instead you assign each row a number and also assign its label explicitly:

To add points you write:

 chart1.Series["1"].Points.AddXY(1, a1, a2);
 chart1.Series["1"].Points.AddXY(2, a12, a22);
 chart1.Series["2"].Points.AddXY(3, b1, b2);

To add the Labels (Note: all series share the same axis/labels!) :

 chart1.Series["1"].Points[0].AxisLabel = "A1";
 chart1.Series["1"].Points[1].AxisLabel = "A2";
 chart1.Series["2"].Points[2].AxisLabel = "B"; 

If you want the series to overlap, as the example does so nicely, you need to set the PointWidth and the DrawSideBySide parameters:

chart1.Series["1"]["PointWidth"] = "0.7";
chart1.Series["2"]["PointWidth"] = "0.2";
chart1.Series["2"]["DrawSideBySide"] = "false";

Some of this was salvaged from the MSDN Chart Example code which is remarkably buggy and incomplete.. (One small indication is visible even in the above chart: 'Task 5' should probably be labelled 'Task 3'..)

Also note that x- and y-axis are switched for all bar-type charts, so the x-axis is the vertical one!


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

1.4m articles

1.4m replys

5 comments

56.8k users

...