Click here to Skip to main content
15,895,667 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I apologize in advance if I'm posting in the wrong forum, my question is about half and half on XML and C#. I am trying to draw a pie chart using the Arc class from the Microsoft.Expression.Shapes namespace. This works correctly in WPF when the Arcs are defined in XML with the following code:

HTML
<Grid Grid.Row="0" x:Name="primaryGrid">
            <ed:Arc x:Name="pieSlice1" ArcThickness="1" ArcThicknessUnit="Percent" Fill="Green" HorizontalAlignment="Left" VerticalAlignment="Stretch" Stretch="None" Stroke="Black" UseLayoutRounding="False" Width="204" Height="204" Margin="0" ToolTipService.ToolTip="Text"/>
            <TextBlock x:Name="pie1TextBlock" FontSize="18" Height="26" Margin="0,51,47,0" TextWrapping="NoWrap" VerticalAlignment="Top" HorizontalAlignment="Right" Width="121"/>
            <Rectangle Fill="Green" Height="20" Width="20" Margin="294,55,189,0" Stroke="Black" VerticalAlignment="Top"/>

            <ed:Arc x:Name="pieSlice2" ArcThickness="1" ArcThicknessUnit="Percent" Fill="Blue" HorizontalAlignment="Left" Stretch="None" Stroke="Black" UseLayoutRounding="False" Width="204" Height="204" Margin="0"/>
            <TextBlock x:Name="pie2TextBlock" FontSize="18" Height="26" Margin="0,86,47,0" TextWrapping="NoWrap" VerticalAlignment="Top" HorizontalAlignment="Right" Width="121"/>
            <Rectangle Fill="Blue" Height="20" Width="20" Margin="294,90,189,0" Stroke="Black" VerticalAlignment="Top"/>
        </Grid>


Using XML, the items line up correctly and create a full circle for my pie graph (i.e., the Start and End angles work as defined), even when I draw the segments in C# code, such as:

C#
double[] itemsArray = new double[arraySize] { 12.5, 25.0, 6.25, 6.25, 10.0, 8.8, 11.2, 20 };
        
            Arc[] sliceArray = new Arc[arraySize] {pieSlice1, pieSlice2, pieSlice3, pieSlice4, pieSlice5, pieSlice6, pieSlice7, pieSlice8};
            TextBlock[] textArray = new TextBlock[arraySize] { pie1TextBlock, pie2TextBlock, pie3TextBlock, pie4TextBlock, pie5TextBlock, pie6TextBlock, pie7TextBlock, pie8TextBlock };

            for (int counter = 0; counter < 8; counter++)
            {
                endAngle = endAngle + itemsArray[counter] / 100 * 360;

                sliceArray[counter].StartAngle = beginAngle;
                sliceArray[counter].EndAngle = endAngle;

                textArray[counter].Text = (((endAngle - beginAngle) / 360) * 100).ToString() + "%";

                beginAngle = endAngle;
            }


However, when I create the arcs dynamically in C# code instead of defining them in WPF, the arcs end up stacked on top of each other:

C#
Arc arc = new Arc();
            arc.HorizontalAlignment = HorizontalAlignment.Left;
            arc.VerticalAlignment = VerticalAlignment.Stretch;
            arc.Stroke = Brushes.Black;
            arc.StrokeThickness = 1;
            arc.ArcThickness = 20;
            arc.UseLayoutRounding = false;
            arc.Fill = Brushes.Blue;
            arc.Margin = new Thickness(0);
            arc.Height = 50;
            arc.Width = 50;
            arc.StartAngle = 0;
            arc.EndAngle = 90;
            arc.ToolTip = new ToolTip();
            arc.ToolTip = "Blue Text";

            Arc arc2 = new Arc();
            arc2.HorizontalAlignment = HorizontalAlignment.Left;
            arc2.VerticalAlignment = VerticalAlignment.Stretch;
            arc2.Stroke = Brushes.Black;
            arc2.StrokeThickness = 1;
            arc2.ArcThickness = 20;
            arc2.UseLayoutRounding = false;
            arc2.Fill = Brushes.Green;
            arc2.Margin = new Thickness(0);
            arc2.Height = 50;
            arc2.Width = 50;
            arc2.StartAngle = 90;
            arc2.EndAngle = 201;
            arc2.ToolTip = new ToolTip();
            arc2.ToolTip = "Green Text";

            Arc arc3 = new Arc();
            arc3.HorizontalAlignment = HorizontalAlignment.Left;
            arc3.VerticalAlignment = VerticalAlignment.Stretch;
            arc3.Stroke = Brushes.Black;
            arc3.StrokeThickness = 1;
            arc3.ArcThickness = 20;
            arc3.Fill = Brushes.Yellow;
            arc3.Margin = new Thickness(0);
            arc3.Height = 50;
            arc3.Width = 50;
            arc3.StartAngle = 201;
            arc3.EndAngle = 234;
            arc3.ToolTip = new ToolTip();
            arc3.ToolTip = "Yellow Text";

            Arc arc4 = new Arc();
            arc4.HorizontalAlignment = HorizontalAlignment.Left;
            arc4.VerticalAlignment = VerticalAlignment.Stretch;
            arc4.Stroke = Brushes.Red;
            arc4.StrokeThickness = 1;
            arc4.ArcThickness = 20;
            arc4.Fill = Brushes.Yellow;
            arc4.Margin = new Thickness(0);
            arc4.Height = 50;
            arc4.Width = 50;
            arc4.StartAngle = 234;
            arc4.EndAngle = 360;
            arc4.ToolTip = new ToolTip();
            arc4.ToolTip = "Red Text";

            Canvas canvas = new Canvas();

            canvas.Margin = new Thickness(50);
            canvas.Height = 300;
            canvas.Width = 300;

            canvas.Children.Add(arc);
            canvas.Children.Add(arc2);
            canvas.Children.Add(arc3);
            canvas.Children.Add(arc4);

      
            this.Content = canvas;


I'm not sure if it's the difference between a canvas and a grid, but I'm having much trouble getting the pie slices to line up. I am trying to avoid setting the margins of the canvas, or defining a set number of arcs in WPF.

I guess I'm confused as to what the difference is between the C# code used to generate the arcs in a canvas and the WPF code used to create the arc in a grid? How could I set the output of the arcs to a grid?
Posted

1 solution

Hi,

obviously a Grid isn't the same as a Canvas.
The Grid control positions the child elements per Grid.Row and Grid.Column.

To position child elements in a Canvas, for each child the attached properties Canvas.Top
and Canvas.Left needs to be set (or Canvas.Right/Canvas.Bottom).
And if you provide no values for Left and Top, the default value is 0 for both,
so each child is stacked above the other.

For example:

C#
// position arc at point 10,10 from the top-/left uppermost corner of the canvas
Canvas.SetTop(arc, 10);
Canvas.SetLeft(arc, 10);

// positions other children here
// ...

// add children to canvas
canvas.Children.Add(arc);
canvas.Children.Add(arc2);
canvas.Children.Add(arc3);
canvas.Children.Add(arc4);


Bye,

Thomas.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900