【问题标题】:Chart: Show more value descriptions on X-Axis图表:在 X 轴上显示更多值描述
【发布时间】:2013-05-18 12:29:35
【问题描述】:

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

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

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

实际上是这样的(描述实际上是字符串,而不是日期)。

感谢您的帮助!

编辑:我的代码:

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

EDIT2:

Skippy's 回答和评论后,我的新试用。变量MainForm.grades 是一个Dictionary(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的解决方案

【问题讨论】:

  • 您是否考虑过 3rd 方绘图组件,例如 ZedGraph?很可能这些小警告已经包含在那里。试一试!
  • @yvytty,我已经用我的代码编辑了我的答案。
  • @Neolisk,我还没有尝试,因为我实际上只使用基本的VB并且我尝试不使用库,但是如果它们不超重,我会尽快看看; )
  • @yvytty,不,日期不必是每天,也可能长时间没有价值,我不希望图表中有大跨度没有数据。实际上,我也可以在 X 轴值处写一些示例文本,日期只是令人困惑。主要问题是 VB 图表以某种方式在 X 轴上的这些描述上计算了一个非常大的边距。
  • @yvytty 取决于你的回答是否真的回答了我公认的复杂问题;)

标签: vb.net for-loop multidimensional-array charts axis-labels


【解决方案1】:

我认为您应该在将字符串日期表示形式添加到图表之前将其转换为实际的日期时间对象。 我没有测试它,但是像这样:(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

【讨论】:

  • 我也试过了,但问题是在这种情况下,随机日期将显示在 X 轴上——不仅仅是在上图中有一个点的日期。正如我所提到的,日期令人困惑 - 假设有“值 1”和“值 2”而不是日期。
  • 我想如果你只是将系列设置为mySeries.XValueIndexed = True 它会得到你想要的
【解决方案2】:

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

通过设置间隔:

myStripLine1.IntervalOffset = 4

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

将此值设置为 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 值并不重要,也不必提供。在这种情况下,绘图区域中的点位置仅由它们的点索引(即它们在 Points 集合中的位置)和它们的 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. 为了表明我在确定问题后也进行了研究,如上面我的 cmets 所述。

弗洛里安,你能显示 x 轴的标签、属性等的代码吗? – yvytty 昨天

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

针对 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 获取了 sn-ps。

 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

【讨论】:

  • XValueIndexed 是错误的。命令是Chart1.Series(0).IsXValueIndexed = True
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 2020-10-31
  • 2020-11-23
  • 2017-11-22
相关资源
最近更新 更多