Разработка
19
Сен
0

Панель управления на FusionCharts

FusionCharts – это мощный набор компонентов для рисования анимированных и интерактивных графиков и диаграмм на базе Flash-анимации, которые легко могут быть интегрированы в любое веб-приложение (дружит с такими языками как HTML, .NET, ASP, JSP, PHP, ColdFusion, Ruby и т.д.). И сейчас попробуем встроить эти диаграммы в CRM… сделаем из них небольшой дашбоард 🙂

Наша панель управления будет состоят из четырех диаграмм, данные для которых будут выбираться следующими SQL-запросами:

  • Воронка продаж
    select
          'Возможные сделки' as tip,
          COUNT(*) as kolvo,
          '1'
    from
          dbo.FilteredOpportunity as CRMAF_opp
    UNION
    select
          'Предложения' as tip,
          COUNT(*) as kolvo,
    	  '2'
    from
          dbo.FilteredQuote as CRMAF_quo
    UNION
    select
          'Заказы' as tip,
          COUNT(*) as kolvo,
    	  '3'
    from
          dbo.FilteredSalesOrder as CRMAF_ord
    UNION
    select
          'Счета' as tip,
          COUNT(*) as kolvo,
    	  '4'
    from
          dbo.FilteredInvoice as CRMAF_inv
    order by 3 desc
    
  • Подсчитываем количество действий
    select
          CRMAF_ap.activitytypecodename as tip,
          COUNT(*) as kolvo
    from
          dbo.FilteredActivityPointer as CRMAF_ap
    group by CRMAF_ap.activitytypecodename
    
  • Количество созданных бизнес-партнеров за последние 4 месяца
    SELECT
    	'mnth' =
    	CASE
    		WHEN MONTH(createdon) = '1' THEN 'Январь'
    		WHEN MONTH(createdon) = '2' THEN 'Февраль'
    		WHEN MONTH(createdon) = '3' THEN 'Март'
    		WHEN MONTH(createdon) = '4' THEN 'Апрель'
    		WHEN MONTH(createdon) = '5' THEN 'Май'
    		WHEN MONTH(createdon) = '6' THEN 'Июнь'
    		WHEN MONTH(createdon) = '7' THEN 'Июль'
    		WHEN MONTH(createdon) = '8' THEN 'Август'
    		WHEN MONTH(createdon) = '9' THEN 'Сентябрь'
    		WHEN MONTH(createdon) = '10' THEN 'Октябрь'
    		WHEN MONTH(createdon) = '11' THEN 'Ноябрь'
    		WHEN MONTH(createdon) = '12' THEN 'Декабрь'
    	END,
    	COUNT(*) [kolvo]
    FROM
    	FilteredAccount
    WHERE
    	(MONTH(GETDATE()) - MONTH(createdon)) < 4
    GROUP BY
    	MONTH(createdon)
    ORDER BY
    	MONTH(createdon)
    
  • Объемы продаж на различных стадиях сделки за последние 4 месяца
    SELECT
    	'mnth' =
    	CASE
    		WHEN tmp.month = '1' THEN 'Январь'
    		WHEN tmp.month = '2' THEN 'Февраль'
    		WHEN tmp.month = '3' THEN 'Март'
    		WHEN tmp.month = '4' THEN 'Апрель'
    		WHEN tmp.month = '5' THEN 'Май'
    		WHEN tmp.month = '6' THEN 'Июнь'
    		WHEN tmp.month = '7' THEN 'Июль'
    		WHEN tmp.month = '8' THEN 'Август'
    		WHEN tmp.month = '9' THEN 'Сентябрь'
    		WHEN tmp.month = '10' THEN 'Октябрь'
    		WHEN tmp.month = '11' THEN 'Ноябрь'
    		WHEN tmp.month = '12' THEN 'Декабрь'
    	END,
    	SUM(tmp.opp) [opp],
    	SUM(tmp.qt) [qt],
    	SUM(tmp.ord) [ord]
    FROM (
    	SELECT
    		MONTH(createdon) [month],
    		SUM(estimatedvalue) [opp],
    		'' [qt],
    		'' [ord]
    	FROM
    		FilteredOpportunity
    	WHERE
    		(MONTH(GETDATE()) - MONTH(createdon)) < 4
    	GROUP BY
    		MONTH(createdon)
    
    	UNION
    
    	SELECT
    		MONTH(createdon) [month],
    		'' [opp],
    		SUM(totalamount) [qt],
    		'' [ord]
    	FROM
    		FilteredQuote
    	WHERE
    		(MONTH(GETDATE()) - MONTH(createdon)) < 4
    	GROUP BY
    		MONTH(createdon)
    
    	UNION
    
    	SELECT
    		MONTH(createdon) [month],
    		'' [opp],
    		'' [qt],
    		SUM(totalamount) [ord]
    	FROM
    		FilteredSalesOrder
    	WHERE
    		(MONTH(GETDATE()) - MONTH(createdon)) < 4
    	GROUP BY
    		MONTH(createdon)
    ) AS tmp
    GROUP BY
    	tmp.month
    ORDER BY
    	tmp.month
    

