Fixed Height Bars with Alternating Marks Position

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

Fixed Height Bars with Alternating Marks Position

Post by qcrnd » Sun Mar 15, 2009 7:09 am

Hey,
I'm trying to create a graph with a fixed height, where the bars value will determine the relative width.
Also I need the marks position and length alternating in position, having odd marks above the graph and even ones below the graph.

In order to make the width relative I tried using Steema.TeeChart.Styles.HorizBar but I got the marks horizontal as well.

see attached image of the intended graph look
Image
The red braces & blue arrows are only for illustration purposes.

Cheers,
Elad

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Post by Sandra » Mon Mar 16, 2009 12:44 pm

Hi qcrnd,


You coud use a similar code as next, for fix your issue:

InitializeChart

Code: Select all

        private void InitializeChart()
        {
            Steema.TeeChart.Styles.HorizBar hbar = new Steema.TeeChart.Styles.HorizBar(tChart1.Chart);
            hbar.FillSampleValues(4);
            hbar.ColorEach = true;
            hbar.MultiBar = Steema.TeeChart.Styles.MultiBars.SelfStack;
            tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_AfterDraw);
            tChart1.MouseUp += new MouseEventHandler(tChart1_MouseUp);
            tChart1.Draw();
        
        }
AfterDraw Event

Code: Select all

        void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
            RepositionMarks(tChart1[0]);
        }

Method RepositionMarks

Code: Select all

        private void RepositionMarks(Steema.TeeChart.Styles.Series series)
        {
            Steema.TeeChart.Styles.SeriesMarks.Position pos;
            series.Chart.AutoRepaint = false;
            for (int i = 0; i < series.Count; i++)
            {
                pos = series.Marks.Positions[i];
                pos.Custom = true;
                series.Marks.Arrow.Width = 2;
                series.Marks.Arrow.Color = Color.Black;

                int tmpX = tChart1.Axes.Bottom.CalcXPosValue(series.XValues[i]);
                int tmpHalfWidth = Convert.ToInt32(pos.Width/2);

                if (i == 0)
                {
                    pos.LeftTop.X = tmpX - Convert.ToInt32((tmpX - tChart1.Axes.Bottom.IStartPos)/2) - tmpHalfWidth;
                }
                else
                {
                    pos.LeftTop.X = series.Marks.Positions[i - 1].LeftTop.X + tmpX - tChart1.Axes.Bottom.IStartPos;
                }                

                pos.ArrowTo.X = pos.LeftTop.X + pos.Width / 2;
                pos.ArrowFrom.X = pos.ArrowTo.X;

                int tmp = ((Steema.TeeChart.Styles.HorizBar)series).BarBounds.Height;

                if (i % 2 == 0)
                {
                    pos.LeftTop.Y += tmp;
                    pos.ArrowFrom.Y = ((Steema.TeeChart.Styles.HorizBar)series).BarBounds.Bottom;
                }
                else
                {
                    pos.LeftTop.Y -= tmp;                    
                    pos.ArrowFrom.Y = ((Steema.TeeChart.Styles.HorizBar)series).BarBounds.Top;
                }

                pos.ArrowTo.Y = pos.LeftTop.Y;
            }
            series.Chart.AutoRepaint = true;
            series.Chart.Invalidate();

        }

I hope that you have been served my help
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

Thanks

Post by qcrnd » Tue Mar 17, 2009 9:33 am

I'm still having some issues.
We build out chart differently, I'll try changing the adjustments to your code.

Thanks
Elad

qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

-

Post by qcrnd » Tue Mar 17, 2009 1:13 pm

I still encounter several problems:

1) I've tried correcting the positions and there are many offsets.

This is the chart is built:

Code: Select all

      foreach (KeyValuePair<string, int> val in Values)
      {
          HorizBar bar = new HorizBar(tChart1.Chart);
          bar.MultiBar = MultiBars.Stacked;
          bar.Cursor = Cursors.Hand;
          bar.BarHeightPercent = 100;

          bar.DepthPercent = 50;
          bar.Marks.Visible = true;
          bar.Color = GetColor(val.Key);
          bar.Add(val.Value, val.Key);

          bar.Title = string.Format("{0} {1}", val.Value, val.Key);
        }
      }

      tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(RepositionChartMarks);
2) Since the marks are visible on creation, causing the chart doesn't occupy all the area, having the right area empty.

3) tChart1.Draw() method should gets System.Drawing.Graphics as a parameter, so I cannot invoke it after creating the chart.

