65.9K
CodeProject 正在变化。 阅读更多。
Home

Office Web Components - 折线图(X 轴为日期)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (2投票s)

2009年9月6日

CPOL

4分钟阅读

viewsIcon

51949

downloadIcon

1936

这是一篇关于在 Office Web Components 中使用线性图表,其中日期用作 X 轴的文章。

Sample Image - maximum width is 600 pixels

引言

最近,我需要在一个 Windows 应用程序中绘制图表。该图表是一个普通的线性图表,X 轴为日期,Y 轴为价格(十进制)。搜索了一段时间后,我找到了 Office Web Components,我认为这应该适合我的需求。因为这是我在 OWC 中的第一次尝试,所以我花了大量时间构建 X 轴(日期),而 OWC 给了我一些奇怪的结果。(Y 值被绘制出来,但每 7 天累加一次。)

在仔细搜索和研究网上仅有的几个离散示例后,我解决了这些问题,并且正在撰写一篇文章来总结我的发现。

背景

Office Web Components 是用于将电子表格、图表和数据库发布到 Web 的组件对象模型 (COM) 控件的集合。但它也可以用于 Windows 应用程序。您可以从 Microsoft 下载中心下载它。

安装后,您必须将名为 (Microsoft Office Web Components 11.0) 的引用添加到您的项目以及工具箱中。

Using the Code

虽然我在 Visual Studio 2008 中构建了我的项目,但与 OWC 相关的代码绝对适用于 .NET 2.0。我将在此处描述构建线性图表的整个过程。

准备源数据

准备数据并将其馈送到 OWC 有不同的方法。许多示例使用逗号分隔的值,例如 Jan,Feb。但是,我更喜欢使用数组,您可以使用函数 `SetData` 将对象数组设置到序列。(嗯,它必须是对象数组,其他类型的数组不起作用!)

假设您有图表值,则必须将其转换为对象数组。(我很懒,所以我使用 LINQ。)
为什么我使用 yyyy-MM-dd 作为格式?答案很简单,我不希望 OWC 混淆 dd/MM/yyyy 和 mm/dd/yyyy。

Dim XValues As New List(Of DateTime)
Dim YValues As New List(Of Double)
Dim xObjects, yObjects As Object()
Dim tmp = From x In XValues Select CObj(x.ToString("yyyy-MM-dd"))
xObjects = tmp.ToArray()
Dim tmp2 = From y In YValues Select CObj(y)
yObjects = tmp2.ToArray()

我更喜欢手动计算图表的 Y 轴的最大值和最小值。

'Determine maxima and minima of Y
Dim yMax As Decimal = YValues.Max()
Dim yMin As Decimal = YValues.Min()
yMin = Math.Floor(yMin / 10) * 10 'Round the minimum to standard number
yMax = Math.Ceiling(yMax / 10) * 10 'Round the maximum to standard number

创建图表主体

在 Windows 应用程序中,从工具箱中拖出一个名为 Microsoft Office Chart 11.0 的控件,它应该在表单中命名为 `AxChartSpace1`。

使用以下代码删除控件中的图表。(为什么没有 `Clear()` 方法?)

If AxChartSpace1.Charts.Count > 0 Then AxChartSpace1.Charts.Delete(0)

以下代码准备图表主体。(对不起,我将在此处使用大量的 `With` 语句。)

Dim chart As ChChart = AxChartSpace1.Charts.Add()
With chart
.HasTitle = True
.Title.Caption = "Line Graph using date in x-axis"
.Title.Font.Name = "Arial"
.Type = ChartChartTypeEnum.chChartTypeSmoothLine
.PlotArea.Interior.SetSolid("White")
End With

系列文章

我们将使用 `SetData` 命令设置序列数据(X、Y 值数据)。
对于 X 轴,使用 `ChartDimensionsEnum.chDimCategories`。
对于 Y 轴,使用 `ChartDimensionsEnum.chDimValues`。
然后在此处放置您之前创建的 X、Y 对象值。

Dim series As ChSeries series = chart.SeriesCollection.Add(0)
With series
.Name = "Series 1"
.Caption = "Caption 1"
.SetData(ChartDimensionsEnum.chDimCategories, _
	ChartSpecialDataSourcesEnum.chDataLiteral, xObjects)
.SetData(ChartDimensionsEnum.chDimValues, _
	ChartSpecialDataSourcesEnum.chDataLiteral, yObjects)
