gpt4 book ai didi

c# - 如何在左侧或右侧以不同比例向 MSChart 添加更多 Y 轴

转载 作者:行者123 更新时间:2023-11-30 14:23:50 29 4
gpt4 key购买 nike

我想为具有不同比例的图表添加 3 个 Y 轴。

我想得到一个 x 轴和不同的 y 轴。我像下面的代码那样做,但我想显示一个 y 轴,就像我附加的第二张图片一样。

到目前为止我的 C# 代码:

   private void checkBoxUseMultipleYAxis_CheckedChanged(object sender, EventArgs e)
{
if (checkBoxUseMultipleYAxis.Checked)
{
// Set custom chart area position
chart1.ChartAreas["ChartArea1"].Position = new ElementPosition(25, 10, 68, 85);
chart1.ChartAreas["ChartArea1"].InnerPlotPosition = new ElementPosition(10, 0, 90, 90);``



// Create extra Y axis for second and third series
CreateYAxis(chart1, chart1.ChartAreas["ChartArea1"], chart1.Series["Current"], 13, 8);
CreateYAxis(chart1, chart1.ChartAreas["ChartArea1"], chart1.Series["Capacity"], 22, 8);
}
else
{
// Set default chart areas
chart1.Series["Current"].ChartArea = "ChartArea1";
chart1.Series["Capacity"].ChartArea = "ChartArea1";

// Remove newly created series and chart areas
while (chart1.Series.Count > 3)
{
chart1.Series.RemoveAt(3);
}
while (chart1.ChartAreas.Count > 1)
{
chart1.ChartAreas.RemoveAt(1);
}

// Set default chart are position to Auto
chart1.ChartAreas["ChartArea1"].Position.Auto = true;
chart1.ChartAreas["ChartArea1"].InnerPlotPosition.Auto = true;

}
}
public void CreateYAxis(Chart chart, ChartArea area, Series series, float axisOffset, float labelsSize)
{
// Create new chart area for original series
ChartArea areaSeries = chart.ChartAreas.Add("ChartArea_" + series.Name);
areaSeries.BackColor = Color.Transparent;
areaSeries.BorderColor = Color.Transparent;
areaSeries.Position.FromRectangleF(area.Position.ToRectangleF());
areaSeries.InnerPlotPosition.FromRectangleF(area.InnerPlotPosition.ToRectangleF());
areaSeries.AxisX.MajorGrid.Enabled = false;
areaSeries.AxisX.MajorTickMark.Enabled = false;
areaSeries.AxisX.LabelStyle.Enabled = false;
areaSeries.AxisY.MajorGrid.Enabled = false;
areaSeries.AxisY.MajorTickMark.Enabled = false;
areaSeries.AxisY.LabelStyle.Enabled = false;
areaSeries.AxisY.IsStartedFromZero = area.AxisY.IsStartedFromZero;


series.ChartArea = areaSeries.Name;

// Create new chart area for axis
ChartArea areaAxis = chart.ChartAreas.Add("AxisY_" + series.ChartArea);
areaAxis.BackColor = Color.Transparent;
areaAxis.BorderColor = Color.Transparent;
areaAxis.Position.FromRectangleF(chart.ChartAreas[series.ChartArea].Position.ToRectangleF());
areaAxis.InnerPlotPosition.FromRectangleF(chart.ChartAreas[series.ChartArea].InnerPlotPosition.ToRectangleF());

// Create a copy of specified series
Series seriesCopy = chart.Series.Add(series.Name + "_Copy");
seriesCopy.ChartType = series.ChartType;
foreach (DataPoint point in series.Points)
{
seriesCopy.Points.AddXY(point.XValue, point.YValues[0]);
}

// Hide copied series
seriesCopy.IsVisibleInLegend = false;
seriesCopy.Color = Color.Transparent;
seriesCopy.BorderColor = Color.Transparent;
seriesCopy.ChartArea = areaAxis.Name;

// Disable drid lines & tickmarks
areaAxis.AxisX.LineWidth = 0;
areaAxis.AxisX.MajorGrid.Enabled = false;
areaAxis.AxisX.MajorTickMark.Enabled = false;
areaAxis.AxisX.LabelStyle.Enabled = false;
areaAxis.AxisY.MajorGrid.Enabled = false;
areaAxis.AxisY.IsStartedFromZero = area.AxisY.IsStartedFromZero;
areaAxis.AxisY.LabelStyle.Font = area.AxisY.LabelStyle.Font;

// Adjust area position
areaAxis.Position.X -= axisOffset;
areaAxis.InnerPlotPosition.X += labelsSize;

}
};

