2017-05-09 108 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