.Line.Color = "Blue"
.Line.Weight = LineWeightEnum.owcLineWeightThin
End With

数据标签

有时您想向图表添加数据标签或标记。

With series
.DataLabelsCollection.Add()
.DataLabelsCollection(0).Font.Name = "Verdana"
.DataLabelsCollection(0).Font.Size = 8

.Marker.Style = ChartMarkerStyleEnum.chMarkerStyleCircle
.Marker.Size = 6
End With

配置 X 轴(重要)

回想一下,当使用日期作为 X 轴时,我遇到一个奇怪的问题。问题是 Y 值每 7 天都累加在一起。这种奇怪的行为实际上可以在 X 轴中手动调整,修改 `GroupingType`、`GroupingUnit` 和 `GroupingTotalFunction` 属性后。默认的 `GroupingUnit` 为 1 周,`GroupingTotalFunction` 为 SUM。这就是为什么在预先没有设置任何内容时会产生这种行为的原因。

我看到许多 Web 示例使用 `chart.Axes(0)` 作为 X 轴。就我个人而言,我不习惯它,请改用 `chart.Axes(ChartAxisPositionEnum.chAxisPositionCategory)`。

此外,为了避免 X 轴上的刻度过于密集,您可以将刻度设置为每周显示,而不是每天显示。

With chart.Axes(ChartAxisPositionEnum.chAxisPositionCategory)
.HasTitle = True
.Title.Caption = "Date"
.Title.Font.Name = "Arial"
.Title.Font.Size = 8
.Font.Size = 8
.Font.Name = "Arial"
.NumberFormat = "dd/MM/yy"

.GroupingType = ChartAxisGroupingEnum.chAxisGroupingManual
.GroupingUnitType = ChartAxisUnitTypeEnum.chAxisUnitDay
.GroupingUnit = 1
.GroupingTotalFunction = ChartGroupingTotalFunctionEnum.chFunctionAvg

.TickLabelUnitType = ChartAxisUnitTypeEnum.chAxisUnitWeek
.TickMarkUnitType = ChartAxisUnitTypeEnum.chAxisUnitWeek
End With

配置 Y 轴

Y 轴很简单,在此处放置您之前计算的最大值和最小值。另外,设置主网格线和次网格线。

对于 Y 轴,使用 `chart.Axes(ChartAxisPositionEnum.chAxisPositionValue)`。

With chart.Axes(ChartAxisPositionEnum.chAxisPositionValue)
.HasTitle = True
.Title.Caption = "Price"
.Title.Font.Name = "Arial"
.Title.Font.Size = 8
.Font.Size = 8
.Font.Name = "Arial"

.Scaling.Maximum = yMax
.Scaling.Minimum = yMin

.MajorUnit = 50
.MajorGridlines.Line.Color = "Gray"

.MinorUnit = 10
.MinorGridlines.Line.Color = "LightGray"
.MinorGridlines.Line.DashStyle = ChartLineDashStyleEnum.chLineSolid
.HasMinorGridlines = True
End With

完成并导出

如果配置正确,您应该会看到一个线性图表,每天绘制一个数据点,并且 X 轴刻度标签为每周。如果您想将图表导出到文件,Microsoft 提供了一种简单的方法,可以使用以下代码。您可以设置渲染文件格式(JPG、GIF)和图像大小。

Dim filePath As String = System.IO.Path.GetTempFileName() & ".gif"
Dim chartBytes As Byte() = AxChartSpace1.GetPicture("GIF", 1280, 960)
System.IO.File.WriteAllBytes(filePath, chartBytes) 'Save to image

Dim process As New System.Diagnostics.Process()
process.Start(filePath)

关注点

我知道一开始使用 OWC 很困难,因为 OWC 的函数和属性都没有注释。有时,我必须打开 Microsoft Excel 才能理解它的含义。此外,我努力将本文中常用的属性包含在内,并希望它能帮助 OWC 的初学者。

如果您使用的是 .NET 3.5,则可以尝试“Microsoft Chart Controls for Microsoft .NET Framework 3.5”,这是 Microsoft 编写的新的图表控件。

这是我在 CodeProject 上的第一篇文章。过去我从 CodeProject 学到了很多东西,这次我想把我的一些发现贡献给大家。

历史

  • 2009 年 9 月 6 日:首次发布
© . All rights reserved.