Render2

 

In the following example we revisited the sample project where we created a Chart Object with Telerik Reporting at runtime. Every time I create Chart objects at design time, I find myself going under the hood in one way or the other, this to enhance customization. Needless to say, I am not stating that design time does not enable us for customization. However, I rather enjoy going directly to the API. My perception is that in instances this might be a faster route.

The Report – Comparing between Two Stocks

We will use a Telerik Report instance this time to compare stock price movement between two stocks. The report would then have two parameters stock1 and stock2. A method was created with a list of my favorite stocks to feed the drop-down render on these parameters.

   1: public List<Stock> GetStocks(string selectedsymbol = null)
   2: {
   3:     var symbols = new List<Stock>();
   4:     symbols.Add(new Stock { company = "TESORO", symbol = "TSO" });
   5:     symbols.Add(new Stock { company = "SOLAR CITY", symbol = "SCTY" });
   6:     symbols.Add(new Stock { company = "CONOCO PHILLIPS", symbol = "COP" });
   7:     symbols.Add(new Stock { company = "COCA COLA", symbol = "CCE" });
   8:     symbols.Add(new Stock { company = "MICROSOFT", symbol = "MSFT" });
   9:     // the below to prevent selection of the same symbol
  10:     if (selectedsymbol != null)
  11:         symbols = symbols.Where(q => q.symbol != selectedsymbol).Select(f => f).ToList<Stock>();
  12:     return symbols;
  13: }
  14: .........
  15: public class Stock
  16: {
  17:     public string company { get; set; }
  18:     public string symbol { get; set; }
  19: }

The reason for the optional parameter, it is so we can pass the already selected stock price to the stock two parameter. We do not want to end up comparing the same stock against itself. Below is the resulting view from of this task at design time. Notice in the Drop Down view of the parameter list. Coca Cola is not available for the second stock entry

ExclusionView

Report Parameter Creation

In Telerik, you could create report parameters in design view. There is plenty of documentation on this subject. Including a video on the creation of report parameters. Here is a view of the parameters I created under my report.

ParameterCreator

Accessing Parameters

Since no data source was apply in my report object, I decided to place my parameters accessor in the NeedDataSource event of my report object.

   1: private void Report_NeedDataSource(object sender, EventArgs e)
   2: {
   3:     Telerik.Reporting.Processing.Report preport = (Telerik.Reporting.Processing.Report)sender;
   4:     string stockone = preport.Parameters["StockOne"].Value.ToString();
   5:     string stocktwo = preport.Parameters["StockTwo"].Value.ToString();
   6:     int year = Convert.ToInt32(preport.Parameters["Year"].Value.ToString());
   7:  
   8:     var chartobject = ChartCreator.CompareTwoStocks(stockone, stocktwo, year);
   9:     detail.Items.Clear();
  10:     // injecting the chart
  11:     detail.Items.Add(chartobject);
  12:  
  13: }
Warning: Warning NeedDataSource will only be executed upon the absence of a DataSource on The Report Object. If an Actual Data-Source is apply to the report object, then we rather access our parameter via the ItemDataBinding or ItemDataBound.

Chart Object

