Here is the Problem.
I need to create multiple charts(number is not known previously). So, I am generating dynamic Chart. The problem is, chart appears but shows no data. It is just a blank white space.
private void Form1_Load(object sender, EventArgs e)
{
Chart demo = new Chart();
demo.Location = new Point(0, 0);
demo.Size=new Size(this.Width,this.Height);
demo.Series.Add("check");
DataPoint dp1 = new DataPoint(1, 1);
DataPoint dp2 = new DataPoint(2, 2);
DataPoint dp3 = new DataPoint(3, 3);
demo.Series["check"].Points.Add(dp1);
demo.Series["check"].Points.Add(dp2);
demo.Series["check"].Points.Add(dp3);
this.Controls.Add(demo);
demo.BringToFront();
demo.Visible = true;
}
Output is just a white chart with nothing on it.
You need to create a chart area. Just add this line in your code.
demo.ChartAreas.Add("newchartarea");
Related
I have WinForm with chart and database.Chart get data from database. If no data the chart isn't visible. I would like to show a message in the chart place.For example: "No data yet." Can I do it?
if (chart1["Series1"].Points.Count == 0)
{
???
}
..show a message in the chart..Can I do it?
Sure. There are in fact many ways, from setting the chart's Title to using the Paint event and DrawString or creating a TextAnnotation etc..
The two latter options are easy to center and both will keep the position even when the chart is resized.
Example 1 - A TextAnnotation:
TextAnnotation ta = new TextAnnotation();
Set it up like this:
ta.Text = "No Data Yet";
ta.X = 45; // % of the..
ta.Y = 45; // chart size
ta.Font = new Font("Consolas", 20f);
ta.Visible = false; // first we hide it
chart1.Annotations.Add(ta);
Show whenever the data are changed:
ta.Visible = (chart1.Series[seriesNameOrIndex].Points.Count == 0)
Example 2 - Drawing the messag in the Paint event:
private void chart1_Paint(object sender, PaintEventArgs e)
{
if (chart1.Series[seriesNameOrIndex].Points.Count == 0)
{
using (Font font = new Font("Consolas", 20f))
using (StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center })
e.Graphics.DrawString("No data yet",
font, Brushes.Black, chart1.ClientRectangle, fmt);
}
}
This should keep itself updated as adding or removing DataPoints will trigger the Paint event.
Btw: The recommended way to test to a collection to contain any data is using the Linq Any() function:
(!chart1.Series[seriesNameOrIndex].Points.Any())
It is both as fast as possible and clear in its intent.
I am working on a simple Windows Forms application which consists of a Panel where I draw graphics with Graphic. Let's say, my panel is now of size 300x300 but the content inside is 500x500. Obviously, I need to add scrollbars to the Panel.
My code so far:
public CircuitControl()
{
// Initialize empty list of circuit objects
CircuitObjects = new List<CircuitObject>();
drawingAreaPanel.AutoScroll = true;
drawingAreaPanel.VerticalScroll.Enabled = true;
drawingAreaPanel.VerticalScroll.Visible = true;
drawingAreaPanel.HorizontalScroll.Enabled = true;
drawingAreaPanel.MaximumSize = new Size(300, 300);
drawingAreaPanel.Size = new Size(600, 600);
}
But none of these codes create actually a scroll bar. My question is: Where and how do I set the size of the Panel where I actually drew? I think this is the part which is missing. Thanks.
The scrollbars won't show up until there's actually something in the Panel that you can't see all of.
Try placing a larger control, such as a PictureBox, inside the Panel, and setting the PictureBox's initial size as larger than the Panel.
Just add:
drawingAreaPanel.AutoScroll = true;
And it will be done automatically.
€dit: Don't forget to set the anchors in order to get the scrollbars.
A clean and simple approach is to set AutoScrollMinSize. This shows the scrollbars (or just one if you leave the other value at 0).
Now drawing through the graphics object will not be scrolled automatically.
This can be easily achieved with a transformation matrix, which is set before painting and translates the drawing by the scroll offset.
A pretty example: (this flickers of course without further optimizations)
private void button1_Click(object sender, EventArgs e)
{
using(Form frm = new Form())
{
Panel pnl = new Panel();
pnl.Paint += delegate (Object snd, PaintEventArgs e2) {
Matrix mtx = new Matrix();
mtx.Translate(pnl.AutoScrollPosition.X, pnl.AutoScrollPosition.Y);
e2.Graphics.Transform = mtx;
e2.Graphics.Clear(Color.Black);
for(int i=0; i <= 125; i++)
for(int j=0; j <= 125; j++)
using(Brush b = new SolidBrush(Color.FromArgb(255, 255-i*2, j*2, (i*j) % 255)))
e2.Graphics.FillRectangle(b, new Rectangle(5+j*20, 5+i*20, 20, 20));
};
pnl.AutoScrollMinSize = new Size(126*20+10, 126*20+10);
pnl.Dock = DockStyle.Fill;
frm.Controls.Add(pnl);
frm.Padding = new Padding(25);
frm.ShowDialog(this);
}
}
I need to create some shape object like Circle, Line etc in Windows Forms using C#.
Added reference to PresentationFramework from .Net tab and using System.Windows.Shapes.
But after creating Line object it is not showing in Windows Form.
Please see below sample code :
code in load event of form :
Line myline = new Line();
myline.X1 = 100;
myline.X2 = 300;
myline.Y1 = 300;
myline.Y2 = 300;
myline.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myline.StrokeThickness = 2;
Please let me know wrong I'm doing in it.
you forgot to update the drawing request, you are just defining the line without drawing it actually
Edited:
public void drawmyline()
{
System.Drawing.Graphics example;
// Create pen.
Pen blackPen = new Pen(Color.Black, 3);
// Create points that define line.
Point point1 = new Point(100, 100);
Point point2 = new Point(400, 400);
example = this.CreateGraphics();
// Draw line to screen.
example.DrawLine(blackPen, point1, point2);
//e.Graphics.DrawLine(blackPen, point1, point2);
}
then, you call your function from any place you want, for example a button click
private void button4_Click_1(object sender, EventArgs e)
{
drawmyline();
}
please mark as accepted if it helped you
I'm working with .NET forms in Visual C#.
I've created a label dynamically, which shows upon a button click. This all works fine; what I'm trying to do is position it so that the element is at the centre of the form. Normally, I'd just set it to half the form size, minus half the element size, but of course this won't work as I am setting the text programmatically also.
My code for the label is as follows:
if(part == 1){
theLabel.Text = "Choose a name for your character!";
}
theLabel.ForeColor = Color.DarkGray;
theLabel.Font = new Font("Arial", 14, FontStyle.Bold);
theLabel.Location = new Point();
I've tried many things here, but I just cannot think of a way. I've tried int[] sizes = (int)theLabel.Size and various other but I just cannot get this to work. Is there another way to line this element to the middle?
If I was you I'd do it this way.
Label theLabel;
private void button1_Click(object sender, EventArgs e)
{
theLabel = new Label();
theLabel.AutoSize = true;
theLabel.BackColor = Color.Red;
theLabel.TextAlign = ContentAlignment.MiddleCenter;
theLabel.Text = "Choose a name for your character!";
this.Controls.Add(this.theLabel);
theLabel.Left = (this.ClientRectangle.Width - theLabel.Width) / 2;
//theLabel.ForeColor = Color.Black;
theLabel.Top = 25;
theLabel.Show();
}
I am able to print a chart from my c# project using:
chart1.Printing.PrintDocument.DocumentName = "Graph of data";
But is it possible to add a title to this? I was hoping the document name would achieve this, but apparently not!
You can print whatever you want directly to the page and then invoke the chart PrintPaint(). Note that if you don't switch the PageUnit to Pixels that the chart scaling gets confused.
void PrintChart(object sender, PrintPageEventArgs ev)
{
using (var f = new System.Drawing.Font("Arial", 10))
{
var size = ev.Graphics.MeasureString(Text, f);
ev.Graphics.DrawString("Whatever text you want", f, Brushes.Black, ev.PageBounds.X + (ev.PageBounds.Width - size.Width) / 2, ev.PageBounds.Y);
}
//Note, the chart printing code wants to print in pixels.
Rectangle marginBounds = ev.MarginBounds;
if (ev.Graphics.PageUnit != GraphicsUnit.Pixel)
{
ev.Graphics.PageUnit = GraphicsUnit.Pixel;
marginBounds.X = (int)(marginBounds.X * (ev.Graphics.DpiX / 100f));
marginBounds.Y = (int)(marginBounds.Y * (ev.Graphics.DpiY / 100f));
marginBounds.Width = (int)(marginBounds.Width * (ev.Graphics.DpiX / 100f));
marginBounds.Height = (int)(marginBounds.Height * (ev.Graphics.DpiY / 100f));
}
chart1.Printing.PrintPaint(ev.Graphics, marginBounds);
}
This menu handler opens a PrintDialog(). If you don't want a dialog you can just call pd.Print().
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
var pd = new System.Drawing.Printing.PrintDocument();
pd.PrintPage += new PrintPageEventHandler(PrintChart);
PrintDialog pdi = new PrintDialog();
pdi.Document = pd;
if (pdi.ShowDialog() == DialogResult.OK)
pdi.Document.Print();
}
Here is a workaround solution to your problem, if you place the ChartingControl inside a Panel control on the Windows Form. You can then print the panel, inside the panel you can add the document heading as a label and whatever other stuff you want to add.
Firstly from the toolbox add a PrintDocument control and call it MyPrintDocument
Then add a Panel control and put your chart inside it.
Make sure you have imported the System.Drawing namespace, then you can print the panel like this.
Bitmap MyChartPanel = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(MyChartPanel, new Rectangle(0, 0, panel1.Width, panel1.Height));
PrintDialog MyPrintDialog = new PrintDialog();
if (MyPrintDialog.ShowDialog() == DialogResult.OK)
{
System.Drawing.Printing.PrinterSettings values;
values = MyPrintDialog.PrinterSettings;
MyPrintDialog.Document = MyPrintDocument;
MyPrintDocument.PrintController = new System.Drawing.Printing.StandardPrintController();
MyPrintDocument.Print();
}
MyPrintDocument.Dispose();
This code converts the panel into a Bitmap and then prints that Bitmap.
You could condense this into a function like:
public void PrintPanel(Panel MyPanel)
{
// Add code from above in here, changing panel1 to MyPanel...
}