Page 1 of 1

Grouping on the TeeChart

Posted: Fri May 15, 2009 10:54 am
by 13047867
hi

i have a DataTable, and i want to group my chart using a specific column, i am coding in c# and this is a web project. the datatable is as follows;
------------------------------------
group | x | y
------------------------------------
101 | a | 1
102 | b | 2
101 | c | 3
103 | d | 4





private void PopulateGraph(
string sChartType,
string sSeriesName,
string sXValueDataMember,
string sYValueDataMember,
string sZValueDataMember,
string sGroupValueDataMember,
DataTable oData,
string sColor,
string sShowValue,
bool bMarkValueHorizontal,
bool bIsLeftSide,
string sYAxisPenWidth,
bool bYAxisSeparate,
string sYAxisRelativePosition,
string sYAxisTopPosition,
string sYAxisBottomPosition,
string sHide,
bool isSeriesClean,
bool isAutomatic,
string sAutomaticMin,
string sAutomaticMax,
bool bShow3D,
int[] iSubReportFields,
bool? showLegend
)
{
if (sColor == "")
{
sColor = "#ffffff";
}

int red = System.Convert.ToInt32(sColor.Substring(1, 2), 16);
int green = System.Convert.ToInt32(sColor.Substring(3, 2), 16);
int blue = System.Convert.ToInt32(sColor.Substring(5, 2), 16);

if (red == 0 && green == 0 && blue == 0)
{
blue = 1;
}

Color oColor = Color.FromArgb(
red
, green
, blue
);


if (isSeriesClean)
ch1.Series.RemoveAllSeries();

if (sXValueDataMember == "" || sYValueDataMember == "")
return;

if (oData == null)
return;

bool isXValueDate = false;
if (oData.Columns[sXValueDataMember].DataType == typeof(DateTime))
{
isXValueDate = true;
}

bool isXValueString = false;
if (oData.Columns[sXValueDataMember].DataType == typeof(string))
isXValueString = true;

IDictionary<int, string> oGraphFieldNamesDictionary = this.GetGraphFieldNames(iSubReportFields);

if (showLegend == null || (bool)showLegend == true)
{
ch1.Legend.Visible = true;
ch1.Legend.Alignment = LegendAlignments.Bottom;
ch1.Legend.Shadow.Visible = true;
ch1.Legend.LegendStyle = LegendStyles.Series;
}
else
{
ch1.Legend.Visible = false;
}


// Panel
ch1.Panel.MarginUnits = PanelMarginUnits.Percent;
ch1.Panel.MarginRight = 10;
ch1.Panel.MarginLeft = 10;

// 3D
ch1.Aspect.View3D = bShow3D;

if (!isXValueDate && !isXValueString)
{
// X Axis is a Decimal
ch1.Axes.Bottom.Labels.ValueFormat = "#.#";
}

if (isXValueDate)
{
ch1.Axes.Bottom.Labels.DateTimeFormat = "dd/MM/yy HH:mm";
}

ch1.Axes.Bottom.Title.Caption = oGraphFieldNamesDictionary[iSubReportFields[0]]; // X Axis Name
ch1.Axes.Left.Title.Angle = 90;
ch1.Axes.Bottom.Title.Font.Color = Color.Black;
ch1.Axes.Bottom.Title.Font.Bold = true;

// Axis
Axis axis1 = null;
if (bYAxisSeparate)
{
axis1 = new Axis();
axis1.Horizontal = false;
axis1.StartPosition = double.Parse(sYAxisTopPosition);
axis1.EndPosition = double.Parse(sYAxisBottomPosition);
axis1.RelativePosition = -double.Parse(sYAxisRelativePosition);

if (isAutomatic)
{
axis1.Automatic = true;
axis1.AutomaticMinimum = true;
axis1.AutomaticMaximum = true;
}
else
{
axis1.Automatic = false;
axis1.Minimum = double.Parse((string.IsNullOrEmpty(sAutomaticMin) ? "0" : sAutomaticMin));
axis1.Maximum = double.Parse((string.IsNullOrEmpty(sAutomaticMax) ? "0" : sAutomaticMax));
}

axis1.AxisPen.Color = oColor;
axis1.Title.Font.Color = oColor;
axis1.Title.Font.Bold = true;
axis1.Title.TextAlign = StringAlignment.Near;
axis1.OtherSide = !bIsLeftSide;

axis1.Title.Caption = oGraphFieldNamesDictionary[iSubReportFields[1]]; // custom Y Axis Name
axis1.Title.Angle = 90;
axis1.Title.Font.Color = Color.Black;

axis1.AxisPen.Width = int.Parse(sYAxisPenWidth);
axis1.PositionUnits = PositionUnits.Pixels;
axis1.Visible = true;


foreach (Axis oAxis in ch1.Axes.Custom)
{
// merge axes
double fRelativePosition = oAxis.RelativePosition;
bool isOtherSide = oAxis.OtherSide;
string sAxisTitle = oAxis.Title.Caption;

if (fRelativePosition == -double.Parse(sYAxisRelativePosition)) // Control Relative Position
{
if (isOtherSide ^ bIsLeftSide)
{
axis1 = oAxis;
axis1.Title.Caption += @" \ " + oGraphFieldNamesDictionary[iSubReportFields[1]];
}
else
{
;
}
}
}

ch1.Axes.Custom.Add(axis1);
}

if (!bYAxisSeparate)
{
if (bIsLeftSide)
{
if (!string.IsNullOrEmpty(ch1.Axes.Left.Title.Caption))
ch1.Axes.Left.Title.Caption += "/";

ch1.Axes.Left.Title.Caption += oGraphFieldNamesDictionary[iSubReportFields[1]]; // Y Axis Name
ch1.Axes.Left.Title.Font.Color = Color.Black;
ch1.Axes.Left.Title.Font.Bold = true;

}
else
{
if (!string.IsNullOrEmpty(ch1.Axes.Right.Title.Caption))
ch1.Axes.Right.Title.Caption += "/";

ch1.Axes.Right.Title.Caption += oGraphFieldNamesDictionary[iSubReportFields[1]]; // Y Axis Name
ch1.Axes.Right.Title.Font.Color = Color.Black;
ch1.Axes.Right.Title.Font.Bold = true;
}
}

Steema.TeeChart.Styles.Series oSeries = null;

switch (sChartType)
{
case "Line":
if (!string.IsNullOrEmpty(sGroupValueDataMember))
{
PopulateWithGroupedData(oData, sXValueDataMember, sYValueDataMember, sZValueDataMember, sGroupValueDataMember, sShowValue, axis1, bMarkValueHorizontal, sChartType, oGraphFieldNamesDictionary);
}
else
{
oSeries = new Steema.TeeChart.Styles.Line();
}
break;

case "Bar":
if (!string.IsNullOrEmpty(sGroupValueDataMember))
{
PopulateWithGroupedData(oData, sXValueDataMember, sYValueDataMember, sZValueDataMember, sGroupValueDataMember, sShowValue, axis1, bMarkValueHorizontal, sChartType, oGraphFieldNamesDictionary);
}
else
{
oSeries = new Steema.TeeChart.Styles.Bar();
oSeries.DefaultNullValue = 0;
}
break;

case "Area":
oSeries = new Steema.TeeChart.Styles.Area();
oSeries.DefaultNullValue = 0;

break;

case "Pie":
oSeries = new Steema.TeeChart.Styles.Pie();

((Pie)oSeries).Circled = true;
((Pie)oSeries).Pen.Visible = true;
oSeries.DefaultNullValue = 0;

break;
case "Bubble":
oSeries = new Steema.TeeChart.Styles.Bubble();

((Bubble)oSeries).RadiusValues.DataMember = sZValueDataMember;
oSeries.DefaultNullValue = 0;

break;
case "Point":
if (!string.IsNullOrEmpty(sGroupValueDataMember))
{
PopulateWithGroupedData(oData, sXValueDataMember, sYValueDataMember, sZValueDataMember, sGroupValueDataMember, sShowValue, axis1, bMarkValueHorizontal, sChartType, oGraphFieldNamesDictionary);
}
else
{
oSeries = new Steema.TeeChart.Styles.Points();
oSeries.DefaultNullValue = 0;
}

break;
} // close switch

if (oSeries != null)
{
/*
if (oSeries is Pie)
{
((Pie)oSeries).Pen.Color = oColor;
}
*/

// ******** set default values for a series. ***** //
if (bIsLeftSide) // Left
oSeries.VertAxis = Steema.TeeChart.Styles.VerticalAxis.Left;
else // Right
oSeries.VertAxis = Steema.TeeChart.Styles.VerticalAxis.Right;

if (bYAxisSeparate) // if bYAxisSeparate true then use custom axis else use left or right axis
{
oSeries.CustomVertAxis = axis1;
}

oSeries.XValues.DateTime = isXValueDate;
oSeries.YValues.DataMember = sYValueDataMember;
oSeries.Title = sSeriesName;
oSeries.Color = oColor;
oSeries.Marks.Style = Steema.TeeChart.Styles.MarksStyles.Value;
oSeries.Marks.Visible = bool.Parse(sShowValue);

if (oSeries is Pie)
{
oSeries.LabelMember = sXValueDataMember;

if (showLegend == null || (bool)showLegend == true)
{
// Legend
ch1.Legend.Visible = true;
ch1.Legend.Shadow.Visible = true;
ch1.Legend.Alignment = LegendAlignments.Bottom;
ch1.Legend.TextStyle = LegendTextStyles.Plain;
ch1.Legend.LegendStyle = LegendStyles.Values;
}
else
{
ch1.Legend.Visible = false;
}
}
else
{
if (isXValueString)
oSeries.LabelMember = sXValueDataMember;
else
oSeries.XValues.DataMember = sXValueDataMember;
}


try
{
oSeries.DataSource = oData;
GenerateToolTip(oSeries, oGraphFieldNamesDictionary);
ch1.Series.Add(oSeries);
}
catch (Exception) { }

// Value Horizontal Or Vertical
if (!bMarkValueHorizontal)
oSeries.Marks.Angle = 90.0;

oSeries.ValueFormat = "#,##0.#";


// end ******** set default values for a series. ***** //
}

ch1.Chart.Tools.Add(seriesHotspot1);
((Steema.TeeChart.Tools.SeriesHotspot)(ch1.Chart.Tools[0])).Style = Steema.TeeChart.Styles.MarksStyles.Value;
}