Итак, начнем…

  • Для начала скачайте бесплатную версию FusionCharts (включает в себя около десятка различны диаграмм, с примерами которых, Вы можете ознакомится в галереи) и разархивируйте к себе на локальный диск;
  • Создайте в Visual Studio новый ASP.NET сайт;
  • Включите в проект папку bin, а в нее поместите файл FusionCharts.dll из папки <FusionCharts>\Code\CSNET\bin;



  • Создайте в проекте новую папку FusionCharts и поместите в нее из папки <FusionCharts>\Charts те файлы .swf, диаграммы которых Вы хотите использовать. В данном случае это:
    • FCF_Funnel.swf;
    • FCF_Pie2D.swf;
    • FCF_Column2D.swf;
    • FCF_MSLine.swf.
  • Замените содержимое файла Default.aspx следующим кодом:
    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
    
    <!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 id="Head1" runat="server">
        <title>Untitled Page</title>
        <style type="text/css">
            BODY 
            {
            	margin: 0;
            	padding: 20px 10px;
            }
            TD 
            {
            	vertical-align: middle;
            }
            .title 
            {
            	font-family: Arial;
            	font-size: 10pt;
            	font-weight: bold;
            	text-align: center;
            }
        </style>
    </head>
    <body>
        <table>
            <tr><td class="title">Воронка</td><td class="title">Кружочек</td></tr>
            <tr>
            <td>
                <asp:Literal ID="FCLiteral1" runat="server"></asp:Literal>
            </td>
            <td>
                <asp:Literal ID="FCLiteral2" runat="server"></asp:Literal>
            </td>
            </tr>
            <tr><td class="title">Столбики</td><td class="title">Линии</td></tr>
            <tr>
            <td>
                <asp:Literal ID="FCLiteral3" runat="server"></asp:Literal>
            </td>
            <td>
                <asp:Literal ID="FCLiteral4" runat="server"></asp:Literal>
            </td>
            </tr>
        </table>
    </body>
    </html>
    

    Тут небольшая HTML-разметка, которая помимо прочего, содержит в HTML-таблицы четыре ключевых элемента asp:Literal. А ключевые они потому, что позднее в коде на их место будет подставлены flash-диаграммы. Все остально тут – просто форматирование 🙂

  • В 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 InfoSoftGlobal;
    
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Подключаемся к скулю
            SqlConnection myConnection = new SqlConnection("Initial Catalog=superfirma_MSCRM;Data Source=win-n22hj23d1b1;Integrated Security=SSPI;");
            myConnection.Open();
    
            DataTable oTable = new DataTable();
            SqlDataAdapter da;
            string strXML;
            string query;
    
            #region Первая диаграмма
    
            // Формируем (первый) SQL-запрос  
            query =
            "select " +
                "'Возможные сделки' as tip, " +
                "COUNT(*) as kolvo, " +
                "'1' " +
            "from " +
                "dbo.FilteredOpportunity as CRMAF_opp " +
            "UNION " +
            "select " +
                "'Предложения' as tip, " +
                "COUNT(*) as kolvo, " +
                "'2' " +
            "from " +
                "dbo.FilteredQuote as CRMAF_quo " +
            "UNION " +
            "select " +
                "'Заказы' as tip, " +
                "COUNT(*) as kolvo, " +
                "'3' " +
            "from " +
                "dbo.FilteredSalesOrder as CRMAF_ord " +
            "UNION " +
            "select " +
                "'Счета' as tip, " +
                "COUNT(*) as kolvo, " +
                "'4' " +
            "from " +
                "dbo.FilteredInvoice as CRMAF_inv " +
            "order by 3 desc";
    
            // Выполняем SQL-запрос и помещаем его результат в DataTable  
            da = new SqlDataAdapter(query, myConnection);
            da.Fill(oTable);
    
            // Из результатов SQL запроса формируем массив XML-данных
            strXML = "<chart isSliced='1' slicingDistance='4' decimalPrecision='0'>";
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<set name='" + oRow["tip"].ToString() + "' value='" + oRow["kolvo"].ToString() + "' />";
            }
            strXML += "</chart>";
    
            // Создаем диаграмму-воронку
            FCLiteral1.Text = FusionCharts.RenderChartHTML("FusionCharts/FCF_Funnel.swf", "", strXML, "funn", "280", "170", false);
    
            #endregion
    
            #region Вторая диаграмма
    
            // Формируем (второй) SQL-запрос  
            query =
            "select " +
                "CRMAF_ap.activitytypecodename as tip, " +
                "COUNT(*) as kolvo " +
            "from " +
                  "dbo.FilteredActivityPointer as CRMAF_ap " +
            "group by CRMAF_ap.activitytypecodename";
    
            // Выполняем SQL-запрос и помещаем его результат в DataTable  
            da = new SqlDataAdapter(query, myConnection);
            oTable.Clear();
            da.Fill(oTable);
    
            // Из результатов SQL запроса формируем массив XML-данных
            strXML = "<graph decimalPrecision='0' showNames='1'>";
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<set name='" + oRow["tip"].ToString() + "' value='" + oRow["kolvo"].ToString() + "' />";
            }
            strXML += "</graph>";
    
            // Создаем круговую диаграмму
            FCLiteral2.Text = FusionCharts.RenderChartHTML("FusionCharts/FCF_Pie2D.swf", "", strXML, "pie", "350", "210", false);
    
            #endregion
    
            #region Третья диаграмма
    
            // Формируем (третий) SQL-запрос  
            query =
            "SELECT " +
                "'mnth' = " +
                "CASE " +
                    "WHEN MONTH(createdon) = '1' THEN 'Январь' " +
                    "WHEN MONTH(createdon) = '2' THEN 'Февраль' " +
                    "WHEN MONTH(createdon) = '3' THEN 'Март' " +
                    "WHEN MONTH(createdon) = '4' THEN 'Апрель' " +
                    "WHEN MONTH(createdon) = '5' THEN 'Май' " +
                    "WHEN MONTH(createdon) = '6' THEN 'Июнь' " +
                    "WHEN MONTH(createdon) = '7' THEN 'Июль' " +
                    "WHEN MONTH(createdon) = '8' THEN 'Август' " +
                    "WHEN MONTH(createdon) = '9' THEN 'Сентябрь' " +
                    "WHEN MONTH(createdon) = '10' THEN 'Октябрь' " +
                    "WHEN MONTH(createdon) = '11' THEN 'Ноябрь' " +
                    "WHEN MONTH(createdon) = '12' THEN 'Декабрь' " +
                "END, " +
                "COUNT(*) [kolvo] " +
            "FROM " +
                "FilteredAccount " +
            "GROUP BY " +
                "MONTH(createdon) " +
            "ORDER BY " +
                "MONTH(createdon)";
    
            // Выполняем SQL-запрос и помещаем его результат в DataTable  
            da = new SqlDataAdapter(query, myConnection);
            oTable.Clear();
            da.Fill(oTable);
    
            // Из результатов SQL запроса формируем массив XML-данных
            strXML = "<graph decimalPrecision='0' showNames='1'>";
            string[] colors = { "AFD8F8", "F6BD0F", "8BBA00", "FF8E46" };
            int i = 0;
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<set name='" + oRow["mnth"].ToString() + "' value='" + oRow["kolvo"].ToString() + "' color='" + colors[i++] + "' />";
            }
            strXML += "</graph>";
    
            // Создаем столбчатую диаграмму
            FCLiteral3.Text = FusionCharts.RenderChartHTML("FusionCharts/FCF_Column2D.swf", "", strXML, "column", "350", "200", false);
    
            #endregion
    
            #region Четвертая диаграмма
    
            // Формируем (четвертый) SQL-запрос  
            query =
            "SELECT " +
                "'mnth' = " +
                "CASE " +
                    "WHEN tmp.month = '1' THEN 'Январь' " +
                    "WHEN tmp.month = '2' THEN 'Февраль' " +
                    "WHEN tmp.month = '3' THEN 'Март' " +
                    "WHEN tmp.month = '4' THEN 'Апрель' " +
                    "WHEN tmp.month = '5' THEN 'Май' " +
                    "WHEN tmp.month = '6' THEN 'Июнь' " +
                    "WHEN tmp.month = '7' THEN 'Июль' " +
                    "WHEN tmp.month = '8' THEN 'Август' " +
                    "WHEN tmp.month = '9' THEN 'Сентябрь' " +
                    "WHEN tmp.month = '10' THEN 'Октябрь' " +
                    "WHEN tmp.month = '11' THEN 'Ноябрь' " +
                    "WHEN tmp.month = '12' THEN 'Декабрь' " +
                "END, " +
                "SUM(tmp.opp) [opp], " +
                "SUM(tmp.qt) [qt], " +
                "SUM(tmp.ord) [ord] " +
            "FROM ( " +
                "SELECT " +
                    "MONTH(createdon) [month], " +
                    "SUM(estimatedvalue) [opp], " +
                    "'' [qt], " +
                    "'' [ord] " +
                "FROM " +
                    "FilteredOpportunity " +
                "WHERE " +
                    "(MONTH(GETDATE()) - MONTH(createdon)) < 4 " +
                "GROUP BY " +
                    "MONTH(createdon) " +
                "UNION " +
                "SELECT " +
                    "MONTH(createdon) [month], " +
                    "'' [opp], " +
                    "SUM(totalamount) [qt], " +
                    "'' [ord] " +
                "FROM " +
                    "FilteredQuote " +
                "WHERE " +
                    "(MONTH(GETDATE()) - MONTH(createdon)) < 4 " +
                "GROUP BY " +
                    "MONTH(createdon) " +
                "UNION " +
                "SELECT " +
                    "MONTH(createdon) [month], " +
                    "'' [opp], " +
                    "'' [qt], " +
                    "SUM(totalamount) [ord] " +
                "FROM " +
                    "FilteredSalesOrder " +
                "WHERE " +
                    "(MONTH(GETDATE()) - MONTH(createdon)) < 4 " +
                "GROUP BY " +
                    "MONTH(createdon) " +
            ") AS tmp " +
            "GROUP BY " +
                "tmp.month " +
            "ORDER BY " +
                "tmp.month";
    
            // Выполняем SQL-запрос и помещаем его результат в DataTable  
            da = new SqlDataAdapter(query, myConnection);
            oTable.Clear();
            da.Fill(oTable);
    
            // Из результатов SQL запроса формируем массив XML-данных
            strXML = "<graph hovercapbg='FFECAA' hovercapborder='F47E00' formatNumberScale='0' decimalPrecision='2' showvalues='0' animation='1' numdivlines='3' numVdivlines='0' lineThickness='3'>";
    
            strXML += "<categories>";
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<category name='" + oRow["mnth"].ToString() + "' />";
            }
            strXML += "</categories>";
    
            strXML += "<dataset seriesName='Возможные сделки' color='1D8BD1' anchorBorderColor='1D8BD1' anchorBgColor='1D8BD1'>";
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<set value='" + oRow["opp"].ToString().Replace(",", ".") + "' />";
            }
            strXML += "</dataset>";
    
            strXML += "<dataset seriesName='Предложения' color='F1683C' anchorBorderColor='F1683C' anchorBgColor='F1683C'>";
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<set value='" + oRow["qt"].ToString().Replace(",", ".") + "' />";
            }
            strXML += "</dataset>";
    
            strXML += "<dataset seriesName='Заказы' color='2AD62A' anchorBorderColor='2AD62A' anchorBgColor='2AD62A'>";
            foreach (DataRow oRow in oTable.Rows)
            {
                strXML += "<set value='" + oRow["ord"].ToString().Replace(",", ".") + "' />";
            }
            strXML += "</dataset>";
    
            strXML += "</graph>";
    
            // Создаем линейную диаграмму
            FCLiteral4.Text = FusionCharts.RenderChartHTML("FusionCharts/FCF_MSLine.swf", "", strXML, "line", "350", "210", false);
    
            #endregion
    
            // Закрываем SQL-соединение
            myConnection.Close();
        }
    }
    

    Тут код уже уже посложнее немного 🙂 Но в целом все просто:

    • Создаем подключение к скулю;
    • Формируем строку SQL-запроса;
    • Просматриваем построчно результат и на основе его данных создаем XML-структуру, которую может «схавать» FusionCharts (ее формат описан в документации к FusionCharts);
    • Подменяем первый asp:Literal отрендеренной диаграммой FusionCharts
    • И в таком же «духе» для оставшихся трех диаграмм.
  • А в web.config поместите «стандартные» настройки:
    <?xml version="1.0"?>
    <configuration>
      <appSettings/>
      <connectionStrings/>
      <system.web>
        <httpModules>
          <add name="MapOrg" type="Microsoft.Crm.MapOrgEngine, Microsoft.Crm, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
          <add name="CrmAuthentication" type="Microsoft.Crm.Authentication.AuthenticationEngine, Microsoft.Crm, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
        </httpModules>
        <identity impersonate="true"/>
        <compilation debug="true">
          <assemblies>
            <add assembly="Microsoft.Crm.Sdk, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add assembly="Microsoft.Crm.SdkTypeProxy, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          </assemblies>
        </compilation>
      </system.web>
    </configuration>
    
  • Опубликуйте сайт в папук <сайт CRM>\ISV\fusioncharts (которую предварительно создайте);



  • Выгрузите из CRM’а SiteMap и поместите куда-нибудь в него такой код:
            <Group Id="DashBid" Title="Графики">
              <SubArea Id="DashB" Url="/../ISV/fusioncharts/default.aspx" Icon="/_imgs/presence/imnon.png" Title="Графики" />
            </Group>
    

    Он просто добавляет новую группу в навигационную панель и в ней создает ссылку на нашу панель управления;

  • Вроде все 🙂 Импортируйте SiteMap обратно в CRM и смотрите на дашбоард 🙂


Много различных примеров работы с FusionCharts описаны в документации, которая скачивается вместе с самими диаграммами (просто запустите Index.html из архива, что Вы скачали в первом пункте).

Комментарии (0)

*

code