Search code examples
c#chartsmschart

C# MSChart - How can I create two pie graphs side by side sharing the same axis?


I'm trying to create two pie charts, side by side, that share the same axis. Does anyone have an example of code to accomplish this using MSChart?

Example of what I want to achieve: Example of what I want to achieve

Here's my code so far:

        Chart chart = new Chart();
        chart.Width = 800;
        string PreContractSeriesName = "PreContract";
        string ContractSeriesName = "Contract";

        //two chart areas
        chart.ChartAreas.Add(PreContractSeriesName);
        chart.ChartAreas.Add(ContractSeriesName);

        //two pie charts, so two series
        chart.Series.Add(PreContractSeriesName);
        chart.Series.Add(ContractSeriesName);

        //add series to chart area
        chart.Series[PreContractSeriesName].ChartArea = PreContractSeriesName;
        chart.Series[ContractSeriesName].ChartArea = ContractSeriesName;

        //set as pie chart
        chart.Series[PreContractSeriesName].ChartType = SeriesChartType.Pie;
        chart.Series[ContractSeriesName].ChartType = SeriesChartType.Pie;

        chart.ChartAreas[PreContractSeriesName].AlignmentOrientation = AreaAlignmentOrientations.Horizontal;
        chart.ChartAreas[ContractSeriesName].AlignmentOrientation = AreaAlignmentOrientations.Horizontal;

        chart.Series[PreContractSeriesName].Points.AddXY("source1", 100);
        chart.Series[PreContractSeriesName].Points.AddXY("source2", 200);
        chart.Series[PreContractSeriesName].Points.AddXY("source3", 300);
        chart.Series[PreContractSeriesName].Points.AddXY("source4", 400);
        chart.Series[PreContractSeriesName].Points.AddXY("source5", 500);

        chart.Series[ContractSeriesName].Points.AddXY("source1", 140);
        chart.Series[ContractSeriesName].Points.AddXY("source2", 240);
        chart.Series[ContractSeriesName].Points.AddXY("source3", 340);
        chart.Series[ContractSeriesName].Points.AddXY("source4", 440);
        chart.Series[ContractSeriesName].Points.AddXY("source5", 540);

        using (MemoryStream memStream = new MemoryStream())
        {
            chart.SaveImage(memStream, ChartImageFormat.Jpeg);

            return File(memStream.ToArray(), "image/jpeg");
        }

My code results in the following graphs on top of each other:

enter image description here

I would like to know:

  1. How can I align the charts side by side?
  2. Is this the correct way of going about sharing an axis?
  3. Does anyone have an example of how to accomplish this?

Edit:

Here is my updated code thanks to user TaW

        Chart chart = new Chart();
        chart.Width = 800;
        string PreContractSeriesName = "PreContract";
        string ContractSeriesName = "Contract";

        //two chart areas
        chart.ChartAreas.Add(PreContractSeriesName);
        chart.ChartAreas.Add(ContractSeriesName);

        //two pie charts, so two series
        chart.Series.Add(PreContractSeriesName);
        chart.Series.Add(ContractSeriesName);

        //add series to chart area
        chart.Series[PreContractSeriesName].ChartArea = PreContractSeriesName;
        chart.Series[ContractSeriesName].ChartArea = ContractSeriesName;

        //position chart areas side by side
        chart.ChartAreas[PreContractSeriesName].Position = new ElementPosition(2, 5, 48, 80);
        chart.ChartAreas[ContractSeriesName].Position = new ElementPosition(50, 5, 48, 80);


        chart.Legends.Add(new Legend() {
            Alignment = StringAlignment.Center,
            Docking = Docking.Bottom }
        );
        chart.Series[ContractSeriesName].IsVisibleInLegend = false;

        //set as pie chart
        chart.Series[PreContractSeriesName].ChartType = SeriesChartType.Pie;
        chart.Series[ContractSeriesName].ChartType = SeriesChartType.Pie;

        chart.Series[PreContractSeriesName].Points.AddXY("source1", 100);
        chart.Series[PreContractSeriesName].Points.AddXY("source2", 200);
        chart.Series[PreContractSeriesName].Points.AddXY("source3", 300);
        chart.Series[PreContractSeriesName].Points.AddXY("source4", 400);
        chart.Series[PreContractSeriesName].Points.AddXY("source5", 500);

        chart.Series[ContractSeriesName].Points.AddXY("source1", 140);
        chart.Series[ContractSeriesName].Points.AddXY("source2", 240);
        chart.Series[ContractSeriesName].Points.AddXY("source3", 340);
        chart.Series[ContractSeriesName].Points.AddXY("source4", 440);
        chart.Series[ContractSeriesName].Points.AddXY("source5", 540);

Solution

  • enter image description here

    Here is how to align two ChartAreas ca1 and ca2 in a Chart chart:

    ca1.Position = new ElementPosition(2, 5, 48, 80);
    ca2.Position = new ElementPosition(50, 5, 48, 80);
    chart.Legends[0].Docking = Docking.Bottom;
    chart.Legends[0].Alignment = StringAlignment.Center;
    

    Note that this hard-codes the positions to percentages of the chart's size.

    The alignment properties you tried are really about aligning data not positioning the chartareas. See their AreaAlignmentStyles! To take control over the placement of ChartArea we need to leave the default Auto settings and pick our own numbers.

    I leave 2 percent to the left and right and make the two ChartAreas sit directly beside each other. I have added colors so you can see what is what..

    I have left 15% at the bototm for the Legend, which is docked to the bottom and centered.

    You will want to use your own numbers.

    Also note that by default the two pies each get their own legend entries. To supress one set of entries you can set this property of one Series S2:

    S2.IsVisibleInLegend = false;
    

    For another example see here!