1

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)
{
   ???
}
TaW
  • 53,122
  • 8
  • 69
  • 111
qwerteste
  • 13
  • 2

1 Answers1

5

..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.

TaW
  • 53,122
  • 8
  • 69
  • 111
  • 2
    You should use `!chart1.Series[seriesName].Points.Any()` instead of `.Count == 0` - this is known as a code smell – Mafii Apr 11 '19 at 06:51
  • I wouldn't call it 'smell' as `0` is not really a magic number but you are right, `Any` is indeed the recommended choice. I tried to stay with OP's code as much as possible butI I'll add it to the answer.. – TaW Apr 11 '19 at 06:52
  • Whatever you wanna call it, it's poor practice and should be avoided, especially when using big data sets (which can be the case when rendering a chart) – Mafii Apr 11 '19 at 06:53
  • Since you updated your comment: It's not about the 0. If it's a list, it doesn't matter, really. But you get a mixed, inconsistent code style, because with Enumberables or Queryables you really __need__ to use `.Any()`, or you _risk enumerating the whole set_ just to be sure if there is at least one item. – Mafii Apr 11 '19 at 06:57
  • [This](https://stackoverflow.com/questions/305092/which-method-performs-better-any-vs-count-0) has a good discussion; but imo this is a good example of style and clarity over (assumed) performance. – TaW Apr 11 '19 at 07:00
  • 1
    Read the comments. I'm definitly on T.J.Kjaer's side. By the way - Any is implemented as .Length on Arrays and on .Count on lists. – Mafii Apr 11 '19 at 07:02