MS Chart Control Two Y Axis

后端 未结 5 1854
礼貌的吻别
礼貌的吻别 2020-11-30 04:41

I\'m building a chart to show items by volume by category. So far I\'ve been succcessful in showing items by volume as it\'s a simple x/y chart, however I\'d like to show y

相关标签:
5条回答
  • 2020-11-30 04:53

    Short Answer first : According to MS Examples, there is no straight way to do that, but just a workaround trick : Plot your series on a second chartArea matching exactly your existing area position, (by performing a copy of your Series) having invisible primary X/Y Axis and a visible secondary Y Axis (AxisY2). And set the chartArea and the copied series's backcolors to transparent. (This can be applied to secondary X axis in case of column graphs rather that bars)

    //Suppose you already have a ChartArea with the series plotted and the left Y Axis
    //Add a fake Area where the only appearent thing is your secondary Y Axis
    ChartArea area1 = chart.ChartAreas.Add("ChartAreaCopy_" + series.Name);
    area1.BackColor = Color.Transparent;
    area1.BorderColor = Color.Transparent;
    area1.Position.FromRectangleF(area.Position.ToRectangleF());
    area1.InnerPlotPosition.FromRectangleF(area.InnerPlotPosition.ToRectangleF());
    area1.AxisX.MajorGrid.Enabled = false;
    area1.AxisX.MajorTickMark.Enabled = false;
    area1.AxisX.LabelStyle.Enabled = false;
    area1.AxisY.MajorGrid.Enabled = false;
    area1.AxisY.MajorTickMark.Enabled = false;
    area1.AxisY.LabelStyle.Enabled = false;
    
    area1.AxisY2.Enabled = AxisEnabled.True;
    area1.AxisY2.LabelStyle.Enabled = true;
    
    // Create a copy of specified series, and change Y Values to categories
    Series seriesCopy = chart.Series.Add(series.Name + "_Copy");
    seriesCopy.ChartType = series.ChartType;
    foreach(DataPoint point in series.Points)
    {
        double category = getYourItemCategory(point.XValue);
        seriesCopy.Points.AddXY(point.XValue, category);
    }
    
    // Hide copied series
    seriesCopy.IsVisibleInLegend = false;
    seriesCopy.Color = Color.Transparent;
    seriesCopy.BorderColor = Color.Transparent;
    
    //Drop it in the chart to make the area show (only the AxisY2 should appear)
    seriesCopy.ChartArea = area1.Name;
    

    PS : I've spent two nights awake messing with MS chart controls, trying to put two different Y axis on a Chart Area. I wanted to put two differently scaled series (same X scale, different Y Scales : one on the left for Series A , the other on the right for Series B). In fact, this proved to be a real nightmare, when one could expect this to be pretty straightforward. The truth is that MS Chart Controls are definitely NOT adapted for this particular use case IMHO. The multiple Y axis sample suggested in the MSCC sample examples is an awful and very ugly workaround, which requires two chartareas on top of the default one, playing with visibility and transparency, to achieve the desired effect (which sounds like a very bad illusion magic trick).

    While hoping for this to be enriched and fixed in a proper way in future versions, if you really need an efficient way to manage multiple Y-Axis, sitck to ZedGraph

    0 讨论(0)
  • 2020-11-30 04:57

    Here's what did it for me- after I created the chart I added the following lines:

    chrtMain.Series[0].YAxisType = AxisType.Primary;
    chrtMain.Series[1].YAxisType = AxisType.Secondary;
    
    chrtMain.ChartAreas[0].AxisY2.LineColor = Color.Transparent;
    chrtMain.ChartAreas[0].AxisY2.MajorGrid.Enabled = false;
    chrtMain.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True;
    chrtMain.ChartAreas[0].AxisY2.IsStartedFromZero = chrtMain.ChartAreas[0].AxisY.IsStartedFromZero;
    

    There was no need to superimpose two charts or anything!

    0 讨论(0)
  • 2020-11-30 04:59

    You can add as many series on the Y axis as you want, below code is an extract from a chart I use that has more than 2 secondary y axes, code is for vb.net but i'm sure you can work it out:

            ChartKPI.Series.Clear()
    
            ChartKPI.Series.Add("Series1")
            ChartKPI.Series("Series1").XValueMember = "Date"
            ChartKPI.Series("Series1").YValueMembers = "HSDPA_Vol_MBy"
            ChartKPI.Series("Series1").Name = "HSDPA_Vol_MBy"
            ChartKPI.Series("HSDPA_Vol_MBy").ChartType = SeriesChartType.Column
            ChartKPI.Series("HSDPA_Vol_MBy").ToolTip = "HSDPA MBytes: #VAL"
    
            ChartKPI.Series.Add("Series2")
            ChartKPI.Series("Series2").YAxisType = AxisType.Secondary
            ChartKPI.Series("Series2").XValueMember = "Date"
            ChartKPI.Series("Series2").YValueMembers = "cs_voice_traffic"
            ChartKPI.Series("Series2").Name = "cs_voice_traffic"
            ChartKPI.Series("cs_voice_traffic").ChartType = SeriesChartType.Line
            ChartKPI.Series("cs_voice_traffic").BorderWidth = 3
            ChartKPI.Series("cs_voice_traffic").ToolTip = "CS Voice Traffic: #VAL"
    
            ChartKPI.Series.Add("Series3")
            ChartKPI.Series("Series3").YAxisType = AxisType.Secondary
            ChartKPI.Series("Series3").XValueMember = "Date"
            ChartKPI.Series("Series3").YValueMembers = "cs_conv_traffic"
            ChartKPI.Series("Series3").Name = "cs_conv_traffic"
            ChartKPI.Series("cs_conv_traffic").ChartType = SeriesChartType.Line
            ChartKPI.Series("cs_conv_traffic").BorderWidth = 3
            ChartKPI.Series("cs_conv_traffic").ToolTip = "CS Conv Traffic: #VAL"
    
            ChartKPI.Series.Add("Series4")
            ChartKPI.Series("Series4").YAxisType = AxisType.Secondary
            ChartKPI.Series("Series4").XValueMember = "Date"
            ChartKPI.Series("Series4").YValueMembers = "ps_backg_traffic_ul"
            ChartKPI.Series("Series4").Name = "ps_backg_traffic_ul"
            ChartKPI.Series("ps_backg_traffic_ul").ChartType = SeriesChartType.Line
            ChartKPI.Series("ps_backg_traffic_ul").BorderWidth = 3
            ChartKPI.Series("ps_backg_traffic_ul").ToolTip = "PS Backg Traffic UL: #VAL"
    
            ChartKPI.Series.Add("Series5")
            ChartKPI.Series("Series5").YAxisType = AxisType.Secondary
            ChartKPI.Series("Series5").XValueMember = "Date"
            ChartKPI.Series("Series5").YValueMembers = "ps_backg_traffic_dl"
            ChartKPI.Series("Series5").Name = "ps_backg_traffic_dl"
            ChartKPI.Series("ps_backg_traffic_dl").ChartType = SeriesChartType.Line
            ChartKPI.Series("ps_backg_traffic_dl").BorderWidth = 3
            ChartKPI.Series("ps_backg_traffic_dl").ToolTip = "PS Backg Traffic DL: #VAL"
    
            ChartKPI.ChartAreas("ChartArea1").AxisX.Title = "HSDPA Traffic (MB)"
            ChartKPI.ChartAreas("ChartArea1").AxisX.MajorGrid.Interval = 1
            ChartKPI.ChartAreas("ChartArea1").AxisX.LabelStyle.Interval = 1
            ChartKPI.ChartAreas("ChartArea1").AxisY.Title = "RRC Attempts"
            ChartKPI.ChartAreas("ChartArea1").AxisY2.Title = "R99 Traffic (Erlang)"
    
            ChartKPI.DataBind()
    
    0 讨论(0)
  • 2020-11-30 05:08

    Solution:

    chart1.ChartAreas[1].AlignWithChartArea = chart1.ChartAreas[0].Name;
    chart1.ChartAreas[1].AlignmentOrientation = AreaAlignmentOrientations.All;
    
    0 讨论(0)
  • 2020-11-30 05:10

    It gets even better:

    For using the second Y axis, there is no need for a second chart area. You can decide per serie which axis you want to use with the Series.YAxisType property. Take a look at the documentation on http://msdn.microsoft.com/en-us/library/dd489216.aspx

    Martijn

    0 讨论(0)
提交回复
热议问题