Avatar billede pablopablo Nybegynder
16. november 2003 - 15:01 Der er 18 kommentarer og
1 løsning

Tegning af Cirkel diagram i c#

Hejsa... 

Jeg skal have afbildet noget statestik fra mit prog. grafisk...til det har jeg tænkt mig at lave et cirkel-diagram...

Mit spg. er nu, hvordan gør jeg dette lettest? Jeg har fundet et link på MSDN men kan ikke helt gennemskue om det er til c# og hvordan jeg skal bruge det?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/linecurv_9egk.asp

2d er fint nok(3d ville selfølgelig være optimalt!), hvert cirkel-udsnit skal have sin egen farve + en tilknyttede beskrivende tekst...det skal (HELST)fungere dynamisk, da det er forskelligt, hvor mange elementer som indgår i statistikken fra gang til gang. Med andre ord : nogle gange skal "lagkagen" opdeles i 3 stykker og andre gang i måske 20 stykker...det afhænger af brugerens valg, hvad han ønsker at lave statistik på...

Håber meget i kan hjælpe mig lidt på vej?-)

mvh. PabloPablo
Avatar billede odegaard Nybegynder
16. november 2003 - 15:07 #1
Søg efter GDI+ istedet. Fx.
http://msdn.microsoft.com/library/en-us/vbcon/html/vborigdifundamentals.asp
Her er der en hel masse små eksempler på hvordan man gør.
Avatar billede finger Nybegynder
16. november 2003 - 15:15 #2
eller brug evt det der ligger i .NET/C#
Erstat koden i en ny form med dette:
---------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace arch
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Panel panel1;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.panel1 = new System.Windows.Forms.Panel();
            this.SuspendLayout();
            //
            // panel1
            //
            this.panel1.BackColor = System.Drawing.Color.White;
            this.panel1.Location = new System.Drawing.Point(8, 8);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(208, 192);
            this.panel1.TabIndex = 0;
            this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
            //
            // Form1
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
            this.ClientSize = new System.Drawing.Size(224, 208);
            this.Controls.Add(this.panel1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.DrawPie(Pens.Black, 3,3,150,150,0,60);
            g.DrawPie(Pens.Blue, 3,3, 150,150,60,60);
            g.DrawPie(Pens.Green, 3,3, 150,150,120,60);
            g.DrawPie(Pens.Gold, 3,3, 150,150,180,60);
            g.DrawPie(Pens.Red, 3,3, 150,150,240,60);
            g.DrawPie(Pens.Yellow, 3,3, 150,150,300,60);
           
        }
    }
}
Avatar billede finger Nybegynder
16. november 2003 - 15:17 #3
Hvis du hellere vil have fyldte "kagestykker" så brug dette:
g.FillPie(Brushes.Black, 3,3,150,150,0,60);
g.FillPie(Brushes.Blue, 3,3, 150,150,60,60);
g.FillPie(Brushes.Green, 3,3, 150,150,120,60);
g.FillPie(Brushes.Gold, 3,3, 150,150,180,60);
g.FillPie(Brushes.Red, 3,3, 150,150,240,60);
g.FillPie(Brushes.Yellow, 3,3, 150,150,300,60);
Avatar billede pablopablo Nybegynder
16. november 2003 - 15:30 #4
Finger : Det ser MEGET fint ud!! MEN...du må lige komme med det sidste guldkorn...Hvordan laver jeg det dynamisk, som beskrevet i mit første indlæg?
Avatar billede nielsbrinch Nybegynder
16. november 2003 - 15:32 #5
Du omtegner bare hele diagrammet fra bunden hver gang brugeren skal lave en ændring. Jeg tror ikke det vil være at foretrække at ændre på selve den tegning der allerede er tegnet. Tegn forfra hver gang, er mit tip.
Avatar billede finger Nybegynder
16. november 2003 - 15:33 #6
det er jo bare at lave et for loop.
bikser lige et eksempel sammen...
Avatar billede pablopablo Nybegynder
16. november 2003 - 15:42 #7
skal lige være sikker på jeg har forstået det rigtigt...fx :

