C#: Paint own Bar Chart

2019-02-15 11:27发布

问题:

I'm trying to paint a simple bar chart via C# but I've never experimented with the Graphics and Drawing namespaces. I thought of generating a "start" and "end" graphic and then repeating an image somehow (to show a "length") but I have no idea how to do this.

I'd be really happy if you can point me in the right direction and/or if you have sample code to do this.

回答1:

I've got to agree with Eros. There are lots of very good graphing libraries to accomplish what you want. The best I've come across:

  • Microsoft Chart Controls - There's even a Visual Studio plugin and a good tutorial.
  • Flot - This one is jQuery based, so good for web apps.
  • Google Chart - Simple API and even an ASP.Net Control


回答2:

Alex, here is a very simple example to get you started. To test the code, just add a panel control to your form and create a paint event handler for it. (Double click on the panel in the designer should do it by default.) Then replace the handler code with th code below.

The code draws five bars of arbitrary length across the panel and the bar widths and heights are related to the panel widths and heights. The code is arbitrary but is a good and simple way to introduce .Net drawing capabilities.

void Panel1Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    int objCount = 5;

    for (int n=0; n<objCount; n++)
    {
        g.FillRectangle(Brushes.AliceBlue, 0, n*(panel1.Height/objCount), 
                        panel1.Width/(n+1), panel1.Height/objCount);
        g.DrawRectangle(new Pen(Color.Black), 0, n*(panel1.Height/objCount), 
                        panel1.Width/(n+1), panel1.Height/objCount);
        g.DrawString(n.ToString(), new Font("Arial", 10f), Brushes.Black, 
                     2, 2+n*(panel1.Height/objCount));
    }
}


回答3:

why dont you give http://zedgraph.org/wiki/index.php?title=Main_Page a try. The time required to build (and test) your own graph controls will be too much



回答4:

Based on reply from Paul Sasik, I've created a bit different simple bar-chart. I hope this might help others.

void DrawTheBar(int[] Values, Panel p)
    {                       
        //configuration of the bar chart
        int barWidth = 20; //Width of the bar
        int barSpace = 5; //Space between each bars.
        int BCS = 5; //Background cell size
        float fontSize = 8;
        string fontFamily = "Arial";        

        Color bgColor = Color.White;
        Brush fillColor = Brushes.CadetBlue;
        Color borderColor = Color.Black;
        Color bgCellColor = Color.Silver;
        Brush textColor = Brushes.Black;

        //do some magic here...
        p.BackColor = bgColor; //set the bg color on panel
        Graphics g = p.CreateGraphics();
        g.Clear(bgColor); //cleans up the previously draw pixels
        int Xpos = barSpace; //initial position
        int panelHeight = panel1.Height-1; //fix panel height for drawing border 

        //Drawing rectangles for background.
        for(int c = 0; c < Convert.ToInt16(panel1.Width / BCS); c++)
        {
            for(int r = 0; r < Convert.ToInt16(panel1.Height / BCS); r++)
            {
                g.DrawRectangle(new Pen(bgCellColor), c * BCS, r * BCS, BCS, BCS);
            }
        }

        //Drawing the bars
        for(int i = 0; i < Values.Length; i++)
        {
            //Drawing a filled rectangle. X = Xpos; Y = ((panel Height - 1) - Actual value); Width = barWidth, Height = as value define it
            g.FillRectangle(fillColor, Xpos, (panelHeight - Values[i]), barWidth, Values[i]);
            //Draw a rectangle around the previously created bar.
            g.DrawRectangle(new Pen(borderColor), Xpos, (panelHeight - Values[i]), barWidth, Values[i]);
            //Draw values over each bar.
            g.DrawString(Values[i].ToString(), new Font(fontFamily, fontSize), textColor, (Xpos + 2), (panelHeight - Values[i]) - (fontSize + barSpace));

            //calculate the next X point for the next bar.
            Xpos += (barWidth + barSpace);
        }

        //here you will be happy with the results. :)
    }


回答5:

What's wrong with using a simple loop?