private void PopulateWithGroupedData(DataTable oData, string sXValueDataMember, string sYValueDataMember, string sZValueDataMember, string sGroupValueDataMember, string sShowValue, Axis oCustomAxis, bool bMarkValueHorizontal, string sChartType, IDictionary<int, string> oGraphFieldNamesDictionary)
{
this.AddInvisibleDummySeries();

IDictionary<string, Series> oGroupDictonary = new Dictionary<string, Series>();

for (int i = 0; i < oData.Rows.Count; i++)
{
string sXValue = oData.Rows[sXValueDataMember].ToString();
string sYValue = oData.Rows[sYValueDataMember].ToString();
string sGroupValue = oData.Rows[sGroupValueDataMember].ToString();

if (oData.Columns[sXValueDataMember].DataType == typeof(DateTime))
{
DateTime dummy = DateTime.Parse(sXValue);

sXValue = dummy.ToString("dd/MM/yy HH:mm");
}

Steema.TeeChart.Styles.Series oSeries = null;

if (oGroupDictonary.ContainsKey(sGroupValue))
{
oSeries = oGroupDictonary[sGroupValue];
}
else
{
if (sChartType == "Bar")
{
oSeries = new Steema.TeeChart.Styles.Bar();
((Bar)oSeries).BarStyle = Steema.TeeChart.Styles.BarStyles.Cylinder;
}
else if (sChartType == "Line")
{
oSeries = new Steema.TeeChart.Styles.Line();
}
else if (sChartType == "Point")
{
oSeries = new Steema.TeeChart.Styles.Points();
}


oSeries.ValueFormat = "#,##0.##";

// Value Horizontal Or Vertical
if (!bMarkValueHorizontal)
oSeries.Marks.Angle = 90.0;

if (oCustomAxis != null)
{
oSeries.CustomVertAxis = oCustomAxis;
}

oSeries.Marks.Visible = bool.Parse(sShowValue);
oSeries.Marks.Style = Steema.TeeChart.Styles.MarksStyles.Value;

oSeries.Title = sGroupValue;
oDynamicChart.Chart.Series.Add(oSeries);

oGroupDictonary.Add(sGroupValue, oSeries);
}

this.addValuesToSeries(oSeries, double.Parse(sYValue), sXValue, oSeries.Color, oGraphFieldNamesDictionary);
}
}

