2017-05-09 25 views
1

다른 배율로 차트에 3 개의 Y 축을 추가하고 싶습니다.왼쪽 또는 오른쪽에 다른 배율로 Y 축을 추가하는 방법

하나의 x 축과 다른 y 축을 얻고 싶습니다. 나는 코드를 아래와 같이 그것을했다하지만 난 .. 내가 첨부 2 이미지처럼 지금까지

내 C# 코드 하나의 y 축 보여주고 싶은 :

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

당신은이 개 additionY 축을 만들고 두 번 CreateYAxis을했다. 대신 보조 Y 축 (오른쪽)에 그 중 하나를 넣을 수 있습니다. 그냥 생각해 보았습니다.이 차트를 커스터마이징 한 이후로, 별도의 범례/축 제목 또는 주석을 추가하고 표시 목적으로 배치 할 수 있습니다. – uqji

+0

@ TaW 예, 그 코드는 제게 변경된 것이 아닙니다. 그리고 저는 이것보다 새로운 것입니다. 그래서 나는 희망하는 유지 보수 코드가 될 수 없습니다. 나는 위에서 주어진 두 번째 이미지처럼이 코드를 다시 배열하고자합니다. 나는 차트 영역의 오른쪽에 용량 축을 가져오고 싶습니다. 다른 축은 괜찮습니다. 가능하다면 문제를 해결하십시오. 내 문제를 극복하는 데 도움이 될 것입니다. – SNP

+0

감사합니다. 도움을 주셔서 감사합니다. – SNP

답변

2

이것은 전혀 알지 못하는 문제를 해결하는 매우 복잡한 코드로 흥미로운 질문입니다.

먼저 abou 기본.

차트에서 일련의 데이터를 같은 영역에 추가 할 수 있습니다. y 값의 범위가 어느 정도 동일하면 대개 아무런 문제가 없습니다. 그러나 그렇지 않은 경우에는 y 축이 축척되어 모든 값이 차트 영역에 맞춰집니다. 즉, 범위가 작은 시리즈는 부숴 질 것입니다. 하나 개의 축이 타이틀이라고 우리가 참조 오렌지색 계열을 제외한 모든 판독 불가능 y 값 이외에

enter image description here

, 예를 들면 다음과 같습니다 그것이 모든 시리즈에 적용된다면, 좋습니다; 하지만이하는 경우없는 : 최고 ..

(. 때로는 도움이 될 수 있습니다 로그로 y 축 설정, 그러나 보통이 그냥 전혀 도움이 일을 혼동하지 않을)

이 호출을 생략 더 많은 축들. 사실 하나 추가 축 가 내장, 바로 바로 물어을 위해 각 차트 영역은에 ''AxisY2라고 왼쪽과 다른,에 y 축을 가질 수 권리.

당신은 하나의 시리즈 그것으로와 동료를 활성화 할 수 있습니다

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

이 잘하고 잘 작동합니다. 그러나이 예제에서는 2 개 이상의 y 축을 요구합니다. 이는 여러분이 찾은 코드가 제공하는 것입니다.

의 처음 reults를 살펴 보자 :

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은 거짓 일 때 보조 보조 대신 보조 축을 선택합니다. (**)

checkbox 이벤트에서 메서드를 호출 할 때 필요한 숫자가 사용됩니다. 여기

내 스크린 샷에 사용 된 선과 숫자 ..

먼저 정상 하나 하나 개 시리즈 축과 하나의 오른쪽에 추가 ..then

// 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; 이것과 전체 반전 코드는 꽤 안정적이지 않습니다!

에 대한 짧은 desciption 코드 자체는 무엇을 :

  • 는 원래 시리즈를 연결할 :

    그것은 각 추가 '시리즈 축'에 대한 별도의 차트 영역을 추가 . 이 것은 원래 도표 영역과 동일한 위치 인 항상 &이어야합니다! 그 목적은이 새로운 차트 영역과 연관된 다른 시리즈가 없으므로 그래픽을 최대한 확장 할 수 있도록하는 것입니다. 그래픽은 보이지 만 축 테두리와 같은 다른 모든 부분은 보이지 않습니다.

  • 은 축을 표시합니다. 여기에는 모든 것이 이지만 축은 보이지 않습니다. 축을 채우려면 원래 시리즈의 점을이 차트 영역과 연관된 새 시리즈에 복사합니다.

마지막 참고 사항 : 전체 사용량은 차트 영역을 배치하는 데 사용하는 숫자에 따라 달라집니다. 나는 약간의 도우미 도구를 썼다. 당신이 관심이 있다면 download이 될 수있다.여기에 직장에서 그것을이다

enter image description here

+0

, 도와 주셔서 대단히 감사합니다. – SNP