Search code examples
c#asp.net.netchartsasp.net-charts

ASP.NET Charting Pie Chart - both inside and outside label per slice


In an existing applications (web forms, but the underlying Microsoft Charting stack is basically the same for winforms/webforms/razor charts) I have Pie Charts, with for each slice the following business data:

  1. Value
  2. Label
  3. Color (used for categorization, same color for multiple slices)

The requirement is a Chart that has all information layout out in one chart like this (mockup):

Pie Chart with both inside and outside Labels

Using the CustomProperties on the Series/Points I can display each datapoint with either an Inside

Pie Chart with Labels inside

Or an Outside Label:

Pie Chart with Labels outside

But not both. Can I somehow trick the Pie Chart into displaying both an inside and outside label for each data point?

I realize that this is an edge case (normally you'd use legend+color to visualize this, but we already use color to categorize). I'd rather avoid rendering to a bitmap first and manually rendering the label texts on there (because there are mechanisms in place to stream the charts to both web pages and generated documents).


Solution

  • Create two series and two chart areas and superimpose them:

    enter image description here

    ASPX:

    <asp:Chart ID="Chart1" runat="server">
        <series>
            <asp:Series ChartType="Pie" 
                Name="Series1" 
                CustomProperties="PieLabelStyle=Inside, PieStartAngle=270" 
                BorderColor="White" 
                ChartArea="ChartArea1">
            </asp:Series>
            <asp:Series ChartType="Pie" 
                Name="Series2" 
                CustomProperties="PieLabelStyle=Outside, PieStartAngle=270" 
                ChartArea="ChartArea2">
            </asp:Series>
        </series>
        <chartareas>
            <asp:ChartArea Name="ChartArea1" >
                <InnerPlotPosition Height="95" Width="45.98404" X="27.00798" Y="2.50000072" />
            </asp:ChartArea>
            <asp:ChartArea Name="ChartArea2" 
                AlignWithChartArea="ChartArea1"
                AlignmentOrientation="All"
                BackColor="Transparent">
                <InnerPlotPosition Height="95" Width="45.98404" X="27.00798" Y="2.50000072" />
            </asp:ChartArea>
            </chartareas>
    </asp:Chart>
    

    CS:

    protected void Page_Load(object sender, EventArgs e)
    {
        List<MyDataModel> data = new List<MyDataModel> {
            new MyDataModel { Color = Color.LightBlue, Label = "Value 1", Value = 100 },
            new MyDataModel { Color = Color.LightBlue, Label = "Value 2", Value = 100 },
            new MyDataModel { Color = Color.LightBlue, Label = "Value 3", Value = 100 },
            new MyDataModel { Color = Color.Blue, Label = "Value 4", Value = 100 },
            new MyDataModel { Color = Color.Blue, Label = "Value 5", Value = 400 },
        };
    
            foreach (MyDataModel dm in data)
            {
                Chart1.Series[0].Points.Add(new DataPoint
                {
                    Color = dm.Color,
                    Label = dm.Value.ToString(),
                    YValues = new double[] { dm.Value }
                });
    
                Chart1.Series[1].Points.Add(new DataPoint
                {
                    Color = Color.Transparent,
                    Label = dm.Label,
                    YValues = new double[] { dm.Value }
                });
            }
    }