private void AddInvisibleDummySeries()
{
// used in addValuesToSeries to add values.
Series dummyInvisibleAndTheFirstSeries = new Bar();
dummyInvisibleAndTheFirstSeries.Marks.Visible = false;
dummyInvisibleAndTheFirstSeries.Visible = true;
dummyInvisibleAndTheFirstSeries.Title = "dummyInvisibleAndTheFirstSeries";
dummyInvisibleAndTheFirstSeries.ShowInLegend = false;

oDynamicChart.Chart.Series.Add(dummyInvisibleAndTheFirstSeries);
}

private void addValuesToSeries(Series oSeries, double dYValue, string sXValue, Color oColor, IDictionary<int, string> oGraphFieldNamesDictionary)
{
if (oSeries == null)
{
throw new NullReferenceException("values can not be added to null series");
}

Series dummyInvisibleAndTheFirstSeries = oDynamicChart.Chart.Series[0];

int iCounter = oGraphIndexDictionary.Count;

if (!oGraphIndexDictionary.ContainsKey(sXValue))
{
oGraphIndexDictionary.Add(sXValue, iCounter);
oSeries.Add(iCounter, dYValue, sXValue, oColor);
dummyInvisibleAndTheFirstSeries.Add(iCounter, 0.0, sXValue, oColor);
iCounter++;
}
else
{
int index = oGraphIndexDictionary[sXValue];
oSeries.Add(index, dYValue, sXValue, oColor);
}

GenerateToolTip(oSeries, oGraphFieldNamesDictionary);
}


