15

我正在向用户展示一个图表,其中有一个带有折线图的图表区域。例如,在这一点上,我得到了一条线。这条线有大约 200 个值。这些值都有描述(例如"01.01.2013""05.02.2013"等等)。

当图表显示时,我只能看到两个描述,即使有更多描述的空间。该线得到正确显示,但只描述了两点。

我垂直旋转了文本,以便有更多空间,但这没有帮助。如果我显示较少的值(5 或 10),说明会正确显示。

这就是它的实际外观(描述实际上是字符串,而不是日期)。

具有很多值但在 X 轴上只有两个描述的图表

感谢您的帮助!

编辑:我的代码:

chart.ChartAreas(0).AxisY.Maximum = 6
chart.ChartAreas(0).AxisY.Minimum = 1
chart.ChartAreas(0).AxisX.LabelStyle.Angle = -90
chart.Series.Clear()
chart.ChartAreas(0).AxisY.StripLines.Clear()
Dim myStripLine1 as new StripLine()
myStripLine1.IntervalOffset = 4
chart.ChartAreas(0).AxisY.StripLines.add(myStripLine1)

'now adding all series
chart.Series.Add("Chemie") 'just to take the example in the image above
chart.Series(chart.Series.Count - 1).ChartType = DataVisualization.Charting.SeriesChartType.Line
chart.Series(chart.Series.Count - 1).BorderWidth = 4

'now adding quite much values (on every date, every Serie has a value)
 chart.Series(chart.Series.Count - 1).Points.AddXY("01.03.2011", 4.9)

在每个日期,都会为所有系列输入一个新点,但只有那些具有重要价值的点才会突出显示。之间的这些值是数学计算的。

一个例子来解释这一点:我有两个系列,一个在点"01.01.2013"和上有两个值(6 和 4) "03.01.2013"。另一个系列在和上有 3 个值 (4,6,5.5 "01.01.2013") 。当我只显示它们时,第一个系列将在第二个日期结束,即使第三个日期有一个值。我通过在第一个系列中填充一个虚拟值来解决这个问题,日期只是此时的平均值(=5)。这一点根本不会用标记项目符号突出显示。这就是我绘制图表的方式。"02.01.2013""03.01.2013""02.01.2013"

编辑2:

Skippy 的回答和评论之后,我的新审判。变量MainForm.grades是 aDictionary(Of Integer,Dictionary(Of String, String))包含大约 150 个等级

    Dim subjects As New Dictionary(Of Integer, ArrayList)
    Dim allgrades As New ArrayList
    For Each grade In MainForm.grades
        Dim cD As New Dictionary(Of String, String)
        cD.Add("SUBJECTID", grade.Value("SUBJECTID"))
        cD.Add("GRADE", grade.Value("GRADE"))
        cD.Add("DATE", grade.Value("DATE"))
        allgrades.Add(cD)
    Next

    cht_main.ChartAreas(0).AxisX.IntervalType = DateTimeIntervalType.Days
    cht_main.ChartAreas(0).AxisX.LabelStyle.Angle = -90
    Dim gradesDateSorter = New gradesDateSorter()
    allgrades.Sort(gradesDateSorter)
    For Each grade In allgrades
        If Not subjects.ContainsKey(Integer.Parse(grade("SUBJECTID"))) Then
            subjects.Add(Integer.Parse(grade("SUBJECTID")), New ArrayList)
        End If
        Dim gradeDict As New Dictionary(Of String, String)
        gradeDict.Add("DATE", grade("DATE"))
        gradeDict.Add("GRADE", grade("GRADE"))
        subjects(Integer.Parse(grade("SUBJECTID"))).Add(gradeDict)
    Next
    For Each subject In subjects
        'adding serie
        cht_main.Series.Add(MainForm.subjects(subject.Key)("NAME"))
        cht_main.Series(cht_main.Series.Count - 1).ChartType = DataVisualization.Charting.SeriesChartType.Line
        cht_main.Series(cht_main.Series.Count - 1).BorderWidth = 4
        'cht_main.Series(cht_main.Series.Count - 1).IsXValueIndexed = True
        For Each grade In subject.Value
            cht_main.Series(cht_main.Series.Count - 1).Points.AddXY(Date.Parse(grade("DATE")), Double.Parse(grade("GRADE")))
        Next
    Next

在我评论的最后一行的第 5 行,IsXValueIndexed=True因为当我激活它时,图表会生成一个大的红色错误十字。


解决方案

在 X 轴上设置间隔就可以了!

chart.ChartAreas(0).AxisX.Interval = 1

Skippy的解决方案

4

2 回答 2

19

是的,我同意迈克尔的观点。在这一点上我只能补充说明。

通过设置间隔:

myStripLine1.IntervalOffset = 4

您保证仅以 4 个“通用 x 轴”值的频率绘制您的 X 轴值:

将此设置为 vale 为 1 将为每个 x 轴值提供一个值,该值作为整数递增(在本例中为天)

chart.ChartAreas(0).AxisX.Interval = 1

并声明要键入的 x 轴值:

DateTimeIntervalType.Days

'Declaration
    Public Sub Add( _
    labelsStep As Double, _
    intervalType As DateTimeIntervalType, _
    format As String _
)
End Sub

chart.ChartAreas(0).AxisX.IntervalType = DateTimeIntervalType.Days

'which as shown in Michael's answer is parsed to string.

Dim format as String = "MM.dd.yyyy"
Dim actualDate as Date = Date.ParseExact(yourDate, format)