Can you assist?

Thanks
Elad

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Post by Sandra » Wed Mar 18, 2009 12:53 pm

Hi Edal,

Please, could you send us a simple example project we can run "as-is" to reproduce the problem here?
You can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at ourupload page

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

File uploaded

Post by qcrnd » Thu Mar 19, 2009 8:44 am

Hey Sandra,
I've uploaded the file, it is named "TChartSample.zip"
I added info in 1.txt file

Thanks
Elad

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Fri Mar 20, 2009 3:38 pm

Hi Elad,

Thanks for the example project. Compiling it with latest TeeChart for .NET v3 release available at the client area we could use tChart1.Draw() method. Could you please check if this solves the problem at your end? If it doesn't which is the exact problem you are having with marks positioning?

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

Post by qcrnd » Sun Mar 22, 2009 6:09 am

Thanks Narcis,
I will check the .Net V3.
Can you please also check regarding my two other questions, especially the reason the chart doesn't fill the entire tChart area becuase of the original marks position?

Thanks again
Elad

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Mon Mar 23, 2009 2:47 pm

Hi Elad,

Sure! Find below the answers to your questions:

2. Below you'll find modified code which works fine with your example:

Code: Select all

    public ChartForm()
    {
      InitializeComponent();
      CreateChart();
			this.Resize += new EventHandler(ChartForm_Resize);
    }

		void ChartForm_Resize(object sender, EventArgs e)
		{
			tChart1.Draw();
		}



    private bool CreateChart()
    {
      IDictionary<string, int> valuesDict = new Dictionary<string, int>();

      valuesDict.Add("opt A", 5);
      valuesDict.Add("option B", 2);
      valuesDict.Add("option CCC", 4);
      valuesDict.Add("D", 8);

      IDictionary<string, Color> colorsDict = new Dictionary<string, Color>();

      colorsDict.Add("opt A", Color.AliceBlue);
      colorsDict.Add("option B", Color.Chocolate);
      colorsDict.Add("option CCC", Color.Gold);
      colorsDict.Add("D", Color.SpringGreen);

			tChart1.Dock = DockStyle.Fill;
      tChart1.Series.Clear();
      tChart1.Legend.Visible = false;

      foreach (KeyValuePair<string, int> status in valuesDict)
      {
        // if there are no requirement with this status, don't add a series
        // (if its in the end of the bar, its color is shown)
        if (status.Value > 0)
        {
          HorizBar bar = new HorizBar(tChart1.Chart);
          bar.MultiBar = MultiBars.Stacked;
          bar.Cursor = Cursors.Hand;
          bar.BarHeightPercent = 100;

          bar.DepthPercent = 50;
          bar.Marks.Visible = true; // 12345 false;
          bar.Color = colorsDict[status.Key];
          bar.Add(status.Value, status.Key);

          bar.Title = string.Format("{0} {1}", status.Value, status.Key);
        }
      }

      tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(RepositionChartMarks);

			tChart1.Draw();

      return true;
    }

    private void RepositionChartMarks(object sender, Steema.TeeChart.Drawing.Graphics3D g)
    {
      HorizBar series = null;
			Steema.TeeChart.Styles.SeriesMarks.Position pos = new SeriesMarks.Position();
			Steema.TeeChart.Styles.SeriesMarks.Position oldPos;

      for (int i = 0; i < tChart1.Series.Count; i++)
      {        
        series = (HorizBar)tChart1[i];
				series.Chart.AutoRepaint = false;
        series.Marks.Arrow.Width = 1;
        series.Marks.Arrow.Color = System.Drawing.Color.Black;

				oldPos = pos;
				pos = series.Marks.Positions[0];
				pos.Custom = true;
				pos.LeftTop.X = series.BarBounds.Left + series.BarBounds.Width / 2 - pos.Width / 2;
        pos.ArrowTo.X = pos.LeftTop.X + pos.Width / 2;
        pos.ArrowFrom.X = pos.ArrowTo.X;

        int tmp = Convert.ToInt32(series.BarBounds.Height / 3);

        if (i % 2 == 1)
        {          
          pos.ArrowFrom.Y = series.BarBounds.Bottom;
					pos.LeftTop.Y = pos.ArrowFrom.Y + tmp; 
        }
        else
        {
					pos.ArrowFrom.Y = series.BarBounds.Top;
					pos.LeftTop.Y = pos.ArrowFrom.Y - tmp;
        }

        pos.ArrowTo.Y = pos.LeftTop.Y;
      }
			series.Chart.AutoRepaint = true;
			series.Chart.Invalidate();
    }
