Microsoft Chart Control generates a different visual then the set property. Property based it always shows correct value but if you open the generated chart with graphic software like Photoshop it shows pixels are not matching with the set property.
I found this bug while trying to retrieve all InnerPlot Positions into a HiddenField. Based on this bug right now, there is no way to get correct absolute position of ChartAreas or InnerPlots. Please let me know if you believe there is a workaround about it...
Thank you for your time and attention...
STEPS TO REPRODUCE
Test.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Test.aspx.vb" Inherits="Test" %>
<%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Chart ID="Chart1" runat="server"></asp:Chart>
</div>
</form>
</body>
</html>
Test.aspx.vb
Imports System.Web.UI.DataVisualization.Charting
Partial Class Test
Inherits System.Web.UI.Page
Private Sub DataHelper()
Dim Historical() As String = _
{ _
"Date,Open,High,Low,Close,Volume", _
"2009-03-05,1.75,2.00,1.73,1.81,47339300", _
"2009-03-04,1.90,1.90,1.83,1.87,22306600", _
"2009-03-03,1.91,1.91,1.80,1.81,15412400", _
"2009-03-02,1.91,1.94,1.83,1.88,19585500", _
"2009-02-27,1.93,2.00,1.80,2.00,31469500", _
"2009-02-26,2.08,2.09,1.81,1.98,32307100", _
"2009-02-25,2.10,2.16,2.00,2.01,54325200", _
"2009-02-24,1.80,2.00,1.80,2.00,33935300", _
"2009-02-23,1.65,1.91,1.61,1.73,44444100", _
"2009-02-20,1.60,1.61,1开发者_开发知识库.50,1.58,37889100" _
}
Dim Query As IEnumerable = From HistoricalLine In Historical Skip 1 _
Where Not String.IsNullOrEmpty(HistoricalLine) _
Let HistoricalFields = HistoricalLine.Split(",") _
Let HistoricalDate = CDate(HistoricalFields(0)) _
Order By HistoricalDate Ascending _
Select New With { _
.Date = HistoricalDate, _
.Open = CDbl(HistoricalFields(1)), _
.High = CDbl(HistoricalFields(2)), _
.Low = CDbl(HistoricalFields(3)), _
.Close = CDbl(HistoricalFields(4)), _
.Volume = CDbl(HistoricalFields(5)) _
}
Chart1.DataSource = Query
End Sub
Private Sub CreateChartArea(ByVal areaname As String)
Chart1.ChartAreas.Add(New ChartArea)
With Chart1.ChartAreas.Last
.Name = areaname
.AxisY2.Enabled = AxisEnabled.False
.AxisX2.Enabled = AxisEnabled.False
With .AxisX
.MajorTickMark.Enabled = False
.MinorTickMark.Enabled = False
.MinorGrid.Enabled = False
.MajorGrid.LineColor = Drawing.Color.Yellow
End With
With .AxisY
.MajorTickMark.Enabled = False
.MinorTickMark.Enabled = False
.MinorGrid.Enabled = False
.MajorGrid.LineColor = Drawing.Color.Red
.IsStartedFromZero = False
End With
.BackColor = Drawing.Color.SkyBlue
.BorderDashStyle = ChartDashStyle.Solid
.BorderColor = Drawing.Color.Brown
.BorderWidth = 0
.ShadowOffset = 0
End With
End Sub
Private Sub CreateSeries(ByVal seriename As String, ByVal areaname As String)
Chart1.Series.Add(New Series)
With Chart1.Series.Last
.Name = seriename
.ChartArea = areaname
.YValuesPerPoint = 4
.ChartType = SeriesChartType.Candlestick
.XValueType = ChartValueType.DateTime
.IsXValueIndexed = True
.XValueMember = "Date"
.YValueMembers = "High,Low,Open,Close"
.BorderColor = Drawing.Color.Green
.IsValueShownAsLabel = True
End With
End Sub
Private Sub ChartHelper()
Chart1.ImageStorageMode = ImageStorageMode.UseImageLocation
Chart1.ImageLocation = "~/_temp/HG_#SEQ(300,60)" '<= make sure you have "_temp" directory
Chart1.ImageType = ChartImageType.Png
Chart1.RenderType = RenderType.ImageTag
Chart1.Titles.Add(New Title())
Chart1.Legends.Add(New Legend())
Chart1.Legends.Last.Enabled = False
Chart1.Palette = ChartColorPalette.BrightPastel
Chart1.BackColor = Drawing.Color.Pink
CreateChartArea("A1")
CreateSeries("S1", "A1")
CreateChartArea("A2")
CreateSeries("S2", "A2")
CreateChartArea("A3")
CreateSeries("S3", "A3")
CreateChartArea("A4")
CreateSeries("S4", "A4")
Chart1.DataBind()
Chart1.SaveXml(Server.MapPath("~/_temp/MyChart.xml"))
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
DataHelper()
ChartHelper()
TestPart()
End If
End Sub
Private Sub TestPart()
Dim SpaceBetweenChartAreas As Single = 1 '<= %1 of Chart's Height
Chart1.Height = 500
Chart1.Width = 1000
Dim locator As Integer = 0
For Each chartareaItem In Chart1.ChartAreas
With chartareaItem
.Position.Auto = False
.Position.Height = 20 '500px/100*20 = 100px
.Position.Width = 80 '1000px/100*80 = 800px
.Position.X = 0
.Position.Y = locator
.InnerPlotPosition.Auto = False
.InnerPlotPosition.Height = 100 '%100 of ChartArea Position's Height
.InnerPlotPosition.Width = 100 ' %100 of ChartArea Position's Width
.InnerPlotPosition.X = 0
.InnerPlotPosition.Y = 0
locator += SpaceBetweenChartAreas + .Position.Height
End With
Next
End Sub
End Class
Please don't forget to create a directory "_temp"
Also you can see the actual result at http://ilerler.com/-bug4ms/Test.pngRESULTS
1st ChartArea Height
ACTUAL 101px | EXPECTED 100px space ACTUAL 4px | EXPECTED 5px 2nd ChartArea Height ACTUAL 101px | EXPECTED 100px space ACTUAL 4px | EXPECTED 5px 3rd ChartArea Height ACTUAL 100px | EXPECTED 100px space ACTUAL 4px | EXPECTED 5px 4th ChartArea Height ACTUAL 101px | EXPECTED 100px space ACTUAL 85px | EXPECTED 85pxYou have the following line:
Dim SpaceBetweenChartAreas As Single = 1 '<= %1 of Chart's Height
That means that your calculations are being performed with single precision float point values - which are highly susceptible to rounding errors.
At the very least you should use Double
values.
精彩评论