Page 1 of 1
Custom Legend
Posted: Tue Oct 02, 2007 9:35 pm
by 9794065
We need to have a custom legend. We would like to show grouping of Series's. Need to have a combobox at the bottom of the series rectangle that allows the user to turn on and off certain types of series's based on some business logic that is custom to our application.
I have investigated 2 approaches.
1. Inherit from the the Legend class, but the TChart.Legend does not have a setter. I tried adding a Setter to the TChart.Legend Property in our copy of the V3 source. The flow of the code really does not appear to accommodate an outside class making assignment of the Legend because the Legend is initialized within the TChart constructor and it interacts with the TChart.Chart object during this intiialization.
2. Creating a user control, called TccLegend, that will do what I would like. It simply inherits from System.Drawing.UserControl. This implementation will cause the TChart Export functionality to not include this control and then there is the issue of sizing the chart and the TccLegend control. This has several problems to overcome. I would have to figure out and modify the layout code.
After more analysis, I am more convinced that I will need to implement Option #2. Given that, I would like this new control be embedded on the drawing surface of the chart, very similar to the built in legend.
Could you recommend an approach that would be the least painful or maybe something I have not considered?
Posted: Thu Oct 04, 2007 11:36 am
by narcis
Hi Mike,
You could use ExtraLegend tool. Also, there's series groups and then there are the legend events for symbols, text, etc.
However you can also do something like this:
Code: Select all
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Steema.TeeChart;
using Steema.TeeChart.Styles;
namespace CustomLegend
{
public partial class Form1 : Form
{
private Bar bar1;
private TChart tChart1;
public Form1()
{
InitializeComponent();
InitializeChart();
}
private void InitializeChart()
{
tChart1 = new TChart();
tChart1.Width = 600;
tChart1.Height = 400;
Controls.Add(tChart1);
tChart1.Series.Add(bar1 = new Bar());
bar1.FillSampleValues();
MyLegend leg = new MyLegend(tChart1.Chart);
Steema.TeeChart.Tools.ExtraLegend extraLeg = new Steema.TeeChart.Tools.ExtraLegend(tChart1.Chart);
extraLeg.Legend = leg;
extraLeg.Series = bar1;
tChart1.Legend.Visible = false;
tChart1.Tools.Add(extraLeg);
}
}
}
Where MyLegend.cs looks like this:
Code: Select all
using System;
using System.Collections.Generic;
using System.Text;
namespace Steema.TeeChart
{
public class MyLegend : Legend
{
public MyLegend(Chart c) : base(c)
{
}
public MyLegend() : this((Chart)null) { }
public override void Paint(Steema.TeeChart.Drawing.Graphics3D g, System.Drawing.Rectangle rect)
{
base.Paint(g, rect);
g.TextOut(ShapeBounds.X, ShapeBounds.Y, "Hello");
}
}
}
Hope this helps!
How would you create a combobox
Posted: Fri Oct 05, 2007 2:46 pm
by 9794065
How would you add a control to the ExtraLegend?
I would like to have a combobox in the legend. It does not appear obvious to me how I can accomplish this?
Is there a way you can add standard windows controls to the legend or do I have to draw everything myself?
Re: How would you create a combobox
Posted: Mon Oct 08, 2007 1:00 pm
by Chris
Hello Mike,
Mike Jones wrote:How would you add a control to the ExtraLegend?
I would like to have a combobox in the legend. It does not appear obvious to me how I can accomplish this?
Is there a way you can add standard windows controls to the legend or do I have to draw everything myself?
Sure. TeeChart for .NET uses a standard '.NET' technique for drawing its checkboxes (when CheckBoxes = true).
Open up teechart.dll in Reflector (
http://www.aisto.com/roeder/dotnet/) and I'll take you through how it's done.
Navigate to Steema.TeeChart.Legend.DrawLegendItem(int ItemIndex, int ItemOrder) and about 2/3 down this method you will see a call to Utils.DrawCheckBox(). This method draws a checkbox to the Legend using the .NET class ControlPaint, which also contains methods to draw other common winform controls. The mouseclicks for the checkboxes are handled in the Steema.TeeChart.Legend.DoMouseDown(int x, int y) method.
Source Code
Posted: Mon Oct 08, 2007 1:59 pm
by 8739068
I have the source code. So I was able to look at the actual implementation.
Your previous post is good for everyone and is a good technique to view the inner workings of an assembly.
Thanks for pointing me in the right direction.
Another approach
Posted: Mon Oct 08, 2007 9:52 pm
by 8739068
After a discussion with other developers on my team, we thought of a technique that could save us some real estate by not showing a legend at all.
Is there a way to automatically have an Annotation Callout that will place some text on or very close to the series drawn on the graphing part of the chart?
I looked at the Annotation Callout, but it looks like we would have to figure where to place the callout. We have seen in other charting packages where there is some intelligence in placing the call outs so that they do not overlap.
Specific to our situation, we are creating styles, Series.Points and Series.Points3D, where we are adding arrays of 1000's of points. We will have 2 or more series's visible at a time. They will be of different color. It would be great if there was a callout on each series that is visible for identification purposes. It would be nice if the user could drag these around and that we could support a right click menu on these callouts as well.
I know it would be easy to place a callout near the middle by dividing the number of points by 2 to get an index of the middle point, but that is a little to simplistic. Ideally there would be a little layout logic to prevent overlapping of callouts. Do you know of a way to accomplish this?
Posted: Tue Oct 09, 2007 7:37 am
by narcis
Hi Mike,
In that case the easiest way to achieve what you request would be using series marks with a DragMarks tool. You can set all marks to an empty string to make them not visible except for those you want visible. For clicking feature you can use marks Clicked method in the MouseDown event for example:
To avoid marks overlap you can do something as my colleague Pep suggested
here.