【问题标题】:Windows Forms chart with two aligned/overlapping areas don't use the entire control具有两个对齐/重叠区域的 Windows 窗体图表不使用整个控件
【发布时间】:2014-03-14 01:19:03
【问题描述】:

我创建的表格上的图表有两个重叠区域。重叠部分工作得很好。问题是可见图只占图表控件高度的一半:

控件的下半部分是空的(大概是因为如果两个区域没有对齐,第二个区域会去哪里?)。我不知道如何让图表使用整个控件。代码如下:

        chart1.Dock = DockStyle.Fill;
        chart1.Legends.Add(new Legend { Name = "Legend1" });
        chart1.Location = new Point(435, 3);
        chart1.Name = "chart1";
        chart1.Size = new Size(426, 287);
        chart1.TabIndex = 2;
        chart1.Text = "chart1";

        var firstArea = chart1.ChartAreas.Add("First Area");
        var seriesFirst = chart1.Series.Add("First Series");
        seriesFirst.ChartType = SeriesChartType.Line;

        seriesFirst.Points.Add(new DataPoint(10, 55));
        seriesFirst.Points.Add(new DataPoint(11, 56));
        seriesFirst.Points.Add(new DataPoint(12, 59));

        var secondArea = chart1.ChartAreas.Add("Second Area");
        secondArea.BackColor = Color.Transparent;
        secondArea.AlignmentOrientation = AreaAlignmentOrientations.All;
        secondArea.AlignmentStyle = AreaAlignmentStyles.All;
        secondArea.AlignWithChartArea = firstArea.Name;
        secondArea.AxisY.LabelStyle.Enabled = false;
        secondArea.AxisX.LabelStyle.Enabled = false;

        var seriesSecond = chart1.Series.Add("Second Series");
        seriesSecond.ChartType = SeriesChartType.Line;
        seriesSecond.ChartArea = secondArea.Name;

        seriesSecond.Points.Add(new DataPoint(10, 1001));
        seriesSecond.Points.Add(new DataPoint(11, 1015));
        seriesSecond.Points.Add(new DataPoint(12, 1016));

【问题讨论】:

    标签: windows forms charts mschart


    【解决方案1】:

    这是我挖掘并修改以适合您的示例的一些旧代码。问题是ChartAreasInnerPlotPosition.AutoPosition.Auto 状态,这就是为什么在添加第二个图表后,第一个图表自动位置会上升,然后第二个图表与新的InnerPlotPosition.Auto 值对齐。

    您可以尝试将其关闭,但我认为手动定位第一个图表然后让第二个图表与新的手动位置对齐更容易。它会生成下面的图像(减去您的图例,您可以自己处理所需的值)

    解决方案有点痛苦,但希望能有所帮助

        Dim chart1 As New Chart
        Me.Controls.Add(chart1)
    
        chart1.Location = New Point(435, 3)
        chart1.Name = "chart1"
        chart1.Size = New Size(426, 287)
        chart1.TabIndex = 2
        chart1.Text = "chart1"
    
        Dim firstArea As ChartArea = chart1.ChartAreas.Add("First Area")
        Dim seriesFirst = chart1.Series.Add("First Series")
        seriesFirst.ChartType = SeriesChartType.Line
    
        seriesFirst.Points.Add(New DataPoint(10, 55))
        seriesFirst.Points.Add(New DataPoint(11, 56))
        seriesFirst.Points.Add(New DataPoint(12, 59))
    
        Dim secondArea As ChartArea = chart1.ChartAreas.Add("Second Area")
        secondArea.BackColor = Color.Transparent
        secondArea.AlignmentOrientation = AreaAlignmentOrientations.All
        secondArea.AlignmentStyle = AreaAlignmentStyles.All
        secondArea.AlignWithChartArea = firstArea.Name
        secondArea.AxisY.LabelStyle.Enabled = False
        secondArea.AxisX.LabelStyle.Enabled = False
    
        Dim seriesSecond = chart1.Series.Add("Second Series")
        seriesSecond.ChartType = SeriesChartType.Line
        seriesSecond.ChartArea = secondArea.Name
    
        seriesSecond.Points.Add(New DataPoint(10, 1001))
        seriesSecond.Points.Add(New DataPoint(11, 1015))
        seriesSecond.Points.Add(New DataPoint(12, 1016))
    
    
        ' *** Set locational values here for your first chart***
        Dim heightAboveChartArea As Integer = 20
        Dim heightBelowChartArea As Integer = 20
        Dim axisLabelHeight As Integer = 40
        Dim widthLeftOfChartArea As Integer = 20
        Dim widthRightOfChartArea As Integer = 20
        Dim heightPerBar As Integer = 20
        Dim numberOfPoints As Integer = chart1.Series(0).Points.Count
    
        ' *** The following code should not normally be modified ***
        chart1.Height = heightAboveChartArea + heightBelowChartArea + axisLabelHeight + (numberOfPoints * heightPerBar)
    
        chart1.ChartAreas(0).Position.X = widthLeftOfChartArea / chart1.Width * 100
        chart1.ChartAreas(0).Position.Width = 100 - (widthRightOfChartArea / chart1.Width * 100) - chart1.ChartAreas(0).Position.X
        chart1.ChartAreas(0).Position.Y = (heightAboveChartArea / chart1.Height * 100)
        chart1.ChartAreas(0).Position.Height = 100 - (heightBelowChartArea / chart1.Height * 100) - chart1.ChartAreas(0).Position.Y
    

    【讨论】:

      【解决方案2】:

      我考虑过调整位置,但我必须考虑边框、图例和其他图表组件,并假设我永远不会像图表提供的自动定位一样好 - 而且它会让我发疯的。然而,TylerDurden 的建议让我想到了将第二个系列/区域的添加简单地延迟到 图表至少渲染一次并计算出位置之后。事实证明这是不平凡的,因为对于大多数图表的初始化,X、Y、高度和宽度仍然为零。我发现最好的方法是在 Form 的 Shown 事件中添加第二个系列:

          private void OnShown(object sender, EventArgs eventArgs)
          {
              Application.DoEvents();
      
              var f = chart1.ChartAreas[0].Position.ToRectangleF();
      
              chart1.ChartAreas[0].Position.Auto = false;
              chart1.ChartAreas[0].Position.X = f.X;
              chart1.ChartAreas[0].Position.Y = f.Y;
              chart1.ChartAreas[0].Position.Height = f.Height;
              chart1.ChartAreas[0].Position.Width = f.Width;
      
              // add second area/series here
      

      需要调用 Application.DoEvents() 来强制图表呈现和计算位置。由于 Position 是一个百分比,因此两个图表区域将始终占据父图表的全部高度和宽度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 2016-06-30
        • 1970-01-01
        相关资源
        最近更新 更多