So I get output like this

but I want to adjust this output like this

最佳答案

这是一个有趣的问题,其中包含一段相当复杂的代码,它解决了一个我从未注意到的问题..

让我们先谈谈基础知识。

在图表中,您可以将多个系列的数据添加到同一区域。只要 y 值的范围或多或少相同,通常就没有问题。但如果不是,y 轴将缩放,以便所有值都适合图表区域。这意味着那些范围较小的系列将被压扁。这是一个例子:

enter image description here

除了橙色系列之外的所有 y 值不可读,我们还看到只有一个轴标题;如果它适用于所有系列,好的;但如果没有:最好把它排除在外..

(有时将 y 轴设置为对数会有所帮助,但通常这只会使事情变得困惑而根本没有帮助。)

这需要更多的轴。其实有一个 额外轴 内置 , 只是为了询问:每个图表区域可以有一个 初级 y 轴向左和另一个,称为 ' 中学 ' AxisY2向右。

您可以启用它并将一个系列与其关联:

chart1.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
chart1.Series[1].YAxisType = AxisType.Secondary;

这很好,效果很好。但是我们的示例需要 2 个以上的 y 轴。这正是您找到的代码所提供的。

我们先来看看结果:

enter image description here

这很好;现在我们可以看到范围与 0 - 30 有何不同至 0 - 120 , -20 - 30最后是 0 - 1200 .

但是随着所有轴都添加到左侧,它们离绘图区域越来越远。因此你的问题..

