Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
325
Composite Chart Layer Order
posted

Hi,

I'm trying to do some layering work, and before my 2 charts are rendered need to place some boxes on the chart.  I've been reading up on chart layers and ordering trying to follow a few examples by creating 3 layers and adding them to the chart, then setting the layer order using UserLayerIndex and then implementing FillSceneGraph to draw the boxes I need in my custom layer .

The code I'm using is as follows:

void RenderCompositeChart(UltraChart chart, DataTable ColumnLineData, DataTable LineData, double StartAtY1, double EndAtY1, double StartAtY2, double EndAtY2, int

PageID)

{

 

 

// Combine the two existing data sets into a single dataset for the IG composite

 

 

// chart to use

 

 

DataTable

CombinedTable = RenderCombinedAxisDataTable(ColumnLineData, LineData);

chart.ChartType =

 

ChartType

.Composite;

 

 

ChartArea area = new ChartArea

();

chart.CompositeChart.ChartAreas.Add(area);

 

 

AxisItem xAxisColumn = new AxisItem(chart, AxisNumber

.X_Axis);

 

 

AxisItem xAxisLine = new AxisItem(chart, AxisNumber

.X_Axis);

 

 

AxisItem yAxis = new AxisItem(chart, AxisNumber

.Y_Axis);

 

 

AxisItem y2Axis = new AxisItem(chart, AxisNumber

.Y2_Axis);

xAxisColumn.DataType =

 

AxisDataType

.String;

xAxisColumn.SetLabelAxisType =

 

SetLabelAxisType

.GroupBySeries;

xAxisColumn.Labels.ItemFormat =

 

AxisItemLabelFormat

.ItemLabel;

xAxisLine.DataType =

 

AxisDataType

.String;

xAxisLine.SetLabelAxisType =

 

SetLabelAxisType

.ContinuousData;

yAxis.DataType =

 

AxisDataType

.Numeric;

yAxis.Labels.ItemFormat =

 

AxisItemLabelFormat

.DataValue;

yAxis.LineThickness = 1;

y2Axis.DataType =

 

AxisDataType

.Numeric;

y2Axis.Labels.ItemFormat =

 

AxisItemLabelFormat

.DataValue;

y2Axis.LineThickness = 1;

area.Axes.Add(xAxisColumn);

area.Axes.Add(xAxisLine);

area.Axes.Add(yAxis);

area.Axes.Add(y2Axis);

 

 

// Define two chart layers for drawing on

 

 

ChartLayerAppearance ColumnLayer = new ChartLayerAppearance

();

ColumnLayer.Key =

 

"ColumnLayer"

;

 

 

ChartLayerAppearance LineLayer = new ChartLayerAppearance

();

LineLayer.Key =

 

"LineLayer"

;

 

 

// Now, define the series for each layer... best way to do this

 

 

// is to iterate the measures and determine which axis it has been

 

 

// assigned to...

 

 

int

maIndex = -1;

 

 

foreach (MeasureAxis ma in

_gadget.MeasureAxis)

{

maIndex++;

 

 

// Define a series for the relevant column in the data table

 

 

NumericSeries maSeries = new NumericSeries

();

maSeries.Data.DataSource = CombinedTable;

maSeries.Label = ma.Name;

maSeries.Data.LabelColumn = CombinedTable.Columns[CombinedTable.Columns.Count - 1].ColumnName;

maSeries.Data.ValueColumn = CombinedTable.Columns[maIndex].ColumnName;

 

 

// Assign the series to the correct chart layer

 

 

if (ma.LayerAssignment == MeasureChartAssignment

.ASSIGNTO_LAYER1)

{

chart.Series.AddRange(

 

new ISeries

[] { maSeries });

ColumnLayer.Series.Add(maSeries);

 

 

if

(_gadget.Stacked)

{

 

 

DataColumn

colSeries = CombinedTable.Columns[maIndex];

 

 

double

colStackMinimum = 0;

 

 

double

colStackTotal = 0;

ValidateStackValues(colSeries,

 

ref colStackMinimum, ref

colStackTotal);

StartAtY1 =

 

Math

.Min(StartAtY1, colStackMinimum);

EndAtY1 =

 

Math

.Max(EndAtY1, colStackTotal);

}

}

 

 

else

{

chart.Series.AddRange(

 

new ISeries

[] { maSeries });

LineLayer.Series.Add(maSeries);

}

}

 

 

// Define the properties of each of the chart layers

ColumnLayer.AxisX = xAxisColumn;

ColumnLayer.AxisY = yAxis;

ColumnLayer.ChartArea = area;

 

 

if

(_gadget.Stacked)

{

ColumnLayer.ChartType =

 

ChartType

.StackColumnChart;

 

 

if (_gadget.Stacked100 == true

)

{

chart.StackChart.StackStyle =

 

StackStyle

.Complete;

}

}

 

 

else

{

ColumnLayer.ChartType =

 

ChartType

.ColumnChart;

}

ColumnLayer.ChartArea.PE.StrokeOpacity = 50;

LineLayer.AxisX = xAxisLine;

LineLayer.AxisY = y2Axis;

LineLayer.ChartArea = area;

LineLayer.ChartType = (_gadget.UseSmoothCurve ?

 

ChartType.SplineChart : ChartType

.LineChart);

chart.CompositeChart.ChartLayers.Add(ColumnLayer);

chart.CompositeChart.ChartLayers.Add(LineLayer);

chart.ColumnChart.SeriesSpacing = 0;

 

 

ChartLayerAppearance gridLayer = new ChartLayerAppearance

();

gridLayer.Key =

 

"GridRangeLayer"

;

chart.CompositeChart.ChartLayers.Add(gridLayer);

 

 

//Set the colour scheme for the chart

ApplyChartPalette(chart);

chart.Border.Thickness = 0;

chart.ColumnChart.NullHandling = Infragistics.UltraChart.Shared.Styles.

 

NullHandling

.DontPlot;

 

 

//Setting tooltip for chart

SetToolTip(chart);

 

 

CompositeLegend ColumnLegend = new CompositeLegend

();

ColumnLegend.ChartLayers.Add(ColumnLayer);

 

 

CompositeLegend LineLegend = new CompositeLegend

();

LineLegend.ChartLayers.Add(LineLayer);

chart.CompositeChart.Legends.Add(ColumnLegend);

chart.CompositeChart.Legends.Add(LineLegend);

 

 

// Reserve a 20% space for the legend

ResizeChart(chart);

 

 

int

FontSize = 12;

 

 

// Formatting, formatting, formatting! Let's try and tidy these suckers up!

 

 

Font verdana = new Font("Verdana", FontSize, GraphicsUnit.Pixel);

// I18CHECKED

chart.Axis.X.Labels.Font = verdana;

chart.Axis.Y.Labels.Font = verdana;

chart.Axis.Y2.Labels.Font = verdana;

 

 

// Make the legend 2 points smaller for now

 

 

Font legVerdana = new Font("Verdana", FontSize - 2, GraphicsUnit.Pixel);

// I18CHECKED

ColumnLegend.LabelStyle.Font = legVerdana;

LineLegend.LabelStyle.Font = legVerdana;

 

 

// Tickmark style cannot be set to 'Smart' (bug logged as CAS-04642-NCZJWZ) when range limits have been set. I have therefore lifted the smart calibration algorithm from infragistics

 

 

// so I can still use it

 

 

double

interval = 0;

 

 

double

interval1 = 0;

 

 

// Perform smart scaling

AxisSmartScale(

 

ref StartAtY1, ref EndAtY1, out

interval);

AxisSmartScale(

 

ref StartAtY2, ref EndAtY2, out

interval1);

ScaleAxis(chart, yAxis, StartAtY1, EndAtY1, interval);

ScaleAxis(chart, y2Axis, StartAtY2, EndAtY2, interval1);

 

 

int EndAtY2Val = (int

)EndAtY2;

 

 

int

EndAtY2Size = FontSize * (EndAtY2Val.ToString().Length + 1);

SetLabelAppearance(xAxisColumn,

 

TextOrientation

.VerticalLeftFacing);

SetLabelAppearance(yAxis,

 

TextOrientation

.Horizontal);

SetLabelAppearance(y2Axis,

 

TextOrientation

.Horizontal);

 

 

int maxLabelWidth = GetMaxColumnLabelDimension(ColumnLineData, verdana, true

);

SetLabelInterval(chart, ColumnLineData,

 

false

, xAxisColumn);

 

 

// Work out the extents we will need to place the legends to the right of the chart

 

 

Size

szy1Legend = GetLegendDimensions(ColumnLineData, FontSize - 2);

 

 

Size

szy2Legend = GetLegendDimensions(LineData, FontSize - 2);

 

 

// Which legend is going to be bigger, we will use that as our extent for the y-Axis'

 

 

int

yAxisExtent = (szy1Legend.Width > szy2Legend.Width ? szy1Legend.Width : szy2Legend.Width);

y2Axis.Extent = yAxisExtent;

 

 

BorderAppearance LegendBorder = new BorderAppearance

();

LegendBorder.Thickness = 0;

 

 

// This code is left in, in case we ever need to refer to the creation of a legend

 

 

// for the column data. It's been turned off for now because it's unnecessary given the

 

 

// current x-axis label display

ColumnLegend.Bounds =

 

new Rectangle

((width + EndAtY2Size) - yAxisExtent, 10, yAxisExtent - EndAtY2Size, szy1Legend.Height + 1);

ColumnLegend.BoundsMeasureType =

 

MeasureType

.Pixels;

ColumnLegend.Border = LegendBorder;

ColumnLegend.Visible =

 

false

;

 

 

if

(ColumnLegend.Visible)

{

LineLegend.Bounds =

 

new Rectangle

((width + EndAtY2Size) - yAxisExtent, szy1Legend.Height + 35, yAxisExtent - EndAtY2Size, szy2Legend.Height + 3);

}

 

 

else

{

LineLegend.Bounds =

 

new Rectangle

((width + EndAtY2Size) - szy2Legend.Width, 10, szy2Legend.Width - EndAtY2Size, szy2Legend.Height + 3);

 

 

// Reset the extent available to the legend to the Y2 axis one only

y2Axis.Extent = szy2Legend.Width;

}

LineLegend.BoundsMeasureType =

 

MeasureType

.Pixels;

LineLegend.Border = LegendBorder;

 

 

BorderAppearance ChartBorder = new BorderAppearance

();

ChartBorder.Thickness = 0;

chart.Border = ChartBorder;

chart.Visible =

 

true

;

 

 

// Shade differently any bars according to range or selection information

 

 

//chart.ChartDrawItem += new Infragistics.UltraChart.Shared.Events.ChartDrawItemEventHandler(chart_ChartDrawItem);

chart.ChartDrawItem +=

 

delegate(Object sender, Infragistics.UltraChart.Shared.Events.ChartDrawItemEventArgs

e)

{

chart_ChartDrawItem(sender, e, PageID);

};

 

 

// Add a custom layer if we need to

 

 

if

(_gadget.Ranges.Count != 0)

{

 

 

// Modify the order of drawing the layers...

chart.UserLayerIndex =

 

new string[] { "GridRangeLayer", "Default"

};

 

 

// Add the fill scene event to the chart

chart.FillSceneGraph +=

 

new FillSceneGraphEventHandler

(CompositeChart_FillSceneGraph);

However, the final result shows the custom layer being drawn last - over the top of the 2 chart layers.  Can anyone point me in the right direction?