2017-05-09 245 views
1

添加到MSChart的我想补充3 Y轴为以不同的比例图。如何更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

+0

你叫CreateYAxis两次,以创建两个additionY轴。相反,您可以将其中的一个放在次Y轴(右侧)。只是一个想法,既然你已经定制你的图表到这个扩展,你可以添加单独的图例/轴标题甚至注释和定位他们为指示目的。 – uqji

+0

@ TaW,是的,代码不是我的,有些是由我改变的。我对这个更新。所以我不能维护我希望的代码。我想重新安排这个代码,就像我给出的第二张图片。要在图表区右侧获得容量轴。其他轴都可以。如果可以的话,请纠正它。它将有助于克服我的问题。感谢您的先生 – SNP

+0

@感谢您的帮助sir – SNP

回答

2

这是一件相当复杂的代码一个有趣的问题解决了,我从来没有注意到一个问题..

让我们先谈谈阿布基本知识。

在图表中可以添加多个序列数据的同一区域。只要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轴......这正是您找到的代码所提供的。

让我们来看看reults第一:

enter image description here

这是很好的;现在我们可以看到范围从0 - 300 - 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将错误时选择中间轴而不是主要的之一。 (**)

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

下面是被用于我的屏幕截图的直线和数字:

一是正常的..

// 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); 

..then了一个与一个系列轴添加到右:

// 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

+0

,非常感谢您的帮助。 – SNP