MS Chart Control两个Y轴

12

我正在构建一个图表,以按类别显示物品的数量。目前,我已成功地显示了按数量显示的物品,因为它是一个简单的x/y图表,但是我想显示y2,并且我知道MS Chart Controls有一个内置的AxisY2,但是当我尝试做任何与它相关的操作时,图表变得很奇怪。

以下是我所期望的(使用ASCII艺术表示):

item1 |[][][][][].............| cat1
item2 |[][]...................| cat2
item3 |[][....................| cat1
item4 |[][][][][][][][........| cat1
      |_______________________|
        0   1   2   3   4   5

就像之前提到的,我可以很好地显示项目和数量,因为这相对容易,但是我似乎无法把类别放在正确的位置上。

谢谢

5个回答

36

这是我所做的-在创建图表后,我添加了以下行:

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;

没有必要叠加两个图表或其他!


9

6
首先回答问题:根据微软的示例,没有直接的方法来实现这一点,但有一个变通的方法:在第二个与现有区域位置完全匹配的图表区域上绘制您的系列(通过复制您的系列),使主X/Y轴不可见,并且次要Y轴(AxisY2)可见。并将chartArea和已复制的系列的背景颜色设置为透明。(在柱形图中可以应用于次要X轴而不是条形图)。
//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:我花了两个晚上的时间来处理 MS 图表控件,试图在一个图表区域中放置两个不同的 Y 轴。我想要在同一 X 轴上绘制两个不同比例的系列(系列 A 的左侧和系列 B 的右侧各一个 Y 轴)。 事实上,这证明是一个真正的噩梦,当人们期望这应该是相当简单的时候。事实是,MS 图表控件绝对不适用于这种特定的用例。在 MSCC 示例示例中建议的多个 Y 轴示例是一个可怕而且非常丑陋的解决方法,需要在默认图表区域之上使用两个图表区域,通过调整可见性和透明度来实现所需的效果(听起来像是一个非常糟糕的幻术魔法技巧)。

希望将来的版本能够以适当的方式丰富和修复此问题,如果您确实需要有效地管理多个 Y 轴,请使用ZedGraph


我正在尝试使用您的示例,但运行不成功;我可以获取y轴,但它们是空的。有什么建议吗?我感觉这也变成了我两天的事情。 - KTF
4
明白了,结果发现我根本不需要叠加图表!我只需要相应地设置每个系列的YAxisType并启用第二个Y轴即可! - KTF
1
这个答案通过使用实现的函数解决了问题,而无需创建两个图表。 - Freddy

3

您可以在Y轴上添加任意多的系列,以下代码是我使用的图表中具有2个以上次要y轴的摘录,代码是vb.net的,但我相信您可以解决:

        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()

2
解决方案:
chart1.ChartAreas[1].AlignWithChartArea = chart1.ChartAreas[0].Name;
chart1.ChartAreas[1].AlignmentOrientation = AreaAlignmentOrientations.All;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接