位置值与实际值不符

发布于 2024-10-04 15:08:37 字数 7091 浏览 3 评论 0原文

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
enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

画骨成沙 2024-10-11 15:08:37

您有以下行:

Dim SpaceBetweenChartAreas As Single = 1 '<= %1 of Chart's Height

这意味着您的计算正在使用单精度浮点值执行 - 这很容易受到舍入误差的影响。

至少您应该使用 Double 值。

You 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文