vb.net 图表:在 X 轴上显示更多值说明
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16708974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chart: Show more value descriptions on X-Axis
提问by Florian Müller
I'm showing a Chart to the user which has one chart area with a line chart. On this, I got, for example, one line. This line has about 200 values. Those values do all have a description (e.g. "01.01.2013"
, "05.02.2013"
and so on).
我正在向用户显示一个图表,其中有一个带有折线图的图表区域。例如,在这一点上,我得到了一行。该行有大约 200 个值。这些值都有一个描述(例如"01.01.2013"
,"05.02.2013"
等等)。
When the Chart is shown, I can only see two descriptions, even if there would be space for much more descriptions. The line gets displayed correctly, but there are only two points described.
当图表显示时,我只能看到两个描述,即使会有更多描述的空间。该线显示正确,但只描述了两点。
I rotated the Text vertically so there is more space, but this didn't help. If I display less values (5 or 10), the descriptions get shown correctly.
我垂直旋转了文本,因此有更多空间,但这没有帮助。如果我显示较少的值(5 或 10),说明会正确显示。
This is how it actually looks like (the descriptions are actually Strings, not Dates).
这就是它的实际外观(描述实际上是字符串,而不是日期)。
Thank you for your help!
感谢您的帮助!
EDIT: My Code:
编辑:我的代码:
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)
On every date, a new point gets entered for all series, but only those points where they have important values get highlighted. Those values between are calculated mathematically.
在每个日期,都会为所有系列输入一个新点,但只有那些具有重要值的点才会突出显示。之间的那些值是通过数学计算得出的。
One example to explain this: I got two series, one has two values (6 and 4) on point "01.01.2013"
and "03.01.2013"
. The other series has 3 values (4,6,5.5) on "01.01.2013"
,"02.01.2013"
and "03.01.2013"
. When I just display them, the first series will end at the second date, even if there was a value for the third date. I solved this by filling a dummy value at the first series with date "02.01.2013"
which is just the average at this point (=5). This point simply does not get highlighted with a marker bullet. This is how I draw my graph.
一个解释这个的例子:我有两个系列,一个在点"01.01.2013"
和上有两个值(6 和 4)"03.01.2013"
。另一系列有3个值(4,6,5.5)上"01.01.2013"
,"02.01.2013"
和"03.01.2013"
。当我只显示它们时,第一个系列将在第二个日期结束,即使第三个日期有一个值。我通过在第一个系列中填充一个虚拟值来解决这个问题,日期"02.01.2013"
只是此时的平均值 (=5)。这一点根本不会用标记项目符号突出显示。这就是我绘制图形的方式。
EDIT2:
编辑2:
After Skippy's answer and comment, my new trial. The variable MainForm.grades
is a Dictionary(Of Integer,Dictionary(Of String, String))
which contains around 150 grades
在Skippy 的回答和评论之后,我的新审判。变量MainForm.grades
是Dictionary(Of Integer,Dictionary(Of String, String))
包含大约 150 个等级的 a
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
On the 5th last row I commented IsXValueIndexed=True
because when I activated it, the chart gets generated with a big red error cross.
在最后一行的第 5 行我进行了评论,IsXValueIndexed=True
因为当我激活它时,图表会生成一个大的红色错误十字。
SOLUTION
解决方案
Setting the Interval on the X-Axis does the trick!
在 X 轴上设置间隔就行了!
chart.ChartAreas(0).AxisX.Interval = 1
Solution by Skippy
Skippy的解决方案
回答by Yvette
Yes I agree with Michael. I can only add to the explanation at this point.
是的,我同意迈克尔的看法。我现在只能补充说明。
By setting your interval:
通过设置您的间隔:
myStripLine1.IntervalOffset = 4
You are guaranteeing that your X-axis values will be plotted only, at frequency of 4 " generic x-axis" values:
您保证仅以 4 个“通用 x 轴”值的频率绘制您的 X 轴值:
Setting this to vale to 1 will give a value for every x-axis value, that is incremented as a whole number (in this case days)
将此设置为 vale 为 1 将为每个 x 轴值提供一个值,即作为整数递增(在这种情况下为天)
chart.ChartAreas(0).AxisX.Interval = 1
And to declare the x-axis values to type:
并声明要键入的 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)
As mentioned by Michael in his comment. By setting the
正如迈克尔在他的评论中提到的。通过设置
mySeries.XValueIndexed = True
Every indexed X-axis value will be plotted.
将绘制每个索引的 X 轴值。
As explained in the following quote, with the link provided.
如以下引用中所述,并提供了链接。
Each data point in a series has X and Y values that determine its position in the plotting area. With some charts, the X value of points is not important, and does not have to be provided. In this case, the point positions in the plotting area are determined only by their point index (i.e. their location in the Points collection) and their Y values.
When X values are "indexed", the data point index, not a point's X value, is used to determine the position of points along the categorical (X) axis. For example in Figure 1 below, two charts are shown displaying the same data. However, the first chart uses non-indexed X values, therefore the X values of those points determine their location along the x-axis. The second chart is indexed, therefore its point indices are used to determine their position along the x-axis. In this case the X values are only used for the axis labels, and nothing more.
系列中的每个数据点都有 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/onlinedocumentation/winchart2005/Data_IndexedXValues.html
I sourced my original information regarding intervals and interval offsets at the following site:
我在以下站点获取了有关间隔和间隔偏移的原始信息:
http://support2.dundas.com/Default.aspx?article=705
http://support2.dundas.com/Default.aspx?article=705
Here it discusses datatype and addresses your issue of highlighted values.
此处讨论了数据类型并解决了突出显示值的问题。
On every date, a new point gets entered for all series, but only those points where they have important values get highlighted
For example, assume you wish to create a re-occurring StripLine to highlight weekends. You set the interval to 7 and its type to Days. Since the first point is Sunday you set the IntervalOffset to 6 (to mean the 6th day of the week) and its type to Days. The resulting chart does not show the first StripLine.
在每个日期,所有系列都会输入一个新点,但只有那些具有重要值的点才会突出显示
例如,假设您希望创建一个重复出现的 StripLine 来突出显示周末。您将时间间隔设置为 7,并将其类型设置为天。由于第一个点是星期日,因此您将 IntervalOffset 设置为 6(表示一周的第 6 天)并将其类型设置为 Days。生成的图表不显示第一条带状线。
This is a an explanation for setting the interval.
这是设置间隔的说明。
A good rule of thumb to follow when using the Interval and IntervalOffset properties of the Chart is that the IntervalOffset should be a lower interval magnitude than the Interval (ie. Interval Days / IntervalOffset Hours, Interval Years / IntervalOffset Months, etc.).
使用图表的 Interval 和 IntervalOffset 属性时要遵循的一个很好的经验法则是,IntervalOffset 应该是比 Interval 更低的间隔幅度(即间隔天数/IntervalOffset 小时数、间隔年数/IntervalOffset 月数等)。
I have added these sources:
我添加了这些来源:
- For your reference
- To show I have, also, done my research after ascertaining the problem, as stated in my comments above.
- 供你参考
- 为了表明我也在确定问题后进行了研究,如我在上面的评论中所述。
Florian, can you pls show the code for the labels, properties etc of the x-axis? – yvytty yesterday
Did you ever consider 3rd party plotting components, such as ZedGraph ? Most likely such little caveats are already covered there. Give it a shot! – Neolisk yesterday
弗洛里安,你能显示 x 轴的标签、属性等的代码吗?– yvytty 昨天
你有没有考虑过 3rd 方绘图组件,比如 ZedGraph ?很可能这些小警告已经包含在那里。试一试!– 昨天的 Neolisk
In response to ZedGraph I advised:
针对 ZedGraph,我建议:
And: After viewing your code
并且:查看您的代码后
Hi can I clarify, you WANT to plot values daily? I think I have your solution, just need clarification,you have all the tools within vb.net
@yvytty, nope, the dates do not have to be daily, there can also be no value for a long time and I don't want a big span in my chart where no data is. Actually, I could also write some sample text at the X axis values, the dates are only confusing. The main problem is that the VB chart somehow calculates a very big margin on those descriptions at the X axis
嗨,我可以澄清一下,您想每天绘制值吗?我想我有你的解决方案,只需要澄清,你有 vb.net 中的所有工具
@yvytty,不,日期不一定是每天,也可能在很长一段时间内没有价值,我不希望图表中没有数据的大跨度。实际上,我也可以在 X 轴值上写一些示例文本,日期只是令人困惑。主要问题是 VB 图表以某种方式计算了 X 轴上这些描述的非常大的边距
It doesn't show that you have formatted your date and date string. There also needs to be taken into account, that you are not using the en-US date format (I'm in Australia, so we have the same format as you). The default date type is for en-US.
它并不表明您已格式化日期和日期字符串。还需要考虑的是,您没有使用 en-US 日期格式(我在澳大利亚,所以我们的格式与您相同)。默认日期类型为 en-US。
Please refer to DateTime.ParseExact
Method
请参考DateTime.ParseExact
方法
http://msdn.microsoft.com/en-us/library/system.datetime.parseexact.aspx
http://msdn.microsoft.com/en-us/library/system.datetime.parseexact.aspx
I have taken snippets from MSDN.
我从 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)
See link: http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx
请参阅链接:http: //msdn.microsoft.com/en-us/library/w2sa9yss.aspx
The DateTime.ToString(IFormatProvider) method returns the string representation of a date and time value using the short date and long time pattern of a specific culture. The following example uses the DateTime.ToString(IFormatProvider) method to display the date and time using the short date and long time pattern for the fr-FR culture.
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
Please see this link: http://msdn.microsoft.com/en-us/library/system.datetime.aspx
请参阅此链接:http: //msdn.microsoft.com/en-us/library/system.datetime.aspx
So it should go, something like this:
所以它应该是这样的:
'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
ALSO:
还:
Double.Parse(grade("GRADE")
'grade is not of type double
回答by Michael
I think you should convert the string date representation to an actual datetime object before adding it to the chart.
I didn't test it but something like this: (where yourDate
is the string you used to pass to the chart)
我认为您应该将字符串日期表示形式转换为实际的日期时间对象,然后再将其添加到图表中。我没有测试它,但类似这样的:(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)
The chart can manage datetime object instead of strings and it has special code that deals with dates. If you do this you you can adjust how it is displayed by formatting:
图表可以管理日期时间对象而不是字符串,并且它具有处理日期的特殊代码。如果您这样做,您可以通过格式调整它的显示方式:
chart.ChartAreas(0).AxisX.LabelStyle.Format ="MM.dd.yyyy"
chart.ChartAreas(0).AxisX.Interval = 1
chart.ChartAreas(0).AxisX.IntervalType = DateTimeIntervalType.Days
If you wanted to only display every other day change the interval to 2
如果您只想每隔一天显示一次,请将间隔更改为 2