我发现扩展您找到的代码而不是从头开始编写更好的版本最容易。这意味着代码的大多数问题仍然存在:
  • 未模块化
  • 例程依赖于“魔法”值
  • 通过反复试验找到这些值很乏味

  • 我在 CreateYAxis 中添加了两个参数方法;一个设置添加的轴区域的宽度,另一个切换将它们添加到左侧或右侧。

    我们先看一下结果:
    enter image description here

    现在对于更改的代码:
    public void CreateYAxis(Chart chart, ChartArea area, Series series, 
    float axisX, float axisWidth, float labelsSize, bool alignLeft)
    {

    chart.ApplyPaletteColors(); // (*)

    // Create new chart area for original series
    ChartArea areaSeries = chart.ChartAreas.Add("CAs_" + series.Name);
    areaSeries.BackColor = Color.Transparent;
    areaSeries.BorderColor = Color.Transparent;
    areaSeries.Position.FromRectangleF(area.Position.ToRectangleF());
    areaSeries.InnerPlotPosition.FromRectangleF(area.InnerPlotPosition.ToRectangleF());
    areaSeries.AxisX.MajorGrid.Enabled = false;
    areaSeries.AxisX.MajorTickMark.Enabled = false;
    areaSeries.AxisX.LabelStyle.Enabled = false;
    areaSeries.AxisY.MajorGrid.Enabled = false;
    areaSeries.AxisY.MajorTickMark.Enabled = false;
    areaSeries.AxisY.LabelStyle.Enabled = false;
    areaSeries.AxisY.IsStartedFromZero = area.AxisY.IsStartedFromZero;
    // associate series with new ca
    series.ChartArea = areaSeries.Name;

    // Create new chart area for axis
    ChartArea areaAxis = chart.ChartAreas.Add("CA_AxY_" + series.ChartArea);

    areaAxis.BackColor = Color.Transparent;
    areaAxis.BorderColor = Color.Transparent;
    RectangleF oRect = area.Position.ToRectangleF();
    areaAxis.Position = new ElementPosition(oRect.X, oRect.Y, axisWidth, oRect.Height);
    areaAxis.InnerPlotPosition
    .FromRectangleF(areaSeries.InnerPlotPosition.ToRectangleF());

    // Create a copy of specified series
    Series seriesCopy = chart.Series.Add(series.Name + "_Copy");
    seriesCopy.ChartType = series.ChartType;
    seriesCopy.YAxisType = alignLeft ? AxisType.Primary : AxisType.Secondary; // (**)

    foreach (DataPoint point in series.Points)
    {
    seriesCopy.Points.AddXY(point.XValue, point.YValues[0]);
    }
    // Hide copied series
    seriesCopy.IsVisibleInLegend = false;
    seriesCopy.Color = Color.Transparent;
    seriesCopy.BorderColor = Color.Transparent;
    seriesCopy.ChartArea = areaAxis.Name;

    // Disable grid lines & tickmarks
    areaAxis.AxisX.LineWidth = 0;
    areaAxis.AxisX.MajorGrid.Enabled = false;
    areaAxis.AxisX.MajorTickMark.Enabled = false;
    areaAxis.AxisX.LabelStyle.Enabled = false;

    Axis areaAxisAxisY = alignLeft ? areaAxis.AxisY : areaAxis.AxisY2; // (**)
    areaAxisAxisY.MajorGrid.Enabled = false;
    areaAxisAxisY.IsStartedFromZero = area.AxisY.IsStartedFromZero;
    areaAxisAxisY.LabelStyle.Font = area.AxisY.LabelStyle.Font;

    areaAxisAxisY.Title = series.Name;
    areaAxisAxisY.LineColor = series.Color; // (*)
    areaAxisAxisY.TitleForeColor = Color.DarkCyan; // (*)

    // Adjust area position
    areaAxis.Position.X = axisX;
    areaAxis.InnerPlotPosition.X += labelsSize;
    }

    我添加了一些代码来使轴具有系列颜色。 (*) alignLeft将在为 false 时选择辅助轴而不是主轴。 (**)

    在复选框事件中调用方法时使用必要的数字。

    以下是用于我的屏幕截图的行和数字:

    先说普通话。。
    // Set custom chart area position
    ChartArea ca = chart1.ChartAreas["ChartArea1"];
    ca.Position = new ElementPosition(23, 10, 77, 85);
    ca.InnerPlotPosition = new ElementPosition(12, 0, 67, 90);

    // Create extra Y axis for some series
    CreateYAxis(chart1, ca, chart1.Series["Current"], 5, 9, 8, true);
    CreateYAxis(chart1, ca, chart1.Series["Capacity"], 13, 9, 8, true);
    CreateYAxis(chart1, ca, chart1.Series["testing"], 21, 9, 8, true);

    ..然后将一个系列轴添加到右侧:
    // Set custom chart area position
    ChartArea ca = chart1.ChartAreas["ChartArea1"];
    ca .Position = new ElementPosition(15, 10, 83, 85);
    ca .InnerPlotPosition = new ElementPosition(12, 0, 67, 90);

    // Create extra Y axis for some series
    CreateYAxis(chart1,ca , chart1.Series["Current"], 5, 9, 8, true);
    CreateYAxis(chart1, ca , chart1.Series["Capacity"], 13, 9, 8, true);
    CreateYAxis(chart1, ca , chart1.Series["testing"], 64, 21, 8, false);

    请注意 else复选框事件的分支尝试删除额外的图表区域。它有一个硬编码的数字 3 ;这和整个反转代码不太稳定!

    关于代码本身的作用的简短说明:

    它增加了 两个 每个额外的“系列轴”的额外图表区域:
  • 一个将原始系列关联到。这个必须始终与原始图表区域具有相同的位置和大小!其目的是允许图形最大程度地缩放,因为没有其他系列与这个新图表区域相关联。图形保持可见,但所有其他部分(如轴边框等)都是不可见的。
  • 另一个将显示轴。这里的一切但是 轴是不可见的;为了填充轴,原始系列中的点被复制到与该图表区域相关联的新系列中。

  • 关于使用的最后说明:整个使用仍然取决于您用于布置图表区域的数字!我自己写了一个小助手工具,你可以 download如果你感兴趣。这是它的工作原理:

    enter image description here

    关于c# - 如何在左侧或右侧以不同比例向 MSChart 添加更多 Y 轴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43861842/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com