g.FillPie(Brushes.Black, 3,3,150,150,0,60);// "3,3"=hvor i forhold til startpunktet det pågældende udsnit skal have centrum , "150,150"=startpunkt/centrum der navigeres udfra, "0,60" = graderne fra/til?-)
Avatar billede pablopablo Nybegynder
16. november 2003 - 15:43 #8
Kan man via en eller flere parametre gøre det til et 3d diagram?
Avatar billede finger Nybegynder
16. november 2003 - 15:53 #9
For at tegne 3D mener jeg du skal have fat i noget andet end det der ligger standard i c#/.Net, men har aldrig selv prøvet.
Her er definitionen på metode kaldet:
------
public void FillPie(Brush brush, int x,int y, int width, int height, int startAngle,int sweepAngle);

brush = Brush object that determines the characteristics of the fill.

x= x-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes.

y= y-coordinate of the upper-left corner of the bounding rectangle that defines the ellipse from which the pie section comes.

width = Width of the bounding rectangle that defines the ellipse from which the pie section comes.

height = Height of the bounding rectangle that defines the ellipse from which the pie section comes.

startAngle = Angle in degrees measured clockwise from the x-axis to the first side of the pie section.

sweepAngle =Angle in degrees measured clockwise from the startAngle parameter to the second side of the pie section.
-------

Og her er en dynamisk form:
------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace arch
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Panel panel1;
        private System.Windows.Forms.NumericUpDown numericUpDown1;
        private System.Windows.Forms.Label label1;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.panel1 = new System.Windows.Forms.Panel();
            this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
            this.label1 = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
            this.SuspendLayout();
            //
            // panel1
            //
            this.panel1.BackColor = System.Drawing.Color.White;
            this.panel1.Location = new System.Drawing.Point(8, 8);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(208, 192);
            this.panel1.TabIndex = 0;
            this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint);
            //
            // numericUpDown1
            //
            this.numericUpDown1.Location = new System.Drawing.Point(280, 80);
            this.numericUpDown1.Maximum = new System.Decimal(new int[] {
                                                                          30,
                                                                          0,
                                                                          0,
                                                                          0});
            this.numericUpDown1.Minimum = new System.Decimal(new int[] {
                                                                          2,
                                                                          0,
                                                                          0,
                                                                          0});
            this.numericUpDown1.Name = "numericUpDown1";
            this.numericUpDown1.Size = new System.Drawing.Size(56, 22);
            this.numericUpDown1.TabIndex = 1;
            this.numericUpDown1.Value = new System.Decimal(new int[] {
                                                                        11,
                                                                        0,
                                                                        0,
                                                                        0});
            this.numericUpDown1.ValueChanged += new System.EventHandler(this.numericUpDown1_ValueChanged);
            //
            // label1
            //
            this.label1.Location = new System.Drawing.Point(280, 48);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(48, 23);
            this.label1.TabIndex = 2;
            this.label1.Text = "Antal";
            //
            // Form1
            //
            this.AutoScaleBaseSize = new System.Drawing.Size(6, 15);
            this.ClientSize = new System.Drawing.Size(392, 280);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.numericUpDown1);
            this.Controls.Add(this.panel1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void panel1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            try
            {
                int size = (360/(Convert.ToInt32(numericUpDown1.Value)));
                int startAngle = 0;
                Brush[] myBrushes = new Brush[6];
                myBrushes[0] = Brushes.Black;
                myBrushes[1] = Brushes.Red;
                myBrushes[2] = Brushes.Blue;
                myBrushes[3] = Brushes.Brown;
                myBrushes[4] = Brushes.Yellow;
                myBrushes[5] = Brushes.Green;
                int brushCount = 0;

                Graphics g = e.Graphics;

                for(int i = 0; i < int.Parse(numericUpDown1.Value.ToString()); i++)
                {
                    g.FillPie(myBrushes[brushCount], 3,3,150,150,startAngle,size);
                    startAngle += size;
                    if(brushCount == 5)
                        brushCount = 0;
                    else
                        brushCount++;
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
           
        }

        private void numericUpDown1_ValueChanged(object sender, System.EventArgs e)
        {
            panel1.Invalidate();

        }
    }
}
Avatar billede pablopablo Nybegynder
16. november 2003 - 16:37 #10
Finger : Du nærmer du kraftigt points...;) Et sidste spg. har du et godt trick til hvordan jeg tilnytter en beskrivende tekst-streng til hver stykke, når jeg benytter den dynamiske form?
Avatar billede odegaard Nybegynder
16. november 2003 - 16:44 #11
Mht. 3D, så er der jo intet i vejen for selv at konstruere 2½D tegninger. Det kræver blot en lille smule matematik.
Avatar billede pablopablo Nybegynder
16. november 2003 - 16:51 #12
odegaard : 2½D tegning ?-) hvordan skal det forstås? synes det er lidt mærkeligt, at det ikke er lavet således, at man via en elkelt parameter mere kunne angive højden på hver stykke...?
Avatar billede pablopablo Nybegynder
16. november 2003 - 17:08 #13
Jeg har lagt mærke til, at hvis "lagkagen" opdeles i 7,11,13,14,16,17,19,21,22,23,25,26,27,28 eller 29 stykker så er det ikke alle 360 grader af den som er farvet...Dette skyldes højest sandsyneligt, at grade-antallet udregnes i Int og der dermed går noget tabt for hvert skykke...jeg kan se at metoden : g.FillPie() tager Int som type...men det er da ikke for smart? da der ved nogle af intervallene er meget store udsnit af "lagkagen" som ikke bliver farvet med andet end baggrunds-farven!! ;(

Håber i har en løsning på dette ?-) Så vil jeg blive MEGET glad!
Avatar billede odegaard Nybegynder
16. november 2003 - 17:41 #14
Eftersom din monitor viser et flat billede, og ikke et egentligt 3D billede med dybde i, så kaldes et billede der ligner et 3D billede for 2½D.