I'm doing by using above code sample. However, i am getting dots (or squares) at the bottom of the graph.
How else can I do this?

Thanks

Posted: Fri May 15, 2009 4:02 pm
by yeray
Hi,

Thank you for the code but it would be really helpful if you could 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 our upload page.

Also we've seen that you have a function with a DataTable parameter. So, please, take a look at this thread, where Narcis posted an example of creating a DataTable at runtime.

Grouping chart

Posted: Fri May 22, 2009 8:39 am
by 13047867
Hi Yeray. thanks for your informations.

My problem is grouping data. i have only one datatable and in the first column there may be same values. i want to show graph grouped for these values.

i have uploaded my sample project to upload page. its name is TestGrouping_sn.rar.

Posted: Fri May 22, 2009 4:04 pm
by narcis
Hello,

Thanks for the example project. We are not sure about if we understood which is the exact problem you are having. What we have found is that your application never gets into the if (oSeries != null) condition in Page_Load because oSeries is always null. This happens because you create an instance of it in Page_Load, which is never initialized and then you create another object with the very same name in PopulateWithGroupedData. This way both methods don't have any connection via those objects. My suggestion would be using a global method for the class, for example:

Code: Select all

				private Steema.TeeChart.Styles.Series oSeries;
Initialize it like this in Page_Load:

Code: Select all

						oSeries = null;
And remove oSeries declaration and initialization in PopulateWithGroupedData method.

I'll also send you your project with the modifications I suggest.

If that's not what you were looking for don't hesitate to let us know.

Posted: Mon May 25, 2009 8:06 am
by 13047867
Hi Narcis,
Thank you for your response. However this is not what i am looking for. I am sending the code with a new datatable (the before one was wrong sorry!). When you view the graph (not in 3D) from the test data you will see the points on the x-axis. The reason is that the dummy series that is created by using AddInvisibleDummySeries() method. We add that method because of putting numbers on x-axis. We want to get rid of those points on x-axis. If you have another solution that is also ok i mean you don't have to do same way we do. The purpose is that making a scatter plot graph with the grouped data and putting a logical x-axis. Another problem (not serious but good to have a solution) we have when we view the graph in 3D with a high amount of records (datatable that we sent have only 4 rows) the graph seems ridiculous. I have uploaded my sample project to upload page. Its name is TestPlotter_sn_2.rar.

Thanks

Posted: Mon May 25, 2009 11:51 am
by narcis
Hello,
Thank you for your response. However this is not what i am looking for. I am sending the code with a new datatable (the before one was wrong sorry!). When you view the graph (not in 3D) from the test data you will see the points on the x-axis. The reason is that the dummy series that is created by using AddInvisibleDummySeries() method. We add that method because of putting numbers on x-axis. We want to get rid of those points on x-axis. If you have another solution that is also ok i mean you don't have to do same way we do. The purpose is that making a scatter plot graph with the grouped data and putting a logical x-axis.


In that case I think it would be much easier removing all dummy series code and initalize your left axis like this:

Code: Select all

						chart.Axes.Left.AutomaticMinimum = false;
						chart.Axes.Left.Minimum = 0;
Another problem (not serious but good to have a solution) we have when we view the graph in 3D with a high amount of records (datatable that we sent have only 4 rows) the graph seems ridiculous. I have uploaded my sample project to upload page. Its name is TestPlotter_sn_2.rar.
I see when your chart is in 3D view several points exist at the same X,Y coordinates. What would you exactly like to get here, just a single series?

Thanks in advance.