正如迈克尔在评论中提到的那样。通过设置

mySeries.XValueIndexed = True

将绘制每个索引的 X 轴值。

如以下引用中所述,并提供了链接。

系列中的每个数据点都有 X 和 Y 值,这些值决定了它在绘图区域中的位置。对于某些图表,点的 X 值并不重要,也不必提供。在这种情况下,绘图区域中的点位置仅由它们的点索引(即它们在点集合中的位置)和它们的 Y 值确定。

当 X 值被“索引”时,数据点索引,而不是点的 X 值,用于确定点沿分类 (X) 轴的位置。例如,在下面的图 1 中,两个图表显示了相同的数据。但是,第一个图表使用非索引 X 值,因此这些点的 X 值确定它们沿 x 轴的位置。第二个图表是索引的,因此它的点索引用于确定它们沿 x 轴的位置。在这种情况下,X 值仅用于轴标签,仅此而已。

http://support2.dundas.com/onlinedocumentation/winchart2005/Data_IndexedXValues.html

我在以下站点获取了有关间隔和间隔偏移的原始信息:

http://support2.dundas.com/Default.aspx?article=705

在这里,它讨论了数据类型并解决了突出显示值的问题。

在每个日期,都会为所有系列输入一个新点,但只有那些具有重要价值的点才会突出显示

例如,假设您希望创建一个重复出现的 StripLine 来突出显示周末。您将时间间隔设置为 7,并将其类型设置为天。由于第一点是星期日,因此您将 IntervalOffset 设置为 6(表示一周的第 6 天)并将其类型设置为 Days。结果图表不显示第一条带状线。

这是设置间隔的说明。

使用图表的 Interval 和 IntervalOffset 属性时要遵循的一个好的经验法则是,IntervalOffset 的间隔幅度应低于 Interval(即 Interval Days / IntervalOffset Hours、Interval Years / IntervalOffset Months 等)。

我添加了这些来源:

  1. 供你参考
  2. 为了表明我在确定问题后也进行了研究,如我在上面的评论中所述。

Florian,您能否显示 x 轴的标签、属性等代码?– yvytty 昨天

您是否考虑过 3rd 方绘图组件,例如 ZedGraph ?很可能这些小警告已经包含在那里。试一试!– 昨天的新利斯克

作为对 ZedGraph 的回应,我建议:

并且:查看您的代码后

嗨,我可以澄清一下,您想每天绘制值吗?我想我有你的解决方案,只需要澄清一下, 你有 vb.net 中的所有工具

@yvytty,不,日期不必是每天,也可能长时间没有价值,我不希望图表中没有数据的地方有很大的跨度。实际上,我也可以在 X 轴值处写一些示例文本,日期只是令人困惑。主要问题是VB图表以某种方式在X轴上的这些描述上计算了一个非常大的边距

它没有显示您已格式化日期和日期字符串。还需要考虑的是,您没有使用 en-US 日期格式(我在澳大利亚,所以我们的格式与您相同)。默认日期类型为 en-US。

请参考DateTime.ParseExact方法

http://msdn.microsoft.com/en-us/library/system.datetime.parseexact.aspx

我从 MSDN 中获取了片段。

 Dim dateString, format As String   
 Dim result As Date 
 Dim provider As CultureInfo = CultureInfo.InvariantCulture

 Parse date and time with custom specifier.
 dateString = "Sun 15 Jun 2008 8:30 AM -06:00"
 format = "ddd dd MMM yyyy h:mm tt zzz"         
 result = Date.ParseExact(dateString, format, provider)

见链接:http: //msdn.microsoft.com/en-us/library/w2sa9yss.aspx

DateTime.ToString(IFormatProvider) 方法使用特定区域性的短日期和长时间模式返回日期和时间值的字符串表示形式。下面的示例使用 DateTime.ToString(IFormatProvider) 方法使用 fr-FR 区域性的短日期和长时间模式来显示日期和时间。

Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 01/03/2008 07:00:00

请参阅此链接:http: //msdn.microsoft.com/en-us/library/system.datetime.aspx

所以它应该去,像这样:

'note
Imports System.Globalization

Dim format as String = "dd.MM.yyyy"
Dim actualDate as Date = Date.ParseExact(yourDate, format, provider)

chart.ChartAreas(0).AxisX.LabelStyle.Format ="dd.MM.yyyy"

cht_main.ChartAreas(0).AxisX.IntervalType = DateTimeIntervalType.Days

cht_main.ChartAreas(0).AxisX.Interval = 1

还:

Double.Parse(grade("GRADE")
'grade is not of type double
于 2013-05-29T06:39:02.450 回答
4

我认为您应该在将字符串日期表示形式添加到图表之前将其转换为实际的日期时间对象。我没有测试它,但是像这样:(yourDate你用来传递给图表的字符串在哪里)

Dim format as String = "MM.dd.yyyy"
Dim actualDate as Date = Date.ParseExact(yourDate, format)
chart.Series(chart.Series.Count - 1).Points.AddXY(actualDate, 4.9)

该图表可以管理日期时间对象而不是字符串,并且它具有处理日期的特殊代码。如果你这样做,你可以通过格式化来调整它的显示方式:

chart.ChartAreas(0).AxisX.LabelStyle.Format ="MM.dd.yyyy"
chart.ChartAreas(0).AxisX.Interval = 1
chart.ChartAreas(0).AxisX.IntervalType = DateTimeIntervalType.Days

如果您只想每隔一天显示一次,请将间隔更改为 2

于 2013-05-28T13:30:40.707 回答