Introduction
This tutorial includes the steps for making a SharePoint AJAX-refreshable Web Part which wraps an ASP .NET Chart Control.
This tutorial is the following of two previous ones:
This tutorial is compliant with both MOSS 2007 and Windows SharePoint Services 3.0.
In this SharePoint Web part Page, 4 SharePoint Web Parts embedding an ASP .NET Chart Control can be refreshed independently some of the others using ASP .NET AJAX 3.5 and can be used to build a SharePoint Dashboard.
Unfortunatly, as an ASP .NET Chart Control is a Server Conrol, the only (easy) way of adding AJAX improvements to an .aspx page regarding an ASP .NET Chart Control is to use Update Panel. Of course Best Practices in using UpdatePanel can increase the page efficiency.
For more information there is this article of Jeff Prosise in MSDN Magazine (june 2007 issue)
For more information:
There is several way to modify this file in order to add support for .Net 3.5 in the SharePoint Web Application:
Here are the steps (I have mentionned all of them ordered as in a SharePoint web.config file, but also mentionned the fact I have skipped some):
This tutorial is the following of two previous ones:
- MOSS, How to...: Use Microsoft Chart Controls for .Net framework in a SharePoint web site
- MOSS, How to...: Use Microsoft ASP .NET Chart Control in a SharePoint Web Part
- Windows SharePoint Services 3.0 Web parts
- Microsoft ASP .NET Chart Control
- Microsoft ASP .NET AJAX 3.5
This tutorial is compliant with both MOSS 2007 and Windows SharePoint Services 3.0.
In this SharePoint Web part Page, 4 SharePoint Web Parts embedding an ASP .NET Chart Control can be refreshed independently some of the others using ASP .NET AJAX 3.5 and can be used to build a SharePoint Dashboard.
1 - Prerequisites
- Usual development environment for SharePoint (Windows 2003 Server or Windows Server 2008 with a SharePoint installation).
-
Microsoft Chart Controls for Microsoft .NET Framework 3.5 are installed on the development environment. You can download installation package
here
(It seems that the download to save to your computer for installation at a later time is corrupted and that you only can install it if you are connected to the Internet) - Microsoft Visual Studio 2008 is installed on the development environment.
- Microsoft Chart Controls Add-on for Microsoft Visual Studio 2008 is installed on the development environment.
- Samples Environment for Microsoft ASP .NET Chart Controls is installed on the development environment.
- You have already done the previous tutorial:
2 - Important ASP .NET AJAX 3.5 information:
1 - Using UpdatePanel control and efficiency.
There are roughly two ways of doing Ajax with Microsoft Ajax Framework.- Using UpdatePanel control
- Using a web Service. ( ASMX Web method called through the javaScript Proxy).
Unfortunatly, as an ASP .NET Chart Control is a Server Conrol, the only (easy) way of adding AJAX improvements to an .aspx page regarding an ASP .NET Chart Control is to use Update Panel. Of course Best Practices in using UpdatePanel can increase the page efficiency.
For more information there is this article of Jeff Prosise in MSDN Magazine (june 2007 issue)
2 - URL of the hosting SharePoint Web site
An article of Microsoft Knowledge Base reports that issue may occur if you use international characters in an URL of a SharePoint Page that contains a Web Part with ASP .NET AJAX Functionality. It is possible that this bug doesn't exist anymore with the ASP .NET AJAX 3.5 version.For more information:
3 - Tutorial Overview
This tutorial includes the following steps:- Step 1: Configure your SharePoint environment for ASP .NET Ajax 3.5
- Step 2: Create a new Class in AspNetChartControl.SharePointWebParts project
- Step 3: Give the Class the Basic Structure for a SharePoint Web Part without forgetting the "public" class declaration.
- Step 4: Define the Logic and rendering of your Web Part
- Step 5: Implement Ajax functionality
- Step 6: Build your web part
- Step 7: Update the DLL already present in the web Application Bin Directory
- Step 8: Import the site template default.aspx page in Visual Studio and rename it
- Step 9: Add a Script Manager to the Web Part Page defaultWithScriptManager.aspx
- Step 10: Add new Web Part Zones to the Web Part Page defaultWithScriptManager.aspx
- Step 11: Import the Web Part Page defaultWithScriptManager.aspx into your Sharepoint Web Site.
- Step 12: Import several Web Parts AjaxRefreshableChartWebPart into your Web Part Page.
4 - Tutorial
4.1 - Step 1: Configure your SharePoint environment for ASP .NET Ajax 3.5
We are going to add entries in the web.config file of the Web Application where is running the SharePoint Team site that is planned to welcome the Ajax-Refreshable Web part.There is several way to modify this file in order to add support for .Net 3.5 in the SharePoint Web Application:
CodePlex Feature automatic way
SharePointOfView - WebConfigFeatureReceiver : This SPFeatureReceiver enable easy web.config modifications via an XML file.
Jan Tielen's lazy way
And the manual way that I have chosen to show here in its minimal version, in order to modify the web.config as little as possible since we have modified it yet for supporting ASP .NET Chart Control, and we have to use caution when modifying a Web Application web.config that is already complex enough.
- <config section> (skipped)
- <SafeControls>
- <httpHandlers>
- <httpModules>
- <assemblies>
- <controls>
- <system.web.extension> (skipped)
- <system.web.server> (skipped)
-
<SafeControls>
<!-- start adding --> <SafeControl Assembly="System.Web.Extensions, version=3.5.0.0, culture=Neutral, publicKeyToken=31bf3856ad364e35" Namespace ="System.Web.UI" TypeName="*" Safe="True" /> <!-- end adding --> </SafeControls>
- <httpHandlers>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
-
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
-
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/> <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
-
<controls>
</tagMapping> <!-- start adding --> <controls> <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> <add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting" assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </controls> <!-- end adding --> </pages>
4.2 - Step 2: Create a new Class in AspNetChartControl.SharePointWebParts project
To create a new class- Right click your project in the Solution Explorer
- Select Add in the first menu
- Select Class in the second menu
- In the opening Dialog type the new Class name: AjaxRefreshableWebPart.cs
- Click Add.
This is the code state at the end of this step:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace AspNetChartControl.SharePointWebParts { class AjaxRefreshableWebPart { } }
4.3 - Step 3: Give the Class the Basic Structure for a SharePoint Web Part without forgetting the "public" class declaration.
Refering to previous tutorial from 3.2 to 3.5, give the Class the basic structure for a Sharepoint Web part Class. This is the code state at the end of this step:using System.ComponentModel; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Microsoft.SharePoint.WebPartPages; using System.Web.UI.DataVisualization.Charting; using System.Xml; using System.Diagnostics; namespace AspNetChartControl.SharePointWebParts { [ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")] public class AjaxRefreshableWebPart : Microsoft.SharePoint.WebPartPages.WebPart { protected override void CreateChildControls() { base.CreateChildControls(); } protected override void RenderWebPart(HtmlTextWriter output) { base.RenderWebPart(output); } } }
4.4 - Step 4: Define the Logic and rendering of your Web Part
We are now using again one of the ASP .NET Chart Control Sample. In one of these samples (Stacked Charts), there is a piece of C# code that shows how to generate a random Chart Serie for a Chart Control. As we have not yet bound our Chart Control to a Data Source, we will use this random Chart Serie generation to simulate a real Data Source binding.We have also to implement an ASP LinkButton to give user the chance to refresh the Web Part using it.
At the end of this step, we have a perfectly well working Wep Part, but it has not yet AJAX ability. That is to mean, if we build this code and deploy the Web Part, the click on the LinkButton will trigger a visible Postback of the Web Part Page.
This is the code state at the end of this step:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Microsoft.SharePoint.WebPartPages; using System.Web.UI.DataVisualization.Charting; using System.Xml; using System.Diagnostics; namespace AspNetChartControl.SharePointWebParts { [ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")] public class AjaxRefreshableWebPart : Microsoft.SharePoint.WebPartPages.WebPart { System.Web.UI.DataVisualization.Charting.Chart Chart1; protected override void CreateChildControls() { base.CreateChildControls(); LinkButton button1 = new LinkButton(); button1.ID = "lButton1"; button1.Text = "Refresh"; button1.Click += new EventHandler(lButton_Click); Chart1 = new System.Web.UI.DataVisualization.Charting.Chart(); Chart1.Width = 412; Chart1.Height = 296; Chart1.RenderType = RenderType.ImageTag; string imagespath = System.Configuration.ConfigurationSettings.AppSettings["ChartImageHandler"].ToString(); Chart1.ImageLocation = imagespath + "ChartPic_#SEQ(200,30)"; Chart1.Palette = ChartColorPalette.BrightPastel; Title t = new Title("Ajax-Refreshable ASP.NET Chart Control Web Part", Docking.Top, new System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105)); Chart1.Titles.Add(t); Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss; Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105); Chart1.BorderlineDashStyle = ChartDashStyle.Solid; Chart1.BorderWidth = 2; if (Chart1.Series.FindByName("Series1") == null) { Chart1.Series.Add(new Series("Series1")); Chart1.ChartAreas.Add("Series1"); } Random random = new Random(); for (int pointIndex = 0; pointIndex < 10; pointIndex++) { Chart1.Series["Series1"].Points.AddY(random.Next(45, 95)); } this.Controls.Add(Chart1); this.Controls.Add(button1); } void lButton_Click(object sender, EventArgs e) { Random random = new Random(); for (int pointIndex = 0; pointIndex < 10; pointIndex++) { Chart1.Series["Series1"].Points.AddY(random.Next(45, 95)); } } protected override void RenderWebPart(HtmlTextWriter output) { base.RenderWebPart(output); } } }
4.5 - Step 5: Implement Ajax functionality
We are now going to give the Web Part its AJAX ability to be refreshed without triggering a visible Post Back. We know now that unfortunatly for the Page efficiency, UpdatePanel control trigger a PostBack, even if it is no visible.For people that does not know at all how to use an UpdatePanel control, let's show the declarative syntax for that control that is very simple.
To use an UpdatePanel control in an ASP .NET Page and to give a piece of code the AJAX ability you just have to write that:
<asp:ScriptManager ID="ScriptManager1" EnablePartialRendering="true" runat="server"> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <!-- Place your code here --> </ContentTemplate> </asp:UpdatePanel>
Here is the previous code decorated with the implementation of the AJAX feature using the imperative syntax:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using Microsoft.SharePoint.WebPartPages; using System.Web.UI.DataVisualization.Charting; using System.Xml; using System.Diagnostics; namespace AspNetChartControl.SharePointWebParts { [ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")] public class AjaxRefreshableWebPart : Microsoft.SharePoint.WebPartPages.WebPart { System.Web.UI.DataVisualization.Charting.Chart Chart1; protected override void CreateChildControls() { base.CreateChildControls(); //UpdatePanel declaration, instantiation and identification UpdatePanel updatePanel1 = new UpdatePanel(); updatePanel1.ID = "udpAjaxRefreshableChartControlWebPart"; //the way the of refreshing updatePanel1.UpdateMode = UpdatePanelUpdateMode.Conditional; LinkButton button1 = new LinkButton(); button1.ID = "lButton1"; button1.Text = "Refresh"; button1.Click += new EventHandler(lButton_Click); Chart1 = new System.Web.UI.DataVisualization.Charting.Chart(); Chart1.Width = 412; Chart1.Height = 296; Chart1.RenderType = RenderType.ImageTag; string imagespath = System.Configuration.ConfigurationSettings.AppSettings["ChartImageHandler"].ToString(); Chart1.ImageLocation = imagespath + "ChartPic_#SEQ(200,30)"; Chart1.Palette = ChartColorPalette.BrightPastel; Title t = new Title("Ajax-Refreshable ASP.Net Chart Control Web Part", Docking.Top, new System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105)); Chart1.Titles.Add(t); Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss; Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105); Chart1.BorderlineDashStyle = ChartDashStyle.Solid; Chart1.BorderWidth = 2; if (Chart1.Series.FindByName("Series1") == null) { Chart1.Series.Add(new Series("Series1")); Chart1.ChartAreas.Add("Series 1"); } Random random = new Random(); Debug.WriteLine("AjaxRefreshWebPart - CreateChildControls"); for (int pointIndex = 0; pointIndex < 10; pointIndex++) { Chart1.Series["Series1"].Points.AddY(random.Next(45, 95)); } //the controls are embedded inside the UpdatePanelControl updatePanel1.ContentTemplateContainer.Controls.Add(Chart1); updatePanel1.ContentTemplateContainer.Controls.Add(button1); this.Controls.Add(updatePanel1); } void lButton_Click(object sender, EventArgs e) { Random random = new Random(); for (int pointIndex = 0; pointIndex < 10; pointIndex++) { Chart1.Series["Series1"].Points.AddY(random.Next(45, 95)); } } protected override void RenderWebPart(HtmlTextWriter output) { base.RenderWebPart(output); } } }
4.6 - Step 6 : Build your web part
After you add all of the preceding code, you can build your sample Web Part.To build your Web Part
On the Build menu, click Build Solution.
4.7 - Step 7: Update the DLL already present in the web Application Bin Directory
After the Web Part is built, you must copy the resulting DLL to the bin directory. To copy your DLL to the bin directory-
On the file system, locate the AspNetChartControl.SharePointWebparts.dll file. It should be in
C:\AspNetChartControl.SharePointWebparts\AspNetChartControl.SharePointWebparts\bin\Debug. - Replace the AspNetChartControl.SharePointWebParts.dll in the the Web application root bin directory with the file from the output directory.
4.8 - Step 8: Import the site template default.aspx page in Visual Studio and rename it
Navigate to the following directoryC:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates\sts
Copy the default.aspx page and paste it in your project directory.
In the Visual Studio Solution Explorer click Display All Files button to make the default.aspx page to be visible.
Right click the page and click on "Include In Project".
Rename the page in "defaultWithScriptManager.aspx"
4.9 - Step 9: Add a Script Manager to the Web Part Page defaultWithScriptManager.aspx
open the Page in Code viewExpand Visual Studio Toolbox and locate the ScriptManager control and drag it.
Locate the first WepPartZone declaration and drop a ScriptManager instance upon it.
4.10 - Step 10: Add new Web Part Zones to the Web Part Page defaultWithScriptManager.aspx
Locate the HTML <tr> line that contains the 2 webPartZone and duplicate it.Rename the 4 WebPartZones in order to obtain the following HTML code:
<table width="100%" cellpadding=0 cellspacing=0 style="padding: 5px 10px 10px 10px;"> <tr> <td valign="top" width="70%"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="LeftUp" Title="loc:LeftUp" /> </td> <td> </td> <td valign="top" width="30%"> <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="RightUp" Title="loc:RightUp" /> </td> <td> </td> </tr> <tr> <td valign="top" width="70%"> <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="LeftDown" Title="loc:LeftDown" /> </td> <td> </td> <td valign="top" width="30%"> <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="RightDown" Title="loc:RightDown" /> </td> <td> </td> </tr> </table>When the changes are done, save the page.
4.11 - Step 11: Import the Web Part Page defaultWithScriptManager.aspx into your Sharepoint Web Site.
Go to the Shared Documents document library of your team site and select upload a document.Then navigate to your project directory and choose the defaultWithScriptManager.aspx page.
4.12 - Step 12: Import several Web Parts AjaxRefreshableWebPart into your Web Part page.
Now you can add 4 AjaxRefeshableChartControlWebParts in your Page.And notice that you can rename them, and they can be refreshed independently some of the others using ASP .NET AJAX 3.5 and can be used to build a SharePoint Dashboard.
5 - For more information
You can find additional information at:- Microsoft Chart Controls for .NET Framework Documentation
- Chart Controls for .NET Framework MSDN Forum
- Alex Gorev's Weblog
By the way, there will be an interesting conference on that topic in february:
Case Studies in SharePoint Dashboards - The Sequel
If you are planning to realize such dashboards using ASP .NET Chart Controls, I will be pleased to exchange information with you...
5 comments:
Absolutely the star!!
Give this man a job, can't wait for the next installment of this thrilling development, the Data Binding part...
Only thing is - I'm not a C# guy, I prefer VB...
Still beggers can't be choosers, or can they?
Suppose I have to learn c#...
regards
Sean
Hi sean,
thank you for your comment. I am very touched.
I have just tried this C# to VB converter, and it seems to be good.
http://www.developerfusion.com/tools/convert/csharp-to-vb/
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports Microsoft.SharePoint.WebPartPages
Imports System.Web.UI.DataVisualization.Charting
Imports System.Xml
Imports System.Diagnostics
Namespace AspNetChartControl.SharePointWebParts
<ToolboxData("<{0}:AjaxRefreshableWebPart runat=server></{0}:AjaxRefreshableWebPart>")> _
Public Class AjaxRefreshableWebPart
Inherits Microsoft.SharePoint.WebPartPages.WebPart
Private Chart1 As System.Web.UI.DataVisualization.Charting.Chart
Protected Overloads Overrides Sub CreateChildControls()
MyBase.CreateChildControls()
'UpdatePanel declaration, instantiation and identification
Dim updatePanel1 As New UpdatePanel()
updatePanel1.ID = "udpAjaxRefreshableChartControlWebPart"
'the way the of refreshing
updatePanel1.UpdateMode = UpdatePanelUpdateMode.Conditional
Dim button1 As New LinkButton()
button1.ID = "lButton1"
button1.Text = "Refresh"
AddHandler button1.Click, AddressOf lButton_Click
Chart1 = New System.Web.UI.DataVisualization.Charting.Chart()
Chart1.Width = 412
Chart1.Height = 296
Chart1.RenderType = RenderType.ImageTag
Dim imagespath As String = System.Configuration.ConfigurationSettings.AppSettings("ChartImageHandler").ToString()
Chart1.ImageLocation = imagespath & "ChartPic_#SEQ(200,30)"
Chart1.Palette = ChartColorPalette.BrightPastel
Dim t As New Title("Ajax-Refreshable ASP.Net Chart Control Web Part", Docking.Top, New System.Drawing.Font("Trebuchet MS", 14, System.Drawing.FontStyle.Bold), System.Drawing.Color.FromArgb(26, 59, 105))
Chart1.Titles.Add(t)
Chart1.BorderSkin.SkinStyle = BorderSkinStyle.Emboss
Chart1.BorderColor = System.Drawing.Color.FromArgb(26, 59, 105)
Chart1.BorderlineDashStyle = ChartDashStyle.Solid
Chart1.BorderWidth = 2
If Chart1.Series.FindByName("Series1") Is Nothing Then
Chart1.Series.Add(New Series("Series1"))
Chart1.ChartAreas.Add("Series 1")
End If
Dim random As New Random()
Debug.WriteLine("AjaxRefreshWebPart - CreateChildControls")
For pointIndex As Integer = 0 To 9
Chart1.Series("Series1").Points.AddY(random.[Next](45, 95))
Next
'the controls are embedded inside the UpdatePanelControl
updatePanel1.ContentTemplateContainer.Controls.Add(Chart1)
updatePanel1.ContentTemplateContainer.Controls.Add(button1)
Me.Controls.Add(updatePanel1)
End Sub
Private Sub lButton_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim random As New Random()
For pointIndex As Integer = 0 To 9
Chart1.Series("Series1").Points.AddY(random.[Next](45, 95))
Next
End Sub
Protected Overloads Overrides Sub RenderWebPart(ByVal output As HtmlTextWriter)
MyBase.RenderWebPart(output)
End Sub
End Class
End Namespace
Hope this helps.
Marc
Well, it only gets better...
I never knew about this C# to VB converter, so will be trying it out. Thanks again.
Only thing I forgot to ask was, and I know all about deadlines, the future etc. when do you think the Data Binding follow up will be available for review?
regards,
Sean
Hi Sean,
I was planning doing it within this week, since after having worked several (long) weeks on Reporting Services, I am back with the Asp .Net Charting Control embedding web part development.
So you should have something about it very soon... ;-)
Marc
Hi sean,
as promissed, within the week (it was my last day yesterday... ;-)) I have posted something on the ASP .NET Chart Control Binding within a SharePoint Web Part.
Bind a Microsoft ASP .NET Chart Control within a SharePoint web part to a DataSetHope this helps.
Marc
Post a Comment