Hi,
I'm using a stacked column chart and would like to set the X2 axis labels to values from a column in a datatable that I am binding the chart to. The X axis seems to bind to the first column by default.
My chart is attached (I hope).
My datatable looks like
dt.Columns.Add("UserId", typeof(System.String));dt.Columns.Add("Percentage", typeof(System.String));dt.Columns.Add("DepartedSales", typeof(System.Double));dt.Columns.Add("ForwardSales", typeof(System.Double));dt.Columns.Add("Target", typeof(System.Double));
At the moment the first column appears on both X and X2 axis, but I want the 2nd column "Percentage" to appear on the X2 axis whilst keeping "UserId" on the X axis.
Is there a way to do this?
Thanks,
James.
to do this, you have to create a class that implements IRenderLabel and set it up to handle the X2 axis formatstring. this class should store a reference to the chart's datasource, and use the current data row to get the value from the Percentage column.
string IRenderLabel.ToString(Hashtable context)
{
int row = (int)context["DATA_ROW"];
return this.theData.Rows[row]["Percentage"].ToString();
}
Thanks for that David.
I have looked at your suggestion, and combined it with Sung Kim's "Chart University 101" blog post to get the following code, but I am doing something wrong, or missing something, because I still do not get X2 axis labels.
My IRenderLabel is as follows:
namespace IGWebChart{ class CustomX2AxisLabelRenderer : IRenderLabel { private DataTable dtChart; // constructor public CustomX2AxisLabelRenderer() { } // constructor public CustomX2AxisLabelRenderer(DataTable dtChart) { this.dtChart = dtChart; } public string ToString(Hashtable context) { int i = (int)context["DATA_ROW"]; return this.dtChart.Rows[i]["Percentage"].ToString(); } }}
And I am using it like this:
public void SetAllProperties(DataTable dtSource) { uwcNationalPax.DataSource = dtSource; uwcNationalPax.DataBind(); IGWebChart.CustomX2AxisLabelRenderer x2AxisLabelRenderer = new IGWebChart.CustomX2AxisLabelRenderer(dtSource); Hashtable htLabel = new Hashtable(); htLabel.Add("X2AXIS_LABEL", x2AxisLabelRenderer); uwcNationalPax.LabelHash = htLabel; //uwcNationalPax.Axis.X2.Labels // hides series labels uwcNationalPax.Axis.X2.Labels.SeriesLabels.Format = Infragistics.UltraChart.Shared.Styles.AxisSeriesLabelFormat.None; //uwcNationalPax.Axis.X2.NumericAxisType = Infragistics.UltraChart.Shared.Styles.NumericAxisType.Linear; uwcNationalPax.Axis.X2.Labels.ItemFormat = Infragistics.UltraChart.Shared.Styles.AxisItemLabelFormat.Custom; uwcNationalPax.Axis.X2.Labels.ItemFormatString = "<X2AXIS_LABEL>"; // top horizontal axis uwcNationalPax.Axis.X2.Visible = true; }
When I run the code I get no errors. The constructor is called and the datatable is passed in, but the ToString() method is never called (or at least the debugging breakpoint is not hit). As you can see from the commented out lines I have tried to hide the Axis SeriesLabel but I'm not sure if I am supposed to be doing this. if I don't hide it, it defaults to the userId that appears (correctly) on the X axis.
A little bit more help on this would be greatly appreciated.
James
Thanks again David.
I've got it working now. You were right about context["DATA_ROW"], it wasn't in the hashtable, so I'm using the ["SERIES_LABEL"] value to get the correct datarow. My final code is as follows:
public void SetAllProperties(DataTable dtSource) { uwcNationalPax.DataSource = dtSource; uwcNationalPax.DataBind(); // set up custom labels for X2 axis IGWebChart.CustomX2AxisLabelRenderer x2AxisLabelRenderer = new IGWebChart.CustomX2AxisLabelRenderer(dtSource); Hashtable htLabel = new Hashtable(); htLabel.Add("X2AXIS_LABEL", x2AxisLabelRenderer); uwcNationalPax.LabelHash = htLabel; uwcNationalPax.Axis.X2.Labels.SeriesLabels.Format = Infragistics.UltraChart.Shared.Styles.AxisSeriesLabelFormat.Custom; uwcNationalPax.Axis.X2.Labels.SeriesLabels.FormatString = "<X2AXIS_LABEL>"; // top horizontal axis uwcNationalPax.Axis.X2.Visible = true; }
and
namespace IGWebChart{ class CustomX2AxisLabelRenderer : IRenderLabel { private DataTable dtChart; // constructor public CustomX2AxisLabelRenderer(){} // constructor public CustomX2AxisLabelRenderer(DataTable dtChart) { this.dtChart = dtChart; } public string ToString(Hashtable context) { String userName = context["SERIES_LABEL"].ToString(); String returnValue = "No Data"; for (int i = 0; i < dtChart.Rows.Count; i++) { if (dtChart.Rows[i]["UserId"].ToString() == userName) { returnValue = String.Format("{0} %", dtChart.Rows[i]["Percentage"]); break; } } return returnValue; } }}
this.ultraChart1.Axis.X2.Labels.ItemFormatString = "";this.ultraChart1.Axis.X2.Labels.SeriesLabels.FormatString = "<X2AXIS_LABEL>";
since this is a stacked chart, there are series labels and no item labels on the x and x2 axes.
also, i think context["DATA_ROW"] will actually be null in this context, but you will have context["SERIES_LABEL"] to look up the row you need.