Page 1 of 1

Multiline titles and legends

Posted: Wed Jan 07, 2009 4:22 am
by 14045174
I have a chart with a very complicated title. It is long and contains multiple lines. If I choose to show legend on the left or right of the chart, instead of being next to the chart, legend is actually drawn much higher and overlaps with the title. To avoid overlapping, I need to set title's alignment to the right, but then part of it is clipped on the left. The whole chart looks awful. Any ideas?

Posted: Wed Jan 07, 2009 10:27 am
by narcis
Hi UserLS,

Can you please send us a simple example project we can run "as-is" to reproduce the problem here so that we can suggest the most suitable solution?

You can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.

Thanks in advance.

Posted: Wed Jan 07, 2009 1:44 pm
by 14045174
You do not need any code snippets, just drop a TChart object on a form, right click on it and select "Edit". Add a series (any), make sure your legend is visible and is located on the left of the chart. Now go Titles page and start typing in the memo box some really long lines (more then 3) and watch title overlap the legend as you type...

Posted: Wed Jan 07, 2009 2:03 pm
by narcis
Hi UserLS,

Ok, in that case you can solve the problem setting the legend to a custom position like this:

Code: Select all

		public Form1()
		{
			InitializeComponent();
			InitializeChart();
		}

		private void InitializeChart()
		{
			line1.FillSampleValues();

			tChart1.Draw();

			int tmp = tChart1.Legend.Left;
			Rectangle tmpRect = tChart1.Chart.ChartRect;

			tChart1.Legend.CustomPosition = true;
			tChart1.Legend.Left = tmp;
			tChart1.Legend.Top = tmpRect.Top;

			tChart1.Panel.MarginLeft = 20;
		}

Posted: Wed Jan 07, 2009 2:21 pm
by 14045174
Not really, since all of your custom positions are kept in pixels, not relative. When user resizes a chart or just prints it the values for custom position are totally out of sink with reality. Unfortunately, not in all cases I can catch the resize event early enough to fix it. That is the reason we cannot utilize (we'd love to) custom positioning of legend, titles, marks. We cannot use your annotation tool... Unless I am wrong, none of them provide a way to specify a relative position for the object.

Posted: Wed Jan 07, 2009 2:30 pm
by narcis
Hi UserLS,

Yes, this can be customized dynamically using the AfterDraw event like this:

Code: Select all

		public Form1()
		{
			InitializeComponent();
			InitializeChart();
		}

		private void InitializeChart()
		{
			tChart1.Dock = DockStyle.Fill;
			tChart1.Header.Text = "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz" + "\n" +
														"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz" + "\n" +
														"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz";

			tChart1.Legend.Alignment = Steema.TeeChart.LegendAlignments.Left;

			Steema.TeeChart.Styles.Line line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
			line1.FillSampleValues();

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

		void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
		{
			int tmp = tChart1.Legend.Left;
			Rectangle tmpRect = tChart1.Chart.ChartRect;

			tChart1.Legend.CustomPosition = true;
			tChart1.Legend.Left = tmp;
			tChart1.Legend.Top = tmpRect.Top;

			tChart1.Panel.MarginLeft = 20; 
		}
Notice that I'm using positions relative to other chart objects for positioning the legend so I consider this as a generic solution. Same approach can be applied to Annotation tools and other TeeChart objects.

Posted: Wed Jan 07, 2009 2:45 pm
by 14045174
Can you please fix the bug instead? What you suggest is to look at all thousands of graphs my users create, find those, which have this problem, fix them, using custom position, but on the user's side pretend, that I am not using a custom position... It is too complicated.

Posted: Wed Jan 07, 2009 3:22 pm
by narcis
Hi UserLS,

We will put your request for revision in a future version. However, this kind of chart header is not very common. In the meantime you can also automatically calculate a vertical offset like this:

Code: Select all

		public Form1()
		{
			InitializeComponent();
			InitializeChart();
		}

		private void InitializeChart()
		{
			tChart1.Dock = DockStyle.Fill;
			tChart1.Header.Text = "abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz" + "\n" +
														"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz" + "\n" +
														"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz";

			tChart1.Legend.Alignment = Steema.TeeChart.LegendAlignments.Left;

			Steema.TeeChart.Styles.Line line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
			line1.FillSampleValues();

			tChart1.BeforeDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_BeforeDraw);		
		}

		void tChart1_BeforeDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
		{
			int numHeaderLines = tChart1.Header.Lines.GetUpperBound(0) + 1;
			int topMargin = (int)(tChart1.Panel.MarginTop * tChart1.Bounds.Height / 100.0);
			int headerHeight = topMargin + (tChart1.Graphics3D.FontTextHeight(tChart1.Header.Font) * numHeaderLines);
			int headerPercent = (int)(headerHeight / (tChart1.Bounds.Height / 100.0));
			tChart1.Legend.TopLeftPos = headerPercent;
		}

Posted: Wed Jan 07, 2009 4:21 pm
by 14045174
Thank you! This kind of solves the problem. It does not account any space taken by frame around the header, or its shadow. Also, if I am using Subheader, there is a gap between it and the header, as well as another gap between header / subheader and the graph itself. It will probably be better to find where the graph itself starts... But the real problem is that the Top/Left offset is one of the properties user can change... I probably will reset it only if the user sets it to the value, smaller, then I've calculated. But, then what should I do when screen is just resized?.. Anyway, this is a solution. THANKS!!!

Posted: Wed Jan 07, 2009 5:17 pm
by 14045174
Another problem here, which will not be taken care of by your fix: when legend is vertical, the header and subheader (I would assume that footers follow this pattern) are trying to align to the edge of the legend, which places them in an unpredictable location.

Try to have your legend on your right and align subhesder to the right - I expect it to be on the right side of the graph, but it hangs out somewhere in the middle. Aligning to the center seems to have calculation problems - it is clearly not on the center!