3. In v3 you can use it as can be seen in the code above. In v2 you can do this:

Code: Select all

				Bitmap bmp = tChart1.Bitmap
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

Post by qcrnd » Tue Mar 24, 2009 2:47 pm

Thanks, it works great.
only problem I have is a empty space in the right of the chart, see attached image:
Image

Instead of the chart taking the entire chart area width, it is behaving as if the default marks were in their default places thus reducing the actual bars width.

I tried changing the custom width but had no luck.

Any advice?
Thanks in advance
Elad

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Tue Mar 24, 2009 4:17 pm

Hi Elad,

In that case I'd use Annotation tools instead of series marks:

Code: Select all

    public ChartForm()
    {
      InitializeComponent();
      CreateChart();
			this.Resize += new EventHandler(ChartForm_Resize);
    }

		void ChartForm_Resize(object sender, EventArgs e)
		{
			tChart1.Draw();
		}

		private Steema.TeeChart.Tools.Annotation[] annotations;

    private bool CreateChart()
    {
      IDictionary<string, int> valuesDict = new Dictionary<string, int>();

      valuesDict.Add("opt A", 5);
      valuesDict.Add("option B", 2);
      valuesDict.Add("option CCC", 4);
      valuesDict.Add("D", 8);

      IDictionary<string, Color> colorsDict = new Dictionary<string, Color>();

      colorsDict.Add("opt A", Color.AliceBlue);
      colorsDict.Add("option B", Color.Chocolate);
      colorsDict.Add("option CCC", Color.Gold);
      colorsDict.Add("D", Color.SpringGreen);

			tChart1.Dock = DockStyle.Fill;
      tChart1.Series.Clear();
      tChart1.Legend.Visible = false;

      foreach (KeyValuePair<string, int> status in valuesDict)
      {
        // if there are no requirement with this status, don't add a series
        // (if its in the end of the bar, its color is shown)
        if (status.Value > 0)
        {
          HorizBar bar = new HorizBar(tChart1.Chart);
          bar.MultiBar = MultiBars.Stacked;
          bar.Cursor = Cursors.Hand;
          bar.BarHeightPercent = 100;

          bar.DepthPercent = 50;
          bar.Marks.Visible = false; // 12345 false;
          bar.Color = colorsDict[status.Key];
          bar.Add(status.Value, status.Key);

          bar.Title = string.Format("{0} {1}", status.Value, status.Key);
        }
      }
      
			annotations = new Steema.TeeChart.Tools.Annotation[tChart1.Series.Count];
			for (int i = 0; i < tChart1.Series.Count; i++)
			{
				annotations[i] = new Steema.TeeChart.Tools.Annotation(tChart1.Chart);
				annotations[i].Text = tChart1[i].Labels[0];
				annotations[i].Callout.Arrow.Visible = true;
				annotations[i].Callout.Arrow.Color = Color.Black;
				annotations[i].Callout.Arrow.Width = 1;
			}

			tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(RepositionChartMarks);
			tChart1.Draw();

      return true;
    }

    private void RepositionChartMarks(object sender, Steema.TeeChart.Drawing.Graphics3D g)
    {
      HorizBar series = null;
			Steema.TeeChart.Tools.Annotation a;
			
      for (int i = 0; i < tChart1.Series.Count; i++)
      {        
        series = (HorizBar)tChart1[i];
				a = annotations[i];
				
				a.Shape.CustomPosition = true;
				a.Shape.Left = series.BarBounds.Left + series.BarBounds.Width / 2 - a.Width / 2;
				a.Callout.XPosition = a.Shape.Left + a.Width / 2;

				int tmp = Convert.ToInt32(series.BarBounds.Height / 3);

				if (i % 2 == 1)
				{
					a.Callout.YPosition = series.BarBounds.Bottom;
					a.Shape.Top = a.Callout.YPosition + tmp;
				}
				else
				{
					a.Callout.YPosition = series.BarBounds.Top;
					a.Shape.Top = a.Callout.YPosition - tmp;
				}
      }
    }
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

qcrnd
Advanced
Posts: 214
Joined: Mon Sep 04, 2006 12:00 am

Post by qcrnd » Wed Mar 25, 2009 11:32 am

Thanks a lot for all your help

Post Reply