سؤال

A chart on a form I created has two overlapping areas. The overlapping part works just fine. The problem is that visible graph only takes up half the height of the chart control:

enter image description here

The bottom half of the control is left empty (presumably because that's where the second area would have gone were the two areas not aligned?). I can't figure out how to get the chart to use the entire control. The code is below:

        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));
هل كانت مفيدة؟

المحلول

This is some old code I've dug out and modified to suit your example. The problem is the InnerPlotPosition.Auto and Position.Auto status of the ChartAreas, thats why after you add the second chart the first charts auto position jumps up and then the second chart aligns with the new InnerPlotPosition.Auto values.

You can try turning this off but I think its easier to just position the first chart manually and then allow the second to align with the new manual position. It produces the below image (minus your legend you can work the values needed yourself)

Bit of pain in the ass solution but hopefully it helps

chart image

    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

نصائح أخرى

I thought about monkeying with the position, but I'd have to take into account borders and the legend and other chart components and assumed I'd never get it as good as the auto-positioning provided by the chart - and it would drive me nuts. However, the suggestion by TylerDurden led me to the idea of simply delaying the addition of the second series/area until after the chart had rendered at least once and had calculated the position. This turned out to be non-trivial, since for most of the chart's initialization the X, Y, Height and Width are still zero. The best way I found was to add the second series in the Form's Shown event:

    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

The call to Application.DoEvents() is required to force the chart to render and calculate the Position. Since Position is a percentage, both chart areas will always occupy the full height and width of the parent Chart.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top