I have a composite scatterchart that produces several lines (ConnectWithLines=true) series. I have created a single X Axis to use on each of thes series and added an IRenderLabel class to this axis:
MyLabelHashTable.Add("X_LABEL",XAxisRenderer);
xAxisLine.Labels.ItemFormat = AxisItemLabelFormat.Custom
xAxisLine.Labels.ItemFormatString = "<X_Label>";
My input Dataseries is an XYSeries:
ChartLayerAppearance
CL_Line = new ChartLayerAppearance();
thisSeries.Data.DataSource = dataseries;
thisSeries.Data.ValueXColumn = ValueXColumn;
thisSeries.Data.ValueYColumn = ValueYColumn;
thisSeries.Data.LabelColumn = labelColumn;
thisSeries.Label = dataseries.TableName;
thisSeries.DataBind();
mychart.Series.Add(thisSeries);
CL_Line.ChartType =
ChartType.ScatterChart;
In my XLabelRender class I see 12 items in my context array in the ToString(). 1 is the data_value. However I would like to get both the X value and Y value to format my X label string but cannot not seem to find them. I would expect to see an X value and Y Value since its a scatterchart type. Am I missing something?
Thanks Petia,
Using your example, I was able to map the context["DATA_VALUE"] , which was my X point, to the date value that wanted. I passed my input DataSet to the XAxisRender class as a property and was able to access the Data column that way.
Hi Chris,
For a scatter chart both the x and y axis are numeric which is why there is no item, label or series equivalent at each of the tickmarks.This is the reason why the context["ITEM_LABEL"] in the IRenderLabel object of an axis Label is null - you can access only the DATA_VALUE of the axis in the axis' Label. The LabelColumn value could be accessed only per data point value, i.e. when you set a ChartText Labels. Find a sample code demonstrating the ChartText usage at the end of the post.
Regarding custom setting of an axis labels value, you could set a custom range of the axis and use a custom token by IRenderLabel. This allows you to post any string that you want. In the following example, we have demonstrated this to you for the Y axis labels. In the sample we have set the TickMarkStyle to DatInterval of the Y axis and the TickmarkInterval to 1 to be sure that on every tick there will be an equivallent Label data in the table so we could return it. Note that if you comment this two settings for the Y axis, there will have ticks' values with unequivallent Y data value, in which cases we just return the y value for the label. You could return whatever you need as a label.
using System;using Infragistics.UltraChart.Shared.Styles;using Infragistics.UltraChart.Resources.Appearance;using System.Data;using Infragistics.UltraChart.Resources;using System.Collections;using Infragistics.WebUI.UltraWebChart;public partial class _Default : System.Web.UI.Page{ private UltraChart UltraChart1; private static DataTable table; private static DataTable GetTable() { if (table == null) { //Setup DataSource Array dataList = Array.CreateInstance(typeof(MyData), 5); for (int i = 0; i < 5; i++) { dataList.SetValue(new MyData(DateTime.Now.AddMonths(i), (double)(i * 10 + i * 0.1), (double)i), i); } table = new DataTable(); table.Columns.Add("name", typeof(string)); table.Columns.Add("Date", typeof(DateTime)); table.Columns.Add("ValueX", typeof(double)); table.Columns.Add("ValueY", typeof(double)); int index = 0; foreach (MyData data in dataList) { table.Rows.Add(new object[] { index.ToString(), data.Date, data.ValueX, data.ValueY }); index++; } } return table; } protected void Page_Load(object sender, EventArgs e) { UltraChart1 = new UltraChart(); DataTable t = GetTable(); double minY = (double) t.Rows[0]["ValueY"];// we know that the min value is the first item double maxY = (double)t.Rows[t.Rows.Count - 1]["ValueY"]; //and the max is the last XYSeries series = new XYSeries(); series.Data.ValueXColumn = "ValueX"; series.Data.ValueYColumn = "ValueY"; series.Data.LabelColumn = "Date"; series.Data.DataSource = t; series.DataBind(); UltraChart1.Series.Add(series); //Setup Chart UltraChart1.ChartType = ChartType.ScatterChart; UltraChart1.ScatterChart.ConnectWithLines = true; //Setup X Axis UltraChart1.Axis.X.Labels.ItemFormatString = "<X_LABEL>"; UltraChart1.Axis.X.LineThickness = 1; UltraChart1.Axis.X.Labels.ItemFormat = AxisItemLabelFormat.Custom; UltraChart1.Axis.X.Labels.Orientation = TextOrientation.Horizontal; UltraChart1.Axis.X.TickmarkStyle = AxisTickStyle.Smart; UltraChart1.Axis.X.TimeAxisStyle.TimeAxisStyle = RulerGenre.Continuous; UltraChart1.Axis.X.Labels.Orientation = TextOrientation.VerticalLeftFacing; //Setup Y Axis UltraChart1.Axis.Y.Labels.ItemFormatString = "<Y_LABEL>"; UltraChart1.Axis.Y.LineThickness = 1; UltraChart1.Axis.Y.Labels.ItemFormat = AxisItemLabelFormat.Custom; UltraChart1.Axis.Y.Labels.Orientation = TextOrientation.Horizontal; UltraChart1.Axis.Y.RangeType = AxisRangeType.Custom; UltraChart1.Axis.Y.RangeMin = minY; UltraChart1.Axis.Y.RangeMax = maxY; UltraChart1.Axis.Y.TickmarkStyle = AxisTickStyle.DataInterval; UltraChart1.Axis.Y.TickmarkInterval = 1; //Setup Item Labels UltraChart1.ScatterChart.ChartText.Add(new ChartTextAppearance()); UltraChart1.ScatterChart.ChartText[0].Visible = true; UltraChart1.ScatterChart.ChartText[0].Column = -2; UltraChart1.ScatterChart.ChartText[0].Row = -2; UltraChart1.ScatterChart.ChartText[0].ItemFormatString = "<MY_VALUE>"; Hashtable MyLabelHashTable = new Hashtable(); MyLabelHashTable.Add("MY_VALUE", new MyLabelRenderer()); MyLabelHashTable.Add("X_LABEL", new XAxisRenderer()); MyLabelHashTable.Add("Y_LABEL", new YAxisRenderer()); UltraChart1.LabelHash = MyLabelHashTable; this.Controls.Add(this.UltraChart1); } public class XAxisRenderer : IRenderLabel { #region IRenderLabel Members public string ToString(Hashtable context) { string value = context["DATA_VALUE"].ToString(); //here the context["ITEM_LABEL"] is null as we have //a scatter axis which is a numeric axis return value; } #endregion } public class YAxisRenderer : IRenderLabel { #region IRenderLabel Members public string ToString(Hashtable context) { //here the context["ITEM_LABEL"] is null as we have //a scatter axis which is a numeric axis double value = (double)context["DATA_VALUE"]; DataTable t = GetTable(); if (t != null && value != null) { foreach (DataRow row in t.Rows) { if ((double)row["ValueY"] == value) { return row["Date"].ToString(); } } } return value.ToString(); } #endregion } public class MyLabelRenderer : IRenderLabel { public string ToString(Hashtable context) { string xValue = context["DATA_VALUE_X"].ToString(); string yValue = context["DATA_VALUE_Y"].ToString(); return xValue.ToString() + " x " + yValue.ToString(); } } class MyData { public MyData(DateTime date, double valueX, double valueY) { this.date = date; this.valueX = valueX; this.valueY = valueY; } private DateTime date; public DateTime Date { get { return this.date; } set { this.date = value; } } private double valueX; public double ValueX { get { return this.valueX; } set { this.valueX = value; } } private double valueY; public double ValueY { get { return this.valueY; } set { this.valueY = value; } } }}
Hi Petia,
I am trying another way to obtain/calulate the value that I need and this might be simpilier.
What I am trying to accomplish is very similar to this post:
https://ko.infragistics.com/community/forums/f/ultimate-ui-for-windows-forms/20848/text-labels-on-the-x-axis-in-a-scatter-chart/113800#113800
This chart has 5 XYSeries with with its ScatterChartAppearance .ConnectWithLines=true.
The XYSeries has its Data.ValueXColumn and Data.ValueYColumn set to the columns containing the points, which works as expected. I also set the Data.LabelColumn = the date Column in the DataTable (which I was trying to obatain using both the X and Y datapoints).
I have been using an IRenderLabel class to customize the spacing and text of the XAxis. Each of my 5 ChartLayerAppearances use the same X Axis which has the IRenderLabel class: xAxisLine.Labels.ItemFormatString = "<X_LABEL>"
In my ToString() method I was expecting to see the value of the series LabelColumn in the Context[ITEM_LABEL] but it is null.
I tried to set my ChartText ItemFormatString to use the IRenderLabel Class like you suggested but it never called the ToString() method.
By the Way- the time you see on the chart: 11:03 is just a placeholder (the current time) until I can get the correct value.
Hi,
I'm not sure what exactly you want to achieve. If you set an IRenderLabel object to an axis Labels, you have access only to the axis values which depends on the axis type. If you want to access both X value and the Y value, you could do it only in the data points labels, i.e. when setting the ChartText ItemFormatString to an IRenderLabel object:
this.UltraChart1.ScatterChart.ChartText[0].Visible = true;this.UltraChart1.ScatterChart.ChartText[0].Column = -2;this.UltraChart1.ScatterChart.ChartText[0].Row = -2;this.UltraChart1.ScatterChart.ChartText[0].ItemFormatString = "<MY_VALUE>";Hashtable MyLabelHashTable = new Hashtable();MyLabelHashTable.Add("MY_VALUE", new MyLabelRenderer());this.UltraChart1.LabelHash = MyLabelHashTable;
Here is a sample IRenderLabel class declaration:
public class MyLabelRenderer : IRenderLabel { public string ToString(Hashtable context) { string xValue = context["DATA_VALUE_X"].ToString(); string yValue = context["DATA_VALUE_Y"].ToString(); return xValue.ToString() + " x " + yValue.ToString(); } }
Let me know if you have further questions.
The steps you need to take is in the construction of the label class pass a copy of the data based on the context of the Row and the Column values. This way you would know which row you are on and create a custom label. Also I would like to know why you are using a composite chart?Please send me regarding any questions.
Magued