Microsoft Chart Controls и MS CRM
Microsoft Chart Controls это набор интерактивных .Net компонентов для рисования графиков и диаграмм. Вы можете выбрать для своего проекта (как WebForm так и WinForm) наиболее подходящие образцы из обширной библиотеки двухмерных и трехмерных диаграмм, модифицировать внешний вид и функциональность любого элемента, добавить подписи и условные обозначения, а также воспользоваться набором встроенных формул для выполнения различных манипуляций с данными. Для помощи в освоении Microsoft подготовил более двух сотен образцов готовых приложений ASP.NET и Windows Forms, а также библиотеку с исходными кодами на C#: Samples Environment for Microsoft Chart Controls, а также документацию: Microsoft Chart Controls for .NET Framework Documentation.
А так как ASP.NET можно прекрасно подружить с CRM, то рассмотрим небольшой пример как использовать Microsoft Chart Controls в CRM системе…
Новый веб-сайт
Для начала нам понадобится новый веб-сайт:
- Откройте IIS Manager;
- Щелкните правой кнопкой по узлу Sites — Add Web Site и задайте следующие параметры:
- Имя: chart;
- Путь: C:\inetpub\chart.
- Перейдите к узлу Application Pools — выделите пул chart — откройте его Advanced Settings — задайте для параметра Identity учетку админа CRM;
З.Ы. Также учтите, что возможно Вам понадобится выдать права на папку chart учетки под которой запущен Application pool нового сайта. Это нужно для того чтобы контрол мог создавать в ней временные файлы (на скриншотах я выдал всем права на эту папку, но в продакшен среде это не лучшее решение 🙂 ).
Подготовка тестовых данных
В итоговом виде у нас будут три различных графика отображаемых в iFrame’е на форме Бизнес-партнера:
- Столбчатая диаграмма отображающая количество действий соверженных в отношении Бизнес-партнера. Отбирается таким SQL запросом:
SELECT activitytypecodename [Действие], COUNT(*) [Кол-во] FROM FilteredActivityPointer WHERE regardingobjectid = '91a46c9a-51a9-df11-aaa7-000c29f6b309' GROUP BY activitytypecodename
- Линейная диаграмма отображающая итоговую сумму (раздельно) по связанным Возможным сделкам, Предложениям и Заказам за последние N-месяцев (период задается в C# коде). Отбирается таким SQL запросом:
SELECT tmp.month [Месяц], SUM(tmp.opp) [Возможные сделки], SUM(tmp.qt) [Предложения], SUM(tmp.ord) [Заказы] FROM ( SELECT MONTH(createdon) [month], SUM(estimatedvalue) [opp], '' [qt], '' [ord] FROM FilteredOpportunity WHERE customerid = '91a46c9a-51a9-df11-aaa7-000c29f6b309' and (MONTH(GETDATE()) - MONTH(createdon)) < 4 GROUP BY MONTH(createdon) UNION SELECT MONTH(createdon) [month], '' [opp], SUM(totalamount) [qt], '' [ord] FROM FilteredQuote WHERE customerid = '91A46C9A-51A9-DF11-AAA7-000C29F6B309' and (MONTH(GETDATE()) - MONTH(createdon)) < 4 GROUP BY MONTH(createdon) UNION SELECT MONTH(createdon) [month], '' [opp], '' [qt], SUM(totalamount) [ord] FROM FilteredSalesOrder WHERE customerid = '91A46C9A-51A9-DF11-AAA7-000C29F6B309' and (MONTH(GETDATE()) - MONTH(createdon)) < 4 GROUP BY MONTH(createdon) ) AS tmp GROUP BY tmp.month ORDER BY tmp.month
- Круговая диаграмма показывающее количество связанных записей Контактов в разрезе их ролей. Отбирается таким SQL запросом:
SELECT accountrolecodename [Роль], COUNT(*) [Кол-во] FROM FilteredContact WHERE parentcustomerid = '91A46C9A-51A9-DF11-AAA7-000C29F6B309' GROUP BY accountrolecodename
Поэтому для этого эксперимента найдите какую-нибудь запись Бизнес-партнера и создайте для нее:
- N-ое количество различных действий;
- По несколько связанных записей Возможных сделок, Предложений и Заказов. Затем откройте БД CRM и поменяйте для этих Возможных сделок, Предложений и Заказовполе createdon так, чтобы они были равномерно распределены по нескольким предыдущим месяцам (включая текущий);
- Несколько связанных Контактов, у которых заполните поле Роль (в стандартной поставке расположено на второй вкладке).
Установка Microsoft Chart Controls
Если Вы используете .Net Framework 3.5 и Visual Studio 2008, то скачайте и установите следующие компоненты (именно в таком порядке):
- Microsoft .NET Framework 3.5 Service Pack 1 (если он у Вас еще не установлен);
- Microsoft Chart Controls for Microsoft .NET Framework 3.5;
- Microsoft Chart Controls Add-on for Microsoft Visual Studio 2008;
- Microsoft Chart Controls for Microsoft .NET Framework 3.5 Language Pack (опционально).
З.Ы. Microsoft Chart Controls также по дефолту входит в .Net Framework 4 и Visual Studio 2010.
Создание ASPX-страницы
- Откройте VS 2008 и создайте новую ASPX-страницу;
- Теперь если Вы откроете панель Toolbox, то увидите что там в разделе Data есть новый контрол – Chart. Мы не будем рассматривать как по шагам вручнуе его использовать 🙂 это Вы как-нибудь сами 🙂 А пока просто поместите этот код в файл default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register Assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Chart</title> </head> <body style="background-color:#eaf3ff; text-align:center"> <nobr> <asp:Chart ID="Chart1" runat="server" Height="170px" Width="210px" backcolor="#eaf3ff" > <Series> <asp:Series Name="Series1"> </asp:Series> </Series> <ChartAreas> <asp:ChartArea Name="ChartArea1" BorderColor="64, 64, 64, 64" BorderDashStyle="Solid" BackSecondaryColor="White" BackColor="64, 165, 191, 228" ShadowColor="Transparent" BackGradientStyle="TopBottom" > <AxisY> <LabelStyle Font="Trebuchet MS, 8.25pt" /> </AxisY> <AxisX> <LabelStyle Font="Trebuchet MS, 8.25pt" /> </AxisX> <InnerPlotPosition Height="75.4" Width="79.74549" X="16.90344" Y="6.4" /> </asp:ChartArea> </ChartAreas> </asp:Chart> <asp:Chart ID="Chart2" runat="server" Height="170px" Width="210px" backcolor="#eaf3ff" > <Series> <asp:Series Name="Series1" ChartType="Line" BorderWidth="2"> </asp:Series> <asp:Series Name="Series2" ChartType="Line" BorderWidth="2"> </asp:Series> <asp:Series Name="Series3" ChartType="Line" BorderWidth="2"> </asp:Series> </Series> <ChartAreas > <asp:ChartArea Name="ChartArea1" BorderColor="64, 64, 64, 64" BorderDashStyle="Solid" BackSecondaryColor="White" BackColor="64, 165, 191, 228" ShadowColor="Transparent" BackGradientStyle="TopBottom" > <AxisY> <LabelStyle Font="Trebuchet MS, 8.25pt" /> <majorgrid linecolor="64, 64, 64, 64" /> </AxisY> <AxisX> <LabelStyle Font="Trebuchet MS, 8.25pt" /> <majorgrid linecolor="64, 64, 64, 64" /> </AxisX> </asp:ChartArea> </ChartAreas> </asp:Chart> <asp:Chart ID="Chart3" runat="server" Height="170px" Width="290px" backcolor="#eaf3ff" > <Series> <asp:Series Name="Series1" ChartType="Pie" CustomProperties="DrawingStyle=Pie, PieDrawingStyle=Concave, MaxPixelPointWidth=50" IsValueShownAsLabel="True" > </asp:Series> </Series> <ChartAreas> <asp:ChartArea Name="ChartArea1" backcolor="#eaf3ff"> <AxisY> <LabelStyle Font="Trebuchet MS, 8.25pt" /> <majorgrid linecolor="64, 64, 64, 64" /> </AxisY> <AxisX> <LabelStyle Font="Trebuchet MS, 8.25pt" /> <majorgrid linecolor="64, 64, 64, 64" /> </AxisX> <Position Height="80" Width="45" X="3" Y="5"> </Position> </asp:ChartArea> </ChartAreas> <Legends> <asp:Legend Name="Legend1" Docking="Right" LegendStyle="Column" BackColor="#EAF3FF" IsTextAutoFit="True" > </asp:Legend> </Legends> </asp:Chart> </nobr> </body> </html>
Здесь представлены три контрола Chart с различными праметрами (тип диаграммы, заливки, позиции и т.д.). Подробно с описанием этих параметров Вы сможете ознакомиться в документации и примерах;
- Далее в файл default.aspx.cs поместите такой код:
using System; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Data.SqlClient; using System.Drawing; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { try { // Подключаемся к скулю SqlConnection myConnection = new SqlConnection("Initial Catalog=superfirma_MSCRM;Data Source=win-n22hj23d1b1;Integrated Security=SSPI;"); myConnection.Open(); // Вытаскиваем GUID Бизнес-партнера и URL string accGUID = Request.QueryString["id"].Replace("{", "").Replace("}", ""); // Формируем (первый) SQL-запрос string query = "SELECT " + "activitytypecodename [Действие], " + "COUNT(*) [Кол-во] " + "FROM " + "FilteredActivityPointer " + "WHERE " + "regardingobjectid = '" + accGUID + "' " + "GROUP BY " + "activitytypecodename"; // Выполняем SQL-запрос и помещаем его результат в DataView SqlDataAdapter da = new SqlDataAdapter(query, myConnection); DataTable table = new DataTable(); da.Fill(table); DataView dv = table.DefaultView; // Заполняем (первый) график данными Chart1.Series["Series1"].Points.DataBindXY(dv, "Действие", dv, "Кол-во"); // Разукрашиваем столбцы в разные цвета Chart1.Series["Series1"].Points[0].Color = Color.Red; Chart1.Series["Series1"].Points[1].Color = Color.DarkKhaki; Chart1.Series["Series1"].Points[2].Color = Color.DarkViolet; Chart1.Series["Series1"].Points[3].Color = Color.DimGray; // Количество месяцев за которое необходимо построить вторую диаграмму string m = "4"; // Формируем (первый) SQL-запрос string query2 = "SELECT " + "tmp.month [Месяц], " + "SUM(tmp.opp) [Возможные сделки], " + "SUM(tmp.qt) [Предложения], " + "SUM(tmp.ord) [Заказы] " + "FROM ( " + "SELECT " + "MONTH(createdon) [month], " + "SUM(estimatedvalue) [opp], " + "'' [qt], " + "'' [ord] " + "FROM " + "FilteredOpportunity " + "WHERE " + "customerid = '" + accGUID + "' and " + "(MONTH(GETDATE()) - MONTH(createdon)) < " + m + " " + "GROUP BY " + "MONTH(createdon) " + "UNION " + "SELECT " + "MONTH(createdon) [month], " + "'' [opp], " + "SUM(totalamount) [qt], " + "'' [ord] " + "FROM " + "FilteredQuote " + "WHERE " + "customerid = '" + accGUID + "' and " + "(MONTH(GETDATE()) - MONTH(createdon)) < " + m + " " + "GROUP BY " + "MONTH(createdon) " + "UNION " + "SELECT " + "MONTH(createdon) [month], " + "'' [opp], " + "'' [qt], " + "SUM(totalamount) [ord] " + "FROM " + "FilteredSalesOrder " + "WHERE " + "customerid = '" + accGUID + "' and " + "(MONTH(GETDATE()) - MONTH(createdon)) < " + m + " " + "GROUP BY " + "MONTH(createdon) " + ") AS tmp " + "GROUP BY " + "tmp.month " + "ORDER BY " + "tmp.month"; // Выполняем SQL-запрос и помещаем его результат в DataView SqlDataAdapter da2 = new SqlDataAdapter(query2, myConnection); DataTable table2 = new DataTable(); da2.Fill(table2); DataView dv2 = table2.DefaultView; // Заполняем (первый) график данными Chart2.Series["Series1"].Points.DataBindXY(dv2, "Месяц", dv2, "Возможные сделки"); Chart2.Series["Series2"].Points.DataBindXY(dv2, "Месяц", dv2, "Предложения"); Chart2.Series["Series3"].Points.DataBindXY(dv2, "Месяц", dv2, "Заказы"); // Формируем (третий) SQL-запрос string query3 = "SELECT " + "accountrolecodename [Роль], " + "COUNT(*) [Кол-во] " + "FROM " + "FilteredContact " + "WHERE " + "parentcustomerid = '" + accGUID + "' and " + "(MONTH(GETDATE()) - MONTH(createdon)) < 4 " + "GROUP BY " + "accountrolecodename"; // Выполняем SQL-запрос и помещаем его результат в DataView SqlDataAdapter da3 = new SqlDataAdapter(query3, myConnection); DataTable table3 = new DataTable(); da3.Fill(table3); DataView dv3 = table3.DefaultView; // Заполняем (третий) график данными Chart3.Series["Series1"].Points.DataBindXY(dv3, "Роль", dv3, "Кол-во"); } catch (Exception error) { throw new Exception(error.Message); } } }
Этот код отвечает за подключение к БД CRM (измените параметры на Ваши), получение GUID’а из URL, формировании на его основе SQL запросов, их выпполнение, преобразовании полученных данных и помещении и в диаграммы 🙂
- А в web.config поместите следущее (это просто служебный код):
<?xml version="1.0"?> <configuration> <appSettings> <add key="ChartImageHandler" value="storage=file;timeout=20;" /> </appSettings> <connectionStrings/> <system.web> <compilation debug="false"> <assemblies> <add assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </assemblies> </compilation> <authentication mode="Windows"/> <pages> <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> </pages> <httpHandlers> <add path="ChartImg.axd" verb="GET,HEAD" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" /> </httpHandlers> <httpModules> <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> </httpModules> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <modules> <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> </modules> <handlers> <add name="ChartImg" verb="*" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> <add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </handlers> </system.webServer> </configuration>
Развертывание
- Опубликуйте ASPX-страницу в папке inetpub\chart (Build — Publish Web Site)
- Создайте новый iFrame на форме Бизнес-пртнера и задайте для него такие параметры:
- Имя: chart;
- URL: about:blank;
- Снимите калку ограничивающую использование скриптов;
- Высоту задайте в 8;
- Уберите прокрутку и границы.
- На онлоад поместите следующий js-код:
if (crmForm.ObjectId) crmForm.all.IFRAME_chart.src = "http://win-n22hj23d1b1:5555/default.aspx?id=" + crmForm.ObjectId;
Этот код динамически формирует URL адрес для iFrame’а и подставляет в него GUID текущей записи Бизнес-партнера.
Ну вот пожалуй и все 🙂 открывайте тестовую запись Бизнес-партнера и любуйтесь диаграммами 🙂