In the code above you would notice that once I access the parameter I pass this to a function that would return a chart object. The chart object that will take the two stock and the year of historical prices the user desire

   1: public static Telerik.Reporting.Chart CompareTwoStocks(string _stockone, string _stocktwo, int _year)
   2: {
   3:     Telerik.Reporting.Chart mychart = new Telerik.Reporting.Chart();
   4:     mychart.Skin = "Office2007";
   5:     string[] Stocks = new string[] { _stockone, _stocktwo };
   6:     System.Drawing.Color[] seriesColor = new Color[] { Color.Red, Color.Blue };
   7:     List<HistoricalStock>[] stockitems = new List<HistoricalStock>[2];
   8:  
   9:     int size = 0;
  10:     foreach (string symbol in Stocks)
  11:     {
  12:         stockitems[size++] = new List<HistoricalStock>(YahooHistoricalLoader.DownloadData(symbol, _year).Where(f => f.Date >= new DateTime(StockChartStartYear, 1, 1)).OrderBy(t => t.Date).Select(m => m));
  13:     }
  14:  
  15:     #region XAxis and YAxis Labels
  16:     mychart.PlotArea.XAxis.AxisLabel.TextBlock.Visible = true;
  17:     mychart.PlotArea.YAxis.AxisLabel.TextBlock.Visible = true;
  18:     mychart.PlotArea.XAxis.AxisLabel.Visible = true;
  19:     mychart.PlotArea.YAxis.AxisLabel.Visible = true;
  20:     mychart.PlotArea.XAxis.AxisLabel.TextBlock.Text = "Period";
  21:     mychart.PlotArea.YAxis.AxisLabel.TextBlock.Text = "Price Per Share ($)";
  22:     mychart.PlotArea.XAxis.AxisLabel.Appearance.Position.Auto = true;
  23:     mychart.PlotArea.YAxis.AxisLabel.Appearance.Position.Auto = true;
  24:     #endregion
  25:  
  26:     mychart.ChartTitle.TextBlock.Text = string.Join(" Vs. ", Stocks) + " " + _year;
  27:     mychart.ChartTitle.TextBlock.Appearance.TextProperties.Color = Color.Blue;
  28:     #region Generate Chart Series
  29:     for (int i = 0; i < size; i++)
  30:     {
  31:         ChartSeries series = new ChartSeries();
  32:         int seriesItemPosition = 0;
  33:         foreach (HistoricalStock hs in stockitems[i])
  34:         {
  35:             ChartSeriesItem seriesItem = new ChartSeriesItem();
  36:             seriesItem.YValue = hs.Close;
  37:             seriesItem.XValue = seriesItemPosition++;
  38:             seriesItem.Label.TextBlock.Visible = false;
  39:             series.Items.Add(seriesItem);
  40:         }
  41:         series.YAxisType = (i == 0) ? ChartYAxisType.Primary : ChartYAxisType.Secondary;
  42:         series.Appearance.FillStyle.MainColor = seriesColor[i];
  43:         series.Name = Stocks[i];
  44:         series.Appearance.LegendDisplayMode = ChartSeriesLegendDisplayMode.Nothing;
  45:         series.Type = ChartSeriesType.Spline;
  46:         mychart.Series.Add(series);
  47:  
  48:     }
  49:     #endregion
  50:  
  51:     #region Custom Legend
  52:     int seq = 0;
  53:     foreach (string symbol in Stocks)
  54:     {
  55:         LabelItem LegenItem = new LabelItem();
  56:         LegenItem.Marker.Visible = true;
  57:         LegenItem.Marker.Appearance.Figure = Telerik.Reporting.Charting.Styles.DefaultFigures.Rectangle;
  58:         LegenItem.Marker.Appearance.FillStyle.MainColor = seriesColor[seq++];
  59:         LegenItem.Marker.Appearance.FillStyle.FillType = Telerik.Reporting.Charting.Styles.FillType.Solid;
  60:         LegenItem.TextBlock.Text = symbol;
  61:  
  62:         mychart.Legend.Items.Add(LegenItem);
  63:     }
  64:     #region Legend Location
  65:     mychart.Legend.Appearance.Location = Telerik.Reporting.Charting.Styles.LabelLocation.OutsidePlotArea;
  66:     mychart.Legend.Appearance.Overflow = Telerik.Reporting.Charting.Styles.Overflow.Row;
  67:     mychart.Legend.Appearance.Position.AlignedPosition = Telerik.Reporting.Charting.Styles.AlignedPositions.Bottom;
  68:     #endregion
  69:     #endregion
  70:     #region EliminateGridlines
  71:     mychart.PlotArea.YAxis.Appearance.MajorGridLines.Visible = false;
  72:     mychart.PlotArea.YAxis.Appearance.MinorGridLines.Visible = false;
  73:     mychart.PlotArea.XAxis.Appearance.MajorGridLines.Visible = false;
  74:     mychart.PlotArea.XAxis.Appearance.MinorGridLines.Visible = false;
  75:     #endregion
  76:  
  77:     #region Conguring XAxis
  78:     mychart.PlotArea.XAxis.Appearance.MinorTick.Visible = false;
  79:     mychart.PlotArea.XAxis.Appearance.MajorTick.Visible = false;
  80:     mychart.PlotArea.XAxis.Appearance.TextAppearance.TextProperties.Font = new System.Drawing.Font(FontFamily.GenericSansSerif, 6, FontStyle.Regular);
  81:     mychart.PlotArea.XAxis.LayoutMode = Telerik.Reporting.Charting.Styles.ChartAxisLayoutMode.Between;
  82:     mychart.PlotArea.XAxis.IsZeroBased = true;
  83:     mychart.PlotArea.XAxis.AutoScale = false;
  84:     mychart.PlotArea.XAxis.AddRange(1, stockitems[0].Count(), 1);
  85:     int sequence = 0;
  86:     foreach (HistoricalStock h in stockitems[0])
  87:     {
  88:  
  89:         mychart.PlotArea.XAxis[sequence].TextBlock.Text = h.Date.ToString("MMM, yyyy");
  90:         mychart.PlotArea.XAxis[sequence].TextBlock.Visible = false;
  91:         sequence++;
  92:  
  93:     }
  94:  
  95:     #endregion
  96:  
  97:     #region Scaling Chart YAxis
  98:  
  99:     mychart.PlotArea.YAxis.IsZeroBased = false;
 100:     mychart.PlotArea.YAxis.AutoScale = true;
 101:  
 102:     mychart.PlotArea.YAxis2.IsZeroBased = false;
 103:     mychart.PlotArea.YAxis2.AutoScale = true;
 104:  
 105:     #endregion
 106:  
 107:     #region Zonification
 108:     int[] ZoningSize = stockitems[0].GroupBy(p => p.Date.Month).Select(t => t.Count()).ToArray();
 109:     int counter = 0;
 110:     int monthSeq = 1;
 111:     foreach (int z in ZoningSize)
 112:     {
 113:         ChartMarkedZone zone = new ChartMarkedZone();
 114:         zone.ValueStartX = counter;
 115:         zone.ValueEndX = counter + z;
 116:         counter = counter + z;
 117:         zone.Label.TextBlock.Text = new DateTime(2012, monthSeq, 1).ToString("MMM");
 118:         zone.Appearance.Border.Color = Color.LightBlue;
 119:         zone.Label.Appearance.Position.AlignedPosition = Telerik.Reporting.Charting.Styles.AlignedPositions.Bottom;
 120:         zone.Label.TextBlock.Appearance.TextProperties.Font = new System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 5, FontStyle.Bold);
 121:         monthSeq++;
 122:         mychart.PlotArea.MarkedZones.Add(zone);
 123:     }
 124:     #endregion
 125:  
 126:     #region Chart Location and Customization
 127:     Telerik.Reporting.Drawing.Unit Height = new Telerik.Reporting.Drawing.Unit(8, ((Telerik.Reporting.Drawing.UnitType)(Telerik.Reporting.Drawing.UnitType.Cm)));
 128:     Telerik.Reporting.Drawing.Unit Width = new Telerik.Reporting.Drawing.Unit(15, ((Telerik.Reporting.Drawing.UnitType)(Telerik.Reporting.Drawing.UnitType.Cm)));
 129:     mychart.PlotArea.XAxis.AutoShrink = false;
 130:     mychart.Size = new Telerik.Reporting.Drawing.SizeU(Width, Height);
 131:     mychart.Location = new Telerik.Reporting.Drawing.PointU(new Telerik.Reporting.Drawing.Unit(0.25, ((Telerik.Reporting.Drawing.UnitType)(Telerik.Reporting.Drawing.UnitType.Cm))), new Telerik.Reporting.Drawing.Unit(0.8, ((Telerik.Reporting.Drawing.UnitType)(Telerik.Reporting.Drawing.UnitType.Cm))));
 132:  
 133:     #region Reposition XAxis Label
 134:     mychart.PlotArea.XAxis.AxisLabel.Appearance.Position.Auto = false;
 135:     mychart.PlotArea.XAxis.AxisLabel.Appearance.Position.X = 320;
 136:     mychart.PlotArea.XAxis.AxisLabel.Appearance.Position.Y = 320;
 137:     #endregion
 138:     #region Reposition Graph
 139:     mychart.PlotArea.Appearance.Dimensions.Margins.Bottom = 90;
 140:     mychart.PlotArea.Appearance.Dimensions.Margins.Right = 80;
 141:     mychart.PlotArea.Appearance.Dimensions.Margins.Left = 90;
 142:     #endregion
 143:     #endregion
 144:  
 145:     return mychart;
 146: }

Rendered

Rendering1