Du kan jo bare lave cirklen om til en ellipse, tegne halvdelen af den igen et stykke under, og forbinde dem med to lodrette linjer langs deres lodrette tangenser (giver det mening?)
Herefter LIGNER det en 3D tegning, selvom det jo egentlig er to ellipser og to linjer (og derved 2½D).
Avatar billede pablopablo Nybegynder
16. november 2003 - 17:59 #15
odegaard - ja det giver mening - dog tror jeg det bliver ret kryptisk at programmere...da det hele jo skal fungere dynamisk...?

Du kender vel ikke svaret på mine spg. postet kl 16:37 og 17:08? Det er nemlig vigtigere end at det blive 2½D...
Avatar billede nielsbrinch Nybegynder
16. november 2003 - 18:04 #16
Jeg anbefaler du bare tjekker til sidst hvor mange pts. du har delt ud. Hvis det ikke er alle 100, så deler du bare lidt ekstra ud indtil det giver 100.
Avatar billede pablopablo Nybegynder
16. november 2003 - 18:21 #17
nielsbrinch...HVORDAN skal jeg dele noget "ekstra" ud, når jeg KUN kan bruge Int værider i følge g.FillPie()? det er præsic den samme problemstilling som før jo...? det kan heller ikke være rigtigt, at man selv skal ligge og fedte med det...der må da være en "rigtig" måde at gøre det på? Jeg tror ikke på, at det kun er mulig at benytte hele grader - så har .net/c# folkene i hvert fald ikke tænkt sig særligt meget om??
Avatar billede pablopablo Nybegynder
16. november 2003 - 19:18 #18
Når jeg nu har fået det hele til at virke...hvordan for jeg så den form ind i min oprindelige form unden  at selvfølgelig kan se form viduet...men kun cirkeldiagrammet...?
Avatar billede pablopablo Nybegynder
16. november 2003 - 19:51 #19
Finger du får dine points...det ser ud til der ikke rigtigt er nogle som svarer længere...så jeg bliver vel nød til at udlove endnu flere points i en ny tråd...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester