位置值与实际值不符
Microsoft 图表控件生成与设置属性不同的视觉效果。基于属性的它始终显示正确的值,但如果您使用 Photoshop 等图形软件打开生成的图表,它会显示像素与设置的属性不匹配。
我在尝试将所有 InnerPlot 位置检索到 HiddenField 时发现了此错误。基于此错误,目前无法获得 ChartAreas 或 InnerPlots 的正确绝对位置。如果您认为有解决方法,请告诉我...
感谢您的时间和关注...
复制
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
的步骤请不要忘记创建目录“_temp”
您还可以在http://ilerler.com/-bug4ms/Test.png<查看实际结果/a>
结果
第一个图表区域高度
实际 101 像素 |预计 100 像素
空间
实际 4 像素 |预计 5 像素
第二张图表区域高度
实际 101 像素 |预计 100 像素
空间
实际 4 像素 |预计 5 像素
第三张图表区域高度
实际 100 像素 |预计 100 像素
空间
实际 4 像素 |预计 5 像素
第四张图区域高度
实际 101 像素 |预计 100 像素
空间
实际 85 像素 |预计 85 像素
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.png
RESULTS
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 85px
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您有以下行:
这意味着您的计算正在使用单精度浮点值执行 - 这很容易受到舍入误差的影响。
至少您应该使用
Double
值